Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Jun 2009 16:20:10 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 163908 for review
Message-ID:  <200906091620.n59GKAvS024568@repoman.freebsd.org>

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

Change 163908 by mav@mav_mavbook on 2009/06/09 16:19:15

	Further cleanup.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#21 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#9 edit

Differences ...

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

@@ -138,26 +138,23 @@
 		rman_fini(&ctlr->sc_iomem);
 		return (error);
 	}
-
-	/* reset controller */
+	/* Reset controller */
 	if ((error = ahci_ctlr_reset(dev)) != 0) {
 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
 		rman_fini(&ctlr->sc_iomem);
 		return (error);
 	};
-
-	/* get the number of HW channels */
+	/* Get the number of HW channels */
 	ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI);
 	ctlr->channels = MAX(flsl(ctlr->ichannels),
 	    (ATA_INL(ctlr->r_mem, AHCI_CAP) & AHCI_CAP_NPMASK) + 1);
-
+	/* Setup interrupts. */
 	if (ahci_setup_interrupt(dev)) {
 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
 		rman_fini(&ctlr->sc_iomem);
 		return ENXIO;
 	}
-
-	/* announce we support the HW */
+	/* Announce HW capabilities. */
 	version = ATA_INL(ctlr->r_mem, AHCI_VS);
 	caps = ATA_INL(ctlr->r_mem, AHCI_CAP);
 	speed = (caps & AHCI_CAP_ISS) >> AHCI_CAP_ISS_SHIFT;
@@ -195,8 +192,7 @@
 		    (caps & AHCI_CAP_SXS) ? " eSATA":"",
 		    (caps & AHCI_CAP_NPMASK) + 1);
 	}
-
-	/* attach all channels on this controller */
+	/* Attach all channels on this controller */
 	for (unit = 0; unit < ctlr->channels; unit++) {
 		if ((ctlr->ichannels & (1 << unit)) == 0)
 			continue;
@@ -217,13 +213,13 @@
 	device_t *children;
 	int nchildren, i;
 
-	/* detach & delete all children */
+	/* Detach & delete all children */
 	if (!device_get_children(dev, &children, &nchildren)) {
 		for (i = 0; i < nchildren; i++)
 			device_delete_child(dev, children[i]);
 		free(children, M_TEMP);
 	}
-
+	/* Free interrupts. */
 	for (i = 0; i < ctlr->numirqs; i++) {
 		if (ctlr->irqs[i].r_irq) {
 			bus_teardown_intr(dev, ctlr->irqs[i].r_irq,
@@ -233,7 +229,7 @@
 		}
 	}
 	pci_release_msi(dev);
-
+	/* Free memory. */
 	rman_fini(&ctlr->sc_iomem);
 	if (ctlr->r_mem)
 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
@@ -249,11 +245,9 @@
 	if (pci_read_config(dev, 0x00, 4) == 0x28298086 &&
 	    (pci_read_config(dev, 0x92, 1) & 0xfe) == 0x04)
 		pci_write_config(dev, 0x92, 0x01, 1);
-
-	/* enable AHCI mode */
+	/* Enable AHCI mode */
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
-
-	/* reset AHCI controller */
+	/* Reset AHCI controller */
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE|AHCI_GHC_HR);
 	for (timeout = 1000; timeout > 0; timeout--) {
 		DELAY(1000);
@@ -264,18 +258,14 @@
 		device_printf(dev, "AHCI controller reset failure\n");
 		return ENXIO;
 	}
-
-	/* reenable AHCI mode */
+	/* Reenable AHCI mode */
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
-
-	/* clear interrupts */
+	/* Clear interrupts */
 	ATA_OUTL(ctlr->r_mem, AHCI_IS, ATA_INL(ctlr->r_mem, AHCI_IS));
-
-	/* enable AHCI interrupts */
+	/* Enable AHCI interrupts */
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC,
 	    ATA_INL(ctlr->r_mem, AHCI_GHC) | AHCI_GHC_IE);
-
-	return 0;
+	return (0);
 }
 
 static int
@@ -284,7 +274,7 @@
 	struct ahci_controller *ctlr = device_get_softc(dev);
 
 	bus_generic_suspend(dev);
-	/* disable interupts so the state change(s) doesn't trigger */
+	/* Disable interupts, so the state change(s) doesn't trigger */
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC,
 	     ATA_INL(ctlr->r_mem, AHCI_GHC) & (~AHCI_GHC_IE));
 	return 0;
@@ -306,6 +296,7 @@
 	struct ahci_controller *ctlr = device_get_softc(dev);
 	int i, msi = 0;
 
+	/* Process hints. */
 	if (resource_int_value(device_get_name(dev),
 	    device_get_unit(dev), "msi", &i) == 0) {
 		if (i == 1)
@@ -313,17 +304,20 @@
 		else if (i > 1)
 			msi = pci_msi_count(dev);
 	}
+	/* Allocate MSI if needed/present. */
 	if (msi && pci_alloc_msi(dev, &msi) == 0) {
 		ctlr->numirqs = msi;
 	} else {
 		msi = 0;
 		ctlr->numirqs = 1;
 	}
+	/* Check for single MSI vector fallback. */
 	if (ctlr->numirqs > 1 &&
 	    (ATA_INL(ctlr->r_mem, AHCI_GHC) & AHCI_GHC_MRSM) != 0) {
 		device_printf(dev, "Falling back to one MSI\n");
 		ctlr->numirqs = 1;
 	}
+	/* Allocate all IRQs. */
 	for (i = 0; i < ctlr->numirqs; i++) {
 		ctlr->irqs[i].ctlr = ctlr;
 		ctlr->irqs[i].r_irq_rid = i + (msi ? 1 : 0);
@@ -349,6 +343,9 @@
 	return (0);
 }
 
+/*
+ * Common case interrupt handler.
+ */
 static void
 ahci_intr(void *data)
 {
@@ -373,6 +370,9 @@
 	}
 }
 
+/*
+ * Simplified interrupt handler for multivector MSI mode.
+ */
 static void
 ahci_intr_one(void *data)
 {
@@ -453,7 +453,6 @@
 	}
 	ctlr->interrupt[unit].function = function;
 	ctlr->interrupt[unit].argument = argument;
-	*cookiep = ctlr;
 	return (0);
 }
 
@@ -502,80 +501,77 @@
 static int
 ahci_ch_attach(device_t dev)
 {
+	struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
 	struct ahci_channel *ch = device_get_softc(dev);
 	struct cam_devq *devq;
-	int tagged_dev_openings;
-	int rid;
+	int rid, error;
 
 	ch->dev = dev;
 	ch->unit = (intptr_t)device_get_ivars(dev);
+	ch->caps = ATA_INL(ctlr->r_mem, AHCI_CAP);
+	ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1,
+	resource_int_value(device_get_name(dev),
+	    device_get_unit(dev), "pm_level", &ch->pm_level);
 	mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF);
 	rid = ch->unit;
 	if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
 	    &rid, RF_ACTIVE)))
 		return (ENXIO);
-
 	ahci_dmainit(dev);
 	ahci_slotsalloc(dev);
 	ahci_ch_resume(dev);
-
 	mtx_lock(&ch->mtx);
-	/*
-	 * We don't do tagged queueing, since the aha cards don't
-	 * support it.
-	 */
-	tagged_dev_openings = 0;
-
-	/*
-	 * Create the device queue for our SIM.
-	 */
-	devq = cam_simq_alloc(32);
-	if (devq == NULL)
-		return (ENOMEM);
-
 	rid = ATA_IRQ_RID;
 	if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
 	    &rid, RF_SHAREABLE | RF_ACTIVE))) {
 		bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
-		device_printf(dev, "unable to map interrupt\n");
-		return ENXIO;
+		device_printf(dev, "Unable to map interrupt\n");
+		return (ENXIO);
 	}
 	if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL,
 	    ahci_ch_intr, dev, &ch->ih))) {
-		bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
-		bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
-		device_printf(dev, "unable to setup interrupt\n");
-		return ENXIO;
+		device_printf(dev, "Unable to setup interrupt\n");
+		error = ENXIO;
+		goto err1;
+	}
+	/* Create the device queue for our SIM. */
+	devq = cam_simq_alloc(ch->numslots);
+	if (devq == NULL) {
+		device_printf(dev, "Unable to allocate simq\n");
+		error = ENOMEM;
+		goto err1;
 	}
-
-	/*
-	 * Construct our SIM entry
-	 */
+	/* Construct SIM entry */
 	ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch,
-	    device_get_unit(dev), &ch->mtx, 32, tagged_dev_openings, devq);
+	    device_get_unit(dev), &ch->mtx, ch->numslots, 0, devq);
 	if (ch->sim == NULL) {
-		cam_simq_free(devq);
-		bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
 		device_printf(dev, "unable to allocate sim\n");
-		return (ENOMEM);
+		error = ENOMEM;
+		goto err2;
 	}
 	if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) {
-		cam_sim_free(ch->sim, /*free_devq*/TRUE);
-		bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
 		device_printf(dev, "unable to register xpt bus\n");
-		return (ENXIO);
+		error = ENXIO;
+		goto err2;
 	}
 	if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim),
 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
-		xpt_bus_deregister(cam_sim_path(ch->sim));
-		cam_sim_free(ch->sim, /*free_devq*/TRUE);
-		bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
 		device_printf(dev, "unable to create path\n");
-		return (ENXIO);
+		error = ENXIO;
+		goto err3;
 	}
-	
+	mtx_unlock(&ch->mtx);
+	return (0);
+
+err3:
+	xpt_bus_deregister(cam_sim_path(ch->sim));
+err2:
+	cam_sim_free(ch->sim, /*free_devq*/TRUE);
+err1:
+	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
+	bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
 	mtx_unlock(&ch->mtx);
-	return 0;
+	return (error);
 }
 
 static int
@@ -672,7 +668,6 @@
 static void
 ahci_dmainit(device_t dev)
 {
-	struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
 	struct ahci_channel *ch = device_get_softc(dev);
 	struct ahci_dc_cb_args dcba;
 
@@ -680,7 +675,7 @@
 	ch->dma.boundary = 65536;
 	ch->dma.segsize = 65536;
 	ch->dma.max_iosize = AHCI_DMA_ENTRIES * PAGE_SIZE;
-	if (ATA_INL(ctlr->r_mem, AHCI_CAP) & AHCI_CAP_64BIT)
+	if (ch->caps & AHCI_CAP_64BIT)
 		ch->dma.max_address = BUS_SPACE_MAXADDR;
 	else
 		ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
@@ -706,7 +701,7 @@
 	    ch->dma.alignment, ch->dma.boundary,
 	    ch->dma.max_address, BUS_SPACE_MAXADDR,
 	    NULL, NULL,
-	    ch->dma.max_iosize * AHCI_MAX_SLOTS,
+	    ch->dma.max_iosize * ch->numslots,
 	    AHCI_DMA_ENTRIES, ch->dma.segsize,
 	    0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) {
 		goto error;
@@ -714,7 +709,7 @@
 	return;
 
 error:
-	device_printf(dev, "WARNING - DMA initialization failed, disabling DMA\n");
+	device_printf(dev, "WARNING - DMA initialization failed\n");
 	ahci_dmafini(dev);
 }
 
@@ -758,7 +753,7 @@
 
 	/* Alloc and setup command/dma slots */
 	bzero(ch->slot, sizeof(ch->slot));
-	for (i = 0; i < AHCI_MAX_SLOTS; i++) {
+	for (i = 0; i < ch->numslots; i++) {
 		struct ahci_slot *slot = &ch->slot[i];
 
 		slot->dev = dev;
@@ -795,7 +790,7 @@
 	int i;
 
 	/* Free all dma slots */
-	for (i = 0; i < AHCI_MAX_SLOTS; i++) {
+	for (i = 0; i < ch->numslots; i++) {
 		struct ahci_slot *slot = &ch->slot[i];
 
 		if (slot->dma.sg_tag) {
@@ -827,7 +822,7 @@
 
 	/* Clear error bits/interrupt */
 	ATA_OUTL(ch->r_mem, AHCI_P_SERR, error);
-	/* If we have a connection event deal with it */
+	/* If we have a connection event, deal with it */
 	if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
 		u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
 		if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
@@ -861,18 +856,15 @@
 	cstatus = ATA_INL(ch->r_mem, AHCI_P_CI);
 	sstatus = ATA_INL(ch->r_mem, AHCI_P_SACT);
 //device_printf(dev, "%s is %08x cs %08x ss %08x rslots %08x\n", __func__, istatus, cstatus, sstatus, ch->rslots);
-
 	/* Process PHY events */
 	if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
 		ahci_phy_check_events(dev);
-
-#define AHCI_STATBITS \
-	(AHCI_P_IX_IF|AHCI_P_IX_HBD|AHCI_P_IX_HBF|AHCI_P_IX_TFE)
-	if ((istatus & AHCI_STATBITS) && ((cstatus | sstatus) & ch->rslots)) {
+	/* Process command errors */
+	if (istatus & (AHCI_P_IX_IF|AHCI_P_IX_HBD|AHCI_P_IX_HBF|AHCI_P_IX_TFE)) {
 device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x\n", __func__, istatus, cstatus, sstatus, ch->rslots);
 		ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
 		    >> AHCI_P_CMD_CCS_SHIFT;
-		/* kick controller into sane state */
+		/* Kick controller into sane state */
 		ahci_stop(dev);
 		ahci_start(dev);
 		res = ch->rslots;
@@ -891,16 +883,10 @@
 		xpt_done(fccb);
 	}
 	/* Check all slots. */
-	for (i = 0; i < AHCI_MAX_SLOTS; i++) {
+	for (i = 0; i < ch->numslots; i++) {
 		/* Do we have an event on slot? */
 	        if ((res & (1 << i)) == 0)
 			continue;
-		/* Do we have a running request on slot? */
-	        if (ch->slot[i].state < AHCI_SLOT_RUNNING) {
-			device_printf(dev, "Request completion on slot %d in state %d\n",
-			    i, ch->slot[i].state);
-			continue;
-		}
 		/* Process request completion. */
 		et = AHCI_ERR_NONE;
 		if ((err >> i) & 1) {
@@ -955,7 +941,7 @@
 	tag = ch->lastslot;
 	do {
 		tag++;
-		if (tag >= AHCI_MAX_SLOTS)
+		if (tag >= ch->numslots)
 			tag = 0;
 		if (ch->slot[tag].state == AHCI_SLOT_EMPTY)
 			break;
@@ -967,7 +953,6 @@
 	slot = &ch->slot[tag];
 //device_printf(slot->dev, "%s slot %d\n", __func__, slot->slot);
 	slot->ccb = ccb;
-	slot->dma.nsegs = 0;
 	/* Update channel stats. */
 	ch->numrslots++;
 	if ((slot->ccb->ccb_h.func_code == XPT_ATA_IO) &&
@@ -975,28 +960,28 @@
 		ch->numtslots++;
 		ch->taggedtarget = ccb->ccb_h.target_id;
 	}
+	slot->dma.nsegs = 0;
 	/* If request moves data, setup and load SG list */
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
+		void *buf;
+		bus_size_t size;
+
 		slot->state = AHCI_SLOT_LOADING;
 		if (ccb->ccb_h.func_code == XPT_ATA_IO) {
-			if (bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
-			    ccb->ataio.data_ptr, ccb->ataio.dxfer_len,
-			    ahci_dmasetprd, slot, 0)) {
-				device_printf(dev, "FAILURE - load data\n");
-			}
+			buf = ccb->ataio.data_ptr;
+			size = ccb->ataio.dxfer_len;
 		} else {
-			if (bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
-			    ccb->csio.data_ptr, ccb->csio.dxfer_len,
-			    ahci_dmasetprd, slot, 0)) {
-				device_printf(dev, "FAILURE - load data\n");
-			}
+			buf = ccb->csio.data_ptr;
+			size = ccb->csio.dxfer_len;
 		}
+		bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
+		    buf, size, ahci_dmasetprd, slot, 0);
 	} else
 		ahci_execute_transaction(slot);
 }
 
 /* Locked by busdma engine. */
-void
+static void
 ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {    
 	struct ahci_slot *slot = arg;
@@ -1008,28 +993,25 @@
 //device_printf(slot->dev, "%s slot %d\n", __func__, slot->slot);
 	if (error) {
 		device_printf(slot->dev, "DMA load error\n");
+		ahci_end_transaction(slot, AHCI_ERR_INVALID);
 		return;
 	}
-
 	KASSERT(nsegs <= AHCI_DMA_ENTRIES, ("too many DMA segment entries\n"));
-
-	/* get a piece of the workspace for this request */
+	/* Get a piece of the workspace for this request */
 	ctp = (struct ahci_cmd_tab *)
 		(ch->dma.work + AHCI_CT_OFFSET + (AHCI_CT_SIZE * slot->slot));
-
+	/* Fill S/G table */
 	prd = &ctp->prd_tab[0];
 	for (i = 0; i < nsegs; i++) {
 		prd[i].dba = htole64(segs[i].ds_addr);
 		prd[i].dbc = htole32((segs[i].ds_len - 1) & AHCI_PRD_MASK);
 	}
 	slot->dma.nsegs = nsegs;
-
 	bus_dmamap_sync(slot->dma.sg_tag, slot->dma.sg_map,
 	    BUS_DMASYNC_PREWRITE);
 	bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map,
 	    ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ?
 	    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
-
 	ahci_execute_transaction(slot);
 }
 
@@ -1051,9 +1033,8 @@
 		(ch->dma.work + AHCI_CT_OFFSET + (AHCI_CT_SIZE * slot->slot));
 	/* Setup the FIS for this request */
 	if (!(fis_size = ahci_setup_fis(ctp, ccb, slot->slot))) {
-		device_printf(ch->dev, "setting up SATA FIS failed\n");
-		ccb->ccb_h.status = CAM_REQ_INVALID;
-		xpt_done(ccb);
+		device_printf(ch->dev, "Setting up SATA FIS failed\n");
+		ahci_end_transaction(slot, AHCI_ERR_INVALID);
 		return;
 	}
 	/* Setup the command list entry */
@@ -1102,29 +1083,25 @@
 	if (ccb->ccb_h.func_code == XPT_ATA_IO &&
 	    (ccb->ataio.cmd.command == ATA_DEVICE_RESET ||
 	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL))) {
-		u_int32_t status;
 		int count, timeout = ccb->ccb_h.timeout;
 		enum ahci_err_type et = AHCI_ERR_NONE;
 
 		for (count = 0; count < timeout; count++) {
 			DELAY(1000);
-			if (!((status = ATA_INL(ch->r_mem, AHCI_P_CI)) &
-			    (1 << slot->slot))) {
+			if (!(ATA_INL(ch->r_mem, AHCI_P_CI) & (1 << slot->slot)))
 				break;
-			}
 		}
 		if (timeout && (count >= timeout)) {
 device_printf(ch->dev, "Poll timeout on slot %d\n", slot->slot);
 			et = CAM_CMD_TIMEOUT;
-			/* kick controller into sane state */
+			/* Kick controller into sane state */
 			ahci_stop(ch->dev);
 			ahci_start(ch->dev);
 		}
 		ahci_end_transaction(slot, et);
 		return;
 	}
-
-	/* start the timeout */
+	/* Start command execution timeout */
 	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
 	    (timeout_t*)ahci_timeout, slot);
 	return;
@@ -1140,6 +1117,7 @@
 	int i;
 
 device_printf(dev, "Timeout on slot %d\n", slot->slot);
+	/* Requeue freezed command. */
 	if (ch->frozen) {
 		union ccb *fccb = ch->frozen;
 		ch->frozen = NULL;
@@ -1147,10 +1125,11 @@
 		fccb->ccb_h.status = CAM_SCSI_BUS_RESET;
 		xpt_done(fccb);
 	}
+	/* Kill the engine and terminate all commands. */
 	ahci_stop(dev);
-	for (i = 0; i < AHCI_MAX_SLOTS; i++) {
+	for (i = 0; i < ch->numslots; i++) {
 		/* Do we have a running request on slot? */
-	        if (ch->slot[i].state < AHCI_SLOT_RUNNING)
+		if (ch->slot[i].state < AHCI_SLOT_RUNNING)
 			continue;
 		if (i == slot->slot)
 			et = AHCI_ERR_TIMEOUT;
@@ -1158,6 +1137,7 @@
 			et = AHCI_ERR_RESET;
 		ahci_end_transaction(&ch->slot[i], et);
 	}
+	/* XXX: This is wrong for NCQ error recovery. */
 	ahci_reset(dev);
 }
 
@@ -1171,9 +1151,9 @@
 //	struct ahci_cmd_list *clp;
 
 //device_printf(dev, "%s slot %d\n", __func__, slot->slot);
-	/* Kill the timeout */
+	/* Cancel command execution timeout */
 	callout_stop(&slot->timeout);
-	/* Read registers to the result struct */
+	/* Read result registers to the result struct */
 	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
 		struct ata_res *res = &ccb->ataio.res;
 		u_int8_t *fis = ch->dma.work + AHCI_FB_OFFSET + 0x40;
@@ -1211,6 +1191,9 @@
 		if (ccb->ccb_h.func_code == XPT_SCSI_IO)
 			ccb->csio.scsi_status = SCSI_STATUS_OK;
 		break;
+	case AHCI_ERR_INVALID:
+		ccb->ccb_h.status = CAM_REQ_INVALID;
+		break;
 	case AHCI_ERR_REAL:
 		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
 			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
@@ -1262,9 +1245,8 @@
 	ATA_OUTL(ch->r_mem, AHCI_P_IS, ATA_INL(ch->r_mem, AHCI_P_IS));
 	/* Start operations on this channel */
 	cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
-	ATA_OUTL(ch->r_mem, AHCI_P_CMD,
-	     cmd | AHCI_P_CMD_ST |
-	     (ch->devices & ATA_PORTMULTIPLIER ? AHCI_P_CMD_PMA : 0));
+	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST);
+//	     (ch->devices & ATA_PORTMULTIPLIER ? AHCI_P_CMD_PMA : 0));
 }
 
 static void
@@ -1292,13 +1274,12 @@
 static void
 ahci_clo(device_t dev)
 {
-	struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
 	struct ahci_channel *ch = device_get_softc(dev);
 	u_int32_t cmd;
 	int timeout;
 
 	/* Issue Command List Override if supported */ 
-	if (ATA_INL(ctlr->r_mem, AHCI_CAP) & AHCI_CAP_SCLO) {
+	if (ch->caps & AHCI_CAP_SCLO) {
 		cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
 		cmd |= AHCI_P_CMD_CLO;
 		ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd);
@@ -1410,7 +1391,7 @@
 		    (AHCI_P_IX_CPD | AHCI_P_IX_PRC | AHCI_P_IX_PC));
 		return;
 	}
-	ch->devices = ATA_ATA_MASTER;
+	ch->devices = 1;
 	/* Enable wanted port interrupts */
 	ATA_OUTL(ch->r_mem, AHCI_P_IE,
 	     (AHCI_P_IX_CPD | AHCI_P_IX_TFE | AHCI_P_IX_HBF |
@@ -1523,7 +1504,7 @@
 	DELAY(50000);
 	ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
 	    ATA_SC_DET_IDLE /*| ATA_SC_SPD_SPEED_GEN1*/ | ((ch->pm_level > 0) ? 0 :
-	    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER));
+	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
 	return (ahci_sata_connect(ch));
 }
 
@@ -1551,7 +1532,7 @@
 		/* Check for command collision. */
 		if (ahci_check_collision(dev, ccb)) {
 			/* Freeze command. */
-//device_printf(dev, "Freeze\n");
+device_printf(dev, "Freeze\n");
 			/* We have only one frozen slot, so freeze simq also. */
 			xpt_freeze_simq(ch->sim, 1);
 			ch->frozen = ccb;

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

@@ -289,13 +289,6 @@
     u_int32_t count;
 };  
 
-/* structure used by the setprd function */
-struct ata_dmasetprd_args {
-    void *dmatab;
-    int nsegs;
-    int error;
-};
-
 struct ata_dmaslot {
     bus_dma_tag_t               sg_tag;         /* SG list DMA tag */
     bus_dmamap_t                sg_map;         /* SG list DMA map */
@@ -319,8 +312,6 @@
     u_int32_t                   segsize;        /* DMA SG list segment size */
     u_int32_t                   max_iosize;     /* DMA data max IO size */
     u_int64_t                   max_address;    /* highest DMA'able address */
-    int                         flags;
-#define ATA_DMA_ACTIVE                  0x01    /* DMA transfer in progress */
 };
 
 #define         ATA_MASTER              0x00
@@ -335,46 +326,32 @@
 };
 
 struct ahci_slot {
-    device_t                    dev;            /* device handle */
+    device_t                    dev;            /* Device handle */
     u_int8_t			slot;           /* Number of this slot */
     enum ahci_slot_states	state;          /* Slot state */
-    union ccb			*ccb;
-    int                         flags;
-
-    struct ata_dmaslot          dma;            /* DMA slot of this request */
-    struct callout              timeout;        /* Timeout management */
+    union ccb			*ccb;		/* CCB occupying slot */
+    struct ata_dmaslot          dma;            /* DMA data of this slot */
+    struct callout              timeout;        /* Execution timeout */
 };
 
 
 /* structure describing an ATA channel */
 struct ahci_channel {
-    device_t                    dev;            /* device handle */
-    int                         unit;           /* physical channel */
-    struct resource     	*r_mem;
-    struct resource             *r_irq;         /* interrupt of this channel */
-    void                        *ih;            /* interrupt handle */
-    struct ata_dma              dma;            /* DMA data / functions */
-    int                         flags;          /* channel flags */
-#define         ATA_NO_SLAVE            0x01
-#define         ATA_USE_16BIT           0x02
-#define         ATA_ATAPI_DMA_RO        0x04
-#define         ATA_NO_48BIT_DMA        0x08
-#define         ATA_ALWAYS_DMASTAT      0x10
-
-    int				pm_level;	/* power management level */
-    int                         devices;        /* what is present */
-#define         ATA_ATA_MASTER          0x00000001
-#define         ATA_ATA_SLAVE           0x00000002
-#define         ATA_PORTMULTIPLIER      0x00008000
-#define         ATA_ATAPI_MASTER        0x00010000
-#define         ATA_ATAPI_SLAVE         0x00020000
-
-	struct mtx		mtx;      /* state lock */
-
+	device_t		dev;            /* Device handle */
+	int			unit;           /* Physical channel */
+	struct resource		*r_mem;		/* Memory of this channel */
+	struct resource		*r_irq;         /* Interrupt of this channel */
+	void			*ih;            /* Interrupt handle */
+	struct ata_dma		dma;            /* DMA data */
 	struct cam_sim		*sim;
 	struct cam_path		*path;
-	
+	uint32_t		caps;		/* Controller capabilities */
+	int			numslots;	/* Number of present slots */
+	int			pm_level;	/* power management level */
+
 	struct ahci_slot	slot[AHCI_MAX_SLOTS];
+	struct mtx		mtx;		/* state lock */
+	int			devices;        /* What is present */
 	uint32_t		rslots;		/* Running slots */
 	int			numrslots;	/* Number of running slots */
 	int			numtslots;	/* Number of tagged slots */
@@ -410,6 +387,7 @@
 
 enum ahci_err_type {
 	AHCI_ERR_NONE,
+	AHCI_ERR_INVALID,
 	AHCI_ERR_REAL,
 	AHCI_ERR_BTW,
 	AHCI_ERR_RESET,



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