summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ips/ips.c10
-rw-r--r--sys/dev/ips/ips.h3
-rw-r--r--sys/dev/ips/ips_commands.c12
-rw-r--r--sys/dev/ips/ips_pci.c28
4 files changed, 38 insertions, 15 deletions
diff --git a/sys/dev/ips/ips.c b/sys/dev/ips/ips.c
index 984fdf9fab41..4d6d1fd0c35b 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 888cc40167f1..68b41e55fadb 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 6b47af57e622..7efb56c95b8b 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 4999de6171a3..f998732491c8 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;
}