Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Jun 2009 14:23:12 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 164272 for review
Message-ID:  <200906131423.n5DENClK066298@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=164272

Change 164272 by mav@mav_mavbook on 2009/06/13 14:22:44

	In preparation to PM support add flag that command require detailed
	status on successfull completion. Also make such command not to be
	queued by AHCI controller, as it is unable to report all results if
	several commands were completed on same interrupt.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.c#8 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.h#8 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#15 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#24 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#11 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.c#8 (text+ko) ====

@@ -133,11 +133,11 @@
 	ataio->cmd.features_exp = sector_count >> 8;
 }
 
-void	ata_reset_cmd(struct ccb_ataio *ataio, int reset)
+void	ata_reset_cmd(struct ccb_ataio *ataio)
 {
 	bzero(&ataio->cmd, sizeof(ataio->cmd));
-	ataio->cmd.flags = CAM_ATAIO_CONTROL;
-	ataio->cmd.control = reset ? 0x04 : 0;
+	ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT;
+	ataio->cmd.control = 0x04;
 }
 
 #endif /* _KERNEL */

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.h#8 (text+ko) ====

@@ -38,6 +38,7 @@
 #define		CAM_ATAIO_48BIT		0x01	/* Command has 48-bit format */
 #define		CAM_ATAIO_FPDMA		0x02	/* FPDMA command */
 #define		CAM_ATAIO_CONTROL	0x04	/* Control, not a command */
+#define		CAM_ATAIO_NEEDRESULT	0x08	/* Request requires result. */
 
 	u_int8_t	command;
 	u_int8_t	features;
@@ -85,6 +86,6 @@
     uint64_t lba, uint16_t sector_count);
 void	ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
     uint64_t lba, uint16_t sector_count);
-void	ata_reset_cmd(struct ccb_ataio *ataio, int reset);
+void	ata_reset_cmd(struct ccb_ataio *ataio);
 
 #endif

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#15 (text+ko) ====

@@ -336,7 +336,7 @@
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      30 * 1000);
-		ata_reset_cmd(ataio, 1);
+		ata_reset_cmd(ataio);
 		break;
 	case PROBE_IDENTIFY:
 	{

==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#24 (text+ko) ====

@@ -904,11 +904,14 @@
 			return (1);
 	}
 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
-	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
-		/* Control command while anything active. */
+	    (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) {
+		/* Atomic command while anything active. */
 		if (ch->numrslots != 0)
 			return (1);
 	}
+       /* We have some atomic command running. */
+       if (ch->aslots != 0)
+               return (1);
 	return (0);
 }
 
@@ -938,11 +941,14 @@
 	slot->ccb = ccb;
 	/* Update channel stats. */
 	ch->numrslots++;
-	if ((slot->ccb->ccb_h.func_code == XPT_ATA_IO) &&
-	    (slot->ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
+	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
+	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
 		ch->numtslots++;
 		ch->taggedtarget = ccb->ccb_h.target_id;
 	}
+	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
+	    (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)))
+		ch->aslots |= (1 << slot->slot);
 	slot->dma.nsegs = 0;
 	/* If request moves data, setup and load SG list */
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
@@ -1030,7 +1036,7 @@
 	/* Special handling for Soft Reset command. */
 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
 	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
-	    ccb->ataio.cmd.control & ATA_A_RESET) {
+	    (ccb->ataio.cmd.control & ATA_A_RESET)) {
 		/* Kick controller into sane state */
 		ahci_stop(dev);
 		ahci_clo(dev);
@@ -1151,8 +1157,8 @@
 	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
 		struct ata_res *res = &ccb->ataio.res;
 
-		if (et == AHCI_ERR_REAL ||
-		    ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) {
+		if ((et == AHCI_ERR_REAL) ||
+		    (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) {
 			u_int8_t *fis = ch->dma.rfis + 0x40;
 
 			bus_dmamap_sync(ch->dma.rfis_tag, ch->dma.rfis_map,
@@ -1209,6 +1215,7 @@
 	}
 	/* Free slot. */
 	ch->rslots &= ~(1 << slot->slot);
+	ch->aslots &= ~(1 << slot->slot);
 	slot->state = AHCI_SLOT_EMPTY;
 	slot->ccb = NULL;
 	/* Update channel stats. */
@@ -1217,8 +1224,8 @@
 	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
 		ch->numtslots--;
 	}
-	/* If it was first request of reset sequence nod no error,
-	 * proceed to second. */
+	/* If it was first request of reset sequence and there is no error,
+	 * proceed to second request. */
 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
 	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
 	    (ccb->ataio.cmd.control & ATA_A_RESET) &&
@@ -1233,11 +1240,7 @@
 //device_printf(dev, "Unfreeze\n");
 		ch->frozen = NULL;
 		ahci_begin_transaction(dev, fccb);
-		/* If frozen command is not reset - release queue.
-		 * Reset will be released after it is finished. */
-		if ((fccb->ccb_h.func_code == XPT_ATA_IO) &&
-		    (fccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0)
-			xpt_release_simq(ch->sim, TRUE);
+		xpt_release_simq(ch->sim, TRUE);
 	}
 }
 
@@ -1534,19 +1537,13 @@
 		}
 		/* Check for command collision. */
 		if (ahci_check_collision(dev, ccb)) {
+//device_printf(dev, "Freeze\n");
 			/* Freeze command. */
-//device_printf(dev, "Freeze\n");
+			ch->frozen = ccb;
 			/* We have only one frozen slot, so freeze simq also. */
 			xpt_freeze_simq(ch->sim, 1);
-			ch->frozen = ccb;
 			return;
 		}
-		/* If it is a reset sequence - freeze the queue. */
-		if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
-		    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
-			xpt_freeze_simq(ch->sim, 1);
-			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
-		}
 		ahci_begin_transaction(dev, ccb);
 		break;
 	case XPT_EN_LUN:		/* Enable LUN as a target */

==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#11 (text+ko) ====

@@ -343,6 +343,7 @@
 	struct mtx		mtx;		/* state lock */
 	int			devices;        /* What is present */
 	uint32_t		rslots;		/* Running slots */
+	uint32_t		aslots;		/* Slots with atomic commands  */
 	int			numrslots;	/* Number of running slots */
 	int			numtslots;	/* Number of tagged slots */
 	int			lastslot;	/* Last used slot */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906131423.n5DENClK066298>