diff options
author | scottl <scottl@FreeBSD.org> | 2003-06-26 00:03:59 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-06-26 00:03:59 +0000 |
commit | 2c94c4118c28e42becd45242eccfb3dbc15e199c (patch) | |
tree | a44cbcf05050fb0e7ea38906671beb724d169bf6 | |
parent | 3a0952afbd82dda0c03d4f658194fd1503720a44 (diff) | |
download | FreeBSD-src-2c94c4118c28e42becd45242eccfb3dbc15e199c.zip FreeBSD-src-2c94c4118c28e42becd45242eccfb3dbc15e199c.tar.gz |
- Zero the buffers used to hold configuration data from the card. Not doing
so can leave stale data in the buffer and confuse the driver.
- enable the ability to set the 'disable' hint for the driver to keep it
from attaching. i.e. 'hw.ips.0.disable=1' will prevent the driver from
attaching.
- Only detach if attach suceeded.
Submitted by: mjacob
-rw-r--r-- | sys/dev/ips/ips.c | 10 | ||||
-rw-r--r-- | sys/dev/ips/ips.h | 3 | ||||
-rw-r--r-- | sys/dev/ips/ips_commands.c | 12 | ||||
-rw-r--r-- | sys/dev/ips/ips_pci.c | 28 |
4 files changed, 38 insertions, 15 deletions
diff --git a/sys/dev/ips/ips.c b/sys/dev/ips/ips.c index 984fdf9..4d6d1fd 100644 --- a/sys/dev/ips/ips.c +++ b/sys/dev/ips/ips.c @@ -322,6 +322,7 @@ static void ips_timeout(void *arg) /* check card and initialize it */ int ips_adapter_init(ips_softc_t *sc) { + int i; DEVICE_PRINTF(1,sc->dev, "initializing\n"); if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, /* alignemnt */ 1, @@ -359,13 +360,18 @@ int ips_adapter_init(ips_softc_t *sc) can handle */ sc->max_cmds = 1; ips_cmdqueue_init(sc); + callout_handle_init(&sc->timer); if(sc->ips_adapter_reinit(sc, 0)) goto error; mtx_init(&sc->cmd_mtx, "ips command mutex", NULL, MTX_DEF); - if(ips_get_adapter_info(sc) || ips_get_drive_info(sc)){ - device_printf(sc->dev, "failed to get configuration data from device\n"); + if ((i = ips_get_adapter_info(sc)) != 0) { + device_printf(sc->dev, "failed to get adapter configuration data from device (%d)\n", i); + goto error; + } + if ((i = ips_get_drive_info(sc)) != 0) { + device_printf(sc->dev, "failed to get drive configuration data from device (%d)\n", i); goto error; } ips_update_nvram(sc); /* no error check as failure doesn't matter */ diff --git a/sys/dev/ips/ips.h b/sys/dev/ips/ips.h index 888cc40..68b41e5 100644 --- a/sys/dev/ips/ips.h +++ b/sys/dev/ips/ips.h @@ -343,7 +343,8 @@ typedef struct ips_wait_list{ typedef struct ips_softc{ struct resource * iores; struct resource * irqres; - int state; + int configured; + int state; int iotype; int rid; int irqrid; diff --git a/sys/dev/ips/ips_commands.c b/sys/dev/ips/ips_commands.c index 6b47af5..7efb56c 100644 --- a/sys/dev/ips/ips_commands.c +++ b/sys/dev/ips/ips_commands.c @@ -266,7 +266,7 @@ int ips_get_adapter_info(ips_softc_t *sc) { int error = 0; ips_cmd_status_t *status; - status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT); + status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; if(ips_get_free_cmd(sc, ips_send_adapter_info_cmd, status, @@ -275,7 +275,7 @@ int ips_get_adapter_info(ips_softc_t *sc) free(status, M_DEVBUF); return ENXIO; } - if(COMMAND_ERROR(status)){ + if (COMMAND_ERROR(status)){ error = ENXIO; } free(status, M_DEVBUF); @@ -372,7 +372,7 @@ int ips_get_drive_info(ips_softc_t *sc) { int error = 0; ips_cmd_status_t *status; - status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT); + status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; if(ips_get_free_cmd(sc, ips_send_drive_info_cmd, status, @@ -415,7 +415,7 @@ static int ips_send_flush_cache_cmd(ips_command_t *command) int ips_flush_cache(ips_softc_t *sc) { ips_cmd_status_t *status; - status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT); + status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; device_printf(sc->dev, "flushing cache\n"); @@ -534,7 +534,7 @@ exit: int ips_update_nvram(ips_softc_t *sc) { ips_cmd_status_t *status; - status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT); + status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; if(ips_get_free_cmd(sc, ips_read_nvram, status, IPS_NOWAIT_FLAG)){ @@ -602,7 +602,7 @@ static int ips_send_error_table_cmd(ips_command_t *command) int ips_clear_adapter(ips_softc_t *sc) { ips_cmd_status_t *status; - status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT); + status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; device_printf(sc->dev, "syncing config\n"); diff --git a/sys/dev/ips/ips_pci.c b/sys/dev/ips/ips_pci.c index 4999de6..f998732 100644 --- a/sys/dev/ips/ips_pci.c +++ b/sys/dev/ips/ips_pci.c @@ -50,8 +50,17 @@ static int ips_pci_probe(device_t dev) static int ips_pci_attach(device_t dev) { u_int32_t command; + int tval; ips_softc_t *sc; + + tval = 0; + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "disable", &tval) == 0 && tval) { + device_printf(dev, "device is disabled\n"); + /* but return 0 so the !$)$)*!$*) unit isn't reused */ + return (0); + } DEVICE_PRINTF(1, dev, "in attach.\n"); sc = (ips_softc_t *)device_get_softc(dev); if(!sc){ @@ -125,6 +134,7 @@ static int ips_pci_attach(device_t dev) } if(ips_adapter_init(sc)) goto error; + sc->configured = 1; return 0; error: ips_pci_free(sc); @@ -141,6 +151,7 @@ static int ips_pci_free(ips_softc_t *sc) bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqrid, sc->irqres); if(sc->iores) bus_release_resource(sc->dev, sc->iotype, sc->rid, sc->iores); + sc->configured = 0; return 0; } @@ -149,18 +160,23 @@ static int ips_pci_detach(device_t dev) ips_softc_t *sc; DEVICE_PRINTF(1, dev, "detaching ServeRaid\n"); sc = (ips_softc_t *) device_get_softc(dev); - ips_flush_cache(sc); - if(ips_adapter_free(sc)) - return EBUSY; - ips_pci_free(sc); - mtx_destroy(&sc->cmd_mtx); + if (sc->configured) { + sc->configured = 0; + ips_flush_cache(sc); + if(ips_adapter_free(sc)) + return EBUSY; + ips_pci_free(sc); + mtx_destroy(&sc->cmd_mtx); + } return 0; } static int ips_pci_shutdown(device_t dev) { ips_softc_t *sc = (ips_softc_t *) device_get_softc(dev); - ips_flush_cache(sc); + if (sc->configured) { + ips_flush_cache(sc); + } return 0; } |