svn commit: r220822 - in head/sys/dev: ahci mvs siis

Alexander Motin mav at FreeBSD.org
Tue Apr 19 08:01:18 UTC 2011


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);
 }
 


More information about the svn-src-all mailing list