From a3169783fccc3c8d71cceea0b5d9bf7aba4bb708 Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback Date: Sun, 19 Dec 2004 06:17:55 +0000 Subject: Reduce delta to FreeBSD by adding and using ahd_alloc() rather than manually reproducing bits in ahd_pci.c. Just as in ahc, avoid allocating and freeing zero length bits of memory for platform data. Don't try to free all or part of ahd_softc, but correctly free allocated memory for seep_config if necessary. Add a final few fields to ahd_softc and scb in preparation for updating/fixing timeout handling. No functional changes. --- sys/dev/ic/aic79xx.c | 70 ++++++++++++++++++++++++++++++++++++-------- sys/dev/ic/aic79xx.h | 12 ++++++-- sys/dev/ic/aic79xx_openbsd.c | 18 +++++++----- sys/dev/pci/ahd_pci.c | 32 +++----------------- 4 files changed, 81 insertions(+), 51 deletions(-) diff --git a/sys/dev/ic/aic79xx.c b/sys/dev/ic/aic79xx.c index a938a659c4e..3ccc1c06112 100644 --- a/sys/dev/ic/aic79xx.c +++ b/sys/dev/ic/aic79xx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aic79xx.c,v 1.22 2004/12/13 05:49:03 krw Exp $ */ +/* $OpenBSD: aic79xx.c,v 1.23 2004/12/19 06:17:54 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -5258,6 +5258,54 @@ ahd_sglist_allocsize(struct ahd_softc *ahd) return (best_list_size); } +/* + * Perform initial initialization for a controller structure. + */ +struct ahd_softc * +ahd_alloc(void *platform_arg, char *name) +{ + struct ahd_softc *ahd = (struct ahd_softc *)platform_arg; + + ahd->seep_config = malloc(sizeof(*ahd->seep_config), + M_DEVBUF, M_NOWAIT); + if (ahd->seep_config == NULL) + return (NULL); + + LIST_INIT(&ahd->pending_scbs); + LIST_INIT(&ahd->timedout_scbs); + + /* We don't know our unit number until the OSM sets it */ + ahd->name = name; + ahd->unit = -1; + ahd->bus_description = NULL; + ahd->channel = 'A'; + ahd->chip = AHD_NONE; + ahd->features = AHD_FENONE; + ahd->bugs = AHD_BUGNONE; + ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A + | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A; + ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT; + ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT; + ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT; + ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT; + ahd->int_coalescing_stop_threshold = + AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT; + + if (ahd_platform_alloc(ahd, platform_arg) != 0) { + free(ahd->seep_config, M_DEVBUF); + return (NULL); + } + +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_MEMORY) != 0) { + printf("%s: scb size = 0x%x, hscb size = 0x%x\n", + ahd_name(ahd), (u_int)sizeof(struct scb), + (u_int)sizeof(struct hardware_scb)); + } +#endif + return (ahd); +} + int ahd_softc_init(struct ahd_softc *ahd) { @@ -5396,15 +5444,10 @@ ahd_free(struct ahd_softc *ahd) free(ahd->black_hole, M_DEVBUF); } #endif - if (ahd->name != NULL) - free(ahd->name, M_DEVBUF); if (ahd->seep_config != NULL) free(ahd->seep_config, M_DEVBUF); if (ahd->saved_stack != NULL) free(ahd->saved_stack, M_DEVBUF); -#ifndef __FreeBSD__ - free(ahd, M_DEVBUF); -#endif return; } @@ -6042,7 +6085,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd) scb_data->scbs_left -= newcount; scb_data->sgs_left -= newcount; for (i = 0; i < newcount; i++) { - struct scb_platform_data *pdata; + struct scb_platform_data *pdata = NULL; u_int col_tag; #ifndef __linux__ int error; @@ -6053,12 +6096,13 @@ ahd_alloc_scbs(struct ahd_softc *ahd) if (next_scb == NULL) break; - pdata = (struct scb_platform_data *)malloc(sizeof(*pdata), - M_DEVBUF, M_NOWAIT); - if (pdata == NULL) { - free(next_scb, M_DEVBUF); - break; - } + if (sizeof(*pdata) > 0) { + pdata = malloc(sizeof(*pdata), M_DEVBUF, M_NOWAIT); + if (pdata == NULL) { + free(next_scb, M_DEVBUF); + break; + } + } next_scb->platform_data = pdata; next_scb->hscb_map = hscb_map; next_scb->sg_map = sg_map; diff --git a/sys/dev/ic/aic79xx.h b/sys/dev/ic/aic79xx.h index 072acb24db7..7e1f887555d 100644 --- a/sys/dev/ic/aic79xx.h +++ b/sys/dev/ic/aic79xx.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aic79xx.h,v 1.16 2004/12/13 04:07:26 krw Exp $ */ +/* $OpenBSD: aic79xx.h,v 1.17 2004/12/19 06:17:54 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -653,6 +653,7 @@ struct scb { } links2; #define pending_links links2.le #define collision_links links2.le + LIST_ENTRY(scb) timedout_links; struct scb *col_scb; struct scsi_xfer *xs; @@ -700,6 +701,8 @@ struct scb_data { */ struct scb *scbindex[AHD_SCB_MAX]; + u_int recovery_scbs; /* Transactions currently in recovery */ + SLIST_HEAD(, map_node) hscb_maps; SLIST_HEAD(, map_node) sg_maps; SLIST_HEAD(, map_node) sense_maps; @@ -1114,6 +1117,11 @@ struct ahd_softc { */ LIST_HEAD(, scb) pending_scbs; + /* + * SCBs whose timeout routine has been called. + */ + LIST_HEAD(, scb) timedout_scbs; + /* * Current register window mode information. */ @@ -1392,7 +1400,7 @@ int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, u_int tag, role_t role); /****************************** Initialization ********************************/ -/*struct ahd_softc *ahd_alloc(void *platform_arg, char *name);*/ +struct ahd_softc *ahd_alloc(void *platform_arg, char *name); int ahd_softc_init(struct ahd_softc *); void ahd_controller_info(struct ahd_softc *ahd, char *buf, size_t bufsz); diff --git a/sys/dev/ic/aic79xx_openbsd.c b/sys/dev/ic/aic79xx_openbsd.c index 8da21ece3b6..2424c40979c 100644 --- a/sys/dev/ic/aic79xx_openbsd.c +++ b/sys/dev/ic/aic79xx_openbsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aic79xx_openbsd.c,v 1.13 2004/12/13 04:07:26 krw Exp $ */ +/* $OpenBSD: aic79xx_openbsd.c,v 1.14 2004/12/19 06:17:54 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -664,12 +664,13 @@ ahd_platform_set_tags(struct ahd_softc *ahd, int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) { - ahd->platform_data = malloc(sizeof(struct ahd_platform_data), M_DEVBUF, - M_NOWAIT /*| M_ZERO*/); - if (ahd->platform_data == NULL) - return (ENOMEM); - - memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); + if (sizeof(struct ahd_platform_data) > 0) { + ahd->platform_data = malloc(sizeof(struct ahd_platform_data), + M_DEVBUF, M_NOWAIT); + if (ahd->platform_data == NULL) + return (ENOMEM); + bzero(ahd->platform_data, sizeof(struct ahd_platform_data)); + } return (0); } @@ -677,7 +678,8 @@ ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) void ahd_platform_free(struct ahd_softc *ahd) { - free(ahd->platform_data, M_DEVBUF); + if (sizeof(struct ahd_platform_data) > 0) + free(ahd->platform_data, M_DEVBUF); } int diff --git a/sys/dev/pci/ahd_pci.c b/sys/dev/pci/ahd_pci.c index b38848fcd20..07376f5213b 100644 --- a/sys/dev/pci/ahd_pci.c +++ b/sys/dev/pci/ahd_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ahd_pci.c,v 1.10 2004/12/10 17:43:19 krw Exp $ */ +/* $OpenBSD: ahd_pci.c,v 1.11 2004/12/19 06:17:54 krw Exp $ */ /* * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom @@ -337,48 +337,24 @@ ahd_pci_attach(struct device *parent, struct device *self, void *aux) const struct ahd_pci_identity *entry; struct pci_attach_args *pa = aux; struct ahd_softc *ahd = (void *)self; - struct scb_data *shared_scb_data; pci_intr_handle_t ih; const char *intrstr; pcireg_t command, devconfig, memtype, reg, subid; uint16_t device, subvendor; int error, ioh_valid, ioh2_valid, l, memh_valid, offset; - shared_scb_data = NULL; ahd->dev_softc = pa; - - ahd_set_name(ahd, ahd->sc_dev.dv_xname); ahd->parent_dmat = pa->pa_dmat; + if (ahd_alloc(ahd, ahd->sc_dev.dv_xname) == NULL) + return; + command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); entry = ahd_find_pci_device(pa->pa_id, subid); if (entry == NULL) return; - ahd->seep_config = malloc(sizeof(*ahd->seep_config), - M_DEVBUF, M_NOWAIT); - if (ahd->seep_config == NULL) { - printf("%s: cannot malloc seep_config!\n", ahd_name(ahd)); - return; - } - memset(ahd->seep_config, 0, sizeof(*ahd->seep_config)); - - LIST_INIT(&ahd->pending_scbs); - - ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A - | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A; - ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT; - ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT; - ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT; - ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT; - ahd->int_coalescing_stop_threshold = AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT; - - if (ahd_platform_alloc(ahd, NULL) != 0) { - ahd_free(ahd); - return; - } - /* * Record if this is a HostRAID board. */ -- cgit v1.2.3