PERFORCE change 163908 for review
Alexander Motin
mav at FreeBSD.org
Tue Jun 9 16:20:12 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163908
Change 163908 by mav at 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,
More information about the p4-projects
mailing list