summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2011-04-19 08:01:17 +0000
committermav <mav@FreeBSD.org>2011-04-19 08:01:17 +0000
commitcc8f016bc18d45715487b51cf1921fa81a59259d (patch)
treeb127f1c0f2074a00cefb5b52a4696a36352ccb98 /sys
parentebedcfac8977c396375e952c56d739bc5eb917ed (diff)
downloadFreeBSD-src-cc8f016bc18d45715487b51cf1921fa81a59259d.zip
FreeBSD-src-cc8f016bc18d45715487b51cf1921fa81a59259d.tar.gz
Properly handle memory allocation errors during error recovery.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ahci/ahci.c23
-rw-r--r--sys/dev/mvs/mvs.c25
-rw-r--r--sys/dev/siis/siis.c23
3 files changed, 55 insertions, 16 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index e765a32..ac200cb 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -2132,7 +2132,6 @@ ahci_issue_recovery(device_t dev)
struct ccb_scsiio *csio;
int i;
- ch->recoverycmd = 1;
/* Find some holden command. */
for (i = 0; i < ch->numslots; i++) {
if (ch->hold[i])
@@ -2140,8 +2139,20 @@ ahci_issue_recovery(device_t dev)
}
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
- device_printf(dev, "Unable allocate READ LOG command");
- return; /* XXX */
+ device_printf(dev, "Unable allocate recovery command\n");
+completeall:
+ /* We can't do anything -- complete holden commands. */
+ for (i = 0; i < ch->numslots; i++) {
+ if (ch->hold[i] == NULL)
+ continue;
+ ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
+ ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL;
+ xpt_done(ch->hold[i]);
+ ch->hold[i] = NULL;
+ ch->numhslots--;
+ }
+ ahci_reset(dev);
+ return;
}
ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */
if (ccb->ccb_h.func_code == XPT_ATA_IO) {
@@ -2154,8 +2165,9 @@ ahci_issue_recovery(device_t dev)
ataio->data_ptr = malloc(512, M_AHCI, M_NOWAIT);
if (ataio->data_ptr == NULL) {
xpt_free_ccb(ccb);
- device_printf(dev, "Unable allocate memory for READ LOG command");
- return; /* XXX */
+ device_printf(dev,
+ "Unable allocate memory for READ LOG command\n");
+ goto completeall;
}
ataio->dxfer_len = 512;
bzero(&ataio->cmd, sizeof(ataio->cmd));
@@ -2183,6 +2195,7 @@ ahci_issue_recovery(device_t dev)
csio->cdb_io.cdb_bytes[4] = csio->dxfer_len;
}
/* Freeze SIM while doing recovery. */
+ ch->recoverycmd = 1;
xpt_freeze_simq(ch->sim, 1);
ahci_begin_transaction(dev, ccb);
}
diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index 0ab60cd..69e7a14 100644
--- a/sys/dev/mvs/mvs.c
+++ b/sys/dev/mvs/mvs.c
@@ -1781,7 +1781,6 @@ mvs_issue_recovery(device_t dev)
struct ccb_scsiio *csio;
int i;
- ch->recoverycmd = 1;
/* Find some holden command. */
for (i = 0; i < MVS_MAX_SLOTS; i++) {
if (ch->hold[i])
@@ -1789,8 +1788,20 @@ mvs_issue_recovery(device_t dev)
}
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
- device_printf(dev, "Unable allocate READ LOG command");
- return; /* XXX */
+ device_printf(dev, "Unable allocate recovery command\n");
+completeall:
+ /* We can't do anything -- complete holden commands. */
+ for (i = 0; i < MVS_MAX_SLOTS; i++) {
+ if (ch->hold[i] == NULL)
+ continue;
+ ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
+ ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL;
+ xpt_done(ch->hold[i]);
+ ch->hold[i] = NULL;
+ ch->numhslots--;
+ }
+ mvs_reset(dev);
+ return;
}
ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */
if (ccb->ccb_h.func_code == XPT_ATA_IO) {
@@ -1803,8 +1814,9 @@ mvs_issue_recovery(device_t dev)
ataio->data_ptr = malloc(512, M_MVS, M_NOWAIT);
if (ataio->data_ptr == NULL) {
xpt_free_ccb(ccb);
- device_printf(dev, "Unable allocate memory for READ LOG command");
- return; /* XXX */
+ device_printf(dev,
+ "Unable allocate memory for READ LOG command\n");
+ goto completeall;
}
ataio->dxfer_len = 512;
bzero(&ataio->cmd, sizeof(ataio->cmd));
@@ -1831,7 +1843,8 @@ mvs_issue_recovery(device_t dev)
csio->cdb_io.cdb_bytes[0] = 0x03;
csio->cdb_io.cdb_bytes[4] = csio->dxfer_len;
}
- /* Freeze SIM while doing READ LOG EXT. */
+ /* Freeze SIM while doing recovery. */
+ ch->recoverycmd = 1;
xpt_freeze_simq(ch->sim, 1);
mvs_begin_transaction(dev, ccb);
}
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index b974cf2..6e77e2e 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1373,11 +1373,22 @@ siis_issue_recovery(device_t dev)
}
if (i == SIIS_MAX_SLOTS)
return;
- ch->recoverycmd = 1;
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
- device_printf(dev, "Unable allocate READ LOG command");
- return; /* XXX */
+ device_printf(dev, "Unable allocate recovery command\n");
+completeall:
+ /* We can't do anything -- complete holden commands. */
+ for (i = 0; i < SIIS_MAX_SLOTS; i++) {
+ if (ch->hold[i] == NULL)
+ continue;
+ ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
+ ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL;
+ xpt_done(ch->hold[i]);
+ ch->hold[i] = NULL;
+ ch->numhslots--;
+ }
+ siis_reset(dev);
+ return;
}
ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */
if (ccb->ccb_h.func_code == XPT_ATA_IO) {
@@ -1390,8 +1401,9 @@ siis_issue_recovery(device_t dev)
ataio->data_ptr = malloc(512, M_SIIS, M_NOWAIT);
if (ataio->data_ptr == NULL) {
xpt_free_ccb(ccb);
- device_printf(dev, "Unable allocate memory for READ LOG command");
- return; /* XXX */
+ device_printf(dev,
+ "Unable allocate memory for READ LOG command\n");
+ goto completeall;
}
ataio->dxfer_len = 512;
bzero(&ataio->cmd, sizeof(ataio->cmd));
@@ -1418,6 +1430,7 @@ siis_issue_recovery(device_t dev)
csio->cdb_io.cdb_bytes[0] = 0x03;
csio->cdb_io.cdb_bytes[4] = csio->dxfer_len;
}
+ ch->recoverycmd = 1;
siis_begin_transaction(dev, ccb);
}
OpenPOWER on IntegriCloud