From owner-p4-projects@FreeBSD.ORG Tue Jun 9 16:20:11 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2524C1065678; Tue, 9 Jun 2009 16:20:11 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6C441065672 for ; Tue, 9 Jun 2009 16:20:10 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C2DE28FC13 for ; Tue, 9 Jun 2009 16:20:10 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n59GKAbJ024570 for ; Tue, 9 Jun 2009 16:20:10 GMT (envelope-from mav@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n59GKAvS024568 for perforce@freebsd.org; Tue, 9 Jun 2009 16:20:10 GMT (envelope-from mav@freebsd.org) Date: Tue, 9 Jun 2009 16:20:10 GMT Message-Id: <200906091620.n59GKAvS024568@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mav@freebsd.org using -f From: Alexander Motin To: Perforce Change Reviews Cc: Subject: PERFORCE change 163908 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Jun 2009 16:20:12 -0000 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,