Author: mav
Date: Tue Apr 19 08:01:17 2011
New Revision: 220822
URL: http://svn.freebsd.org/changeset/base/220822

Log:
  Properly handle memory allocation errors during error recovery.

Modified:
  head/sys/dev/ahci/ahci.c
  head/sys/dev/mvs/mvs.c
  head/sys/dev/siis/siis.c

Modified: head/sys/dev/ahci/ahci.c
==============================================================================
--- head/sys/dev/ahci/ahci.c    Tue Apr 19 08:00:44 2011        (r220821)
+++ head/sys/dev/ahci/ahci.c    Tue Apr 19 08:01:17 2011        (r220822)
@@ -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);
 }

Modified: head/sys/dev/mvs/mvs.c
==============================================================================
--- head/sys/dev/mvs/mvs.c      Tue Apr 19 08:00:44 2011        (r220821)
+++ head/sys/dev/mvs/mvs.c      Tue Apr 19 08:01:17 2011        (r220822)
@@ -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);
 }

Modified: head/sys/dev/siis/siis.c
==============================================================================
--- head/sys/dev/siis/siis.c    Tue Apr 19 08:00:44 2011        (r220821)
+++ head/sys/dev/siis/siis.c    Tue Apr 19 08:01:17 2011        (r220822)
@@ -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);
 }
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to