Author: mav
Date: Thu Apr 28 07:26:28 2011
New Revision: 221154
URL: http://svn.freebsd.org/changeset/base/221154

Log:
  MFC r220822:
  Properly handle memory allocation errors during error recovery.

Modified:
  stable/8/sys/dev/ahci/ahci.c
  stable/8/sys/dev/mvs/mvs.c
  stable/8/sys/dev/siis/siis.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/ahci/ahci.c
==============================================================================
--- stable/8/sys/dev/ahci/ahci.c        Thu Apr 28 07:22:41 2011        
(r221153)
+++ stable/8/sys/dev/ahci/ahci.c        Thu Apr 28 07:26:28 2011        
(r221154)
@@ -2126,7 +2126,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])
@@ -2134,8 +2133,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) {
@@ -2148,8 +2159,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));
@@ -2177,6 +2189,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: stable/8/sys/dev/mvs/mvs.c
==============================================================================
--- stable/8/sys/dev/mvs/mvs.c  Thu Apr 28 07:22:41 2011        (r221153)
+++ stable/8/sys/dev/mvs/mvs.c  Thu Apr 28 07:26:28 2011        (r221154)
@@ -1780,7 +1780,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])
@@ -1788,8 +1787,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) {
@@ -1802,8 +1813,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));
@@ -1830,7 +1842,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: stable/8/sys/dev/siis/siis.c
==============================================================================
--- stable/8/sys/dev/siis/siis.c        Thu Apr 28 07:22:41 2011        
(r221153)
+++ stable/8/sys/dev/siis/siis.c        Thu Apr 28 07:26:28 2011        
(r221154)
@@ -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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to