Deleted Added
full compact
ahci.c (199717) ahci.c (199747)
1/*-
2 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/ahci/ahci.c 199717 2009-11-23 18:07:28Z mav $");
28__FBSDID("$FreeBSD: head/sys/dev/ahci/ahci.c 199747 2009-11-24 12:47:58Z mav $");
29
30#include <sys/param.h>
31#include <sys/module.h>
32#include <sys/systm.h>
33#include <sys/kernel.h>
34#include <sys/ata.h>
35#include <sys/bus.h>
36#include <sys/endian.h>

--- 734 unchanged lines hidden (view full) ---

771}
772
773static int
774ahci_ch_attach(device_t dev)
775{
776 struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
777 struct ahci_channel *ch = device_get_softc(dev);
778 struct cam_devq *devq;
29
30#include <sys/param.h>
31#include <sys/module.h>
32#include <sys/systm.h>
33#include <sys/kernel.h>
34#include <sys/ata.h>
35#include <sys/bus.h>
36#include <sys/endian.h>

--- 734 unchanged lines hidden (view full) ---

771}
772
773static int
774ahci_ch_attach(device_t dev)
775{
776 struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
777 struct ahci_channel *ch = device_get_softc(dev);
778 struct cam_devq *devq;
779 int rid, error;
779 int rid, error, i;
780
781 ch->dev = dev;
782 ch->unit = (intptr_t)device_get_ivars(dev);
783 ch->caps = ctlr->caps;
784 ch->caps2 = ctlr->caps2;
785 ch->quirks = ctlr->quirks;
786 ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1,
787 mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF);
788 resource_int_value(device_get_name(dev),
789 device_get_unit(dev), "pm_level", &ch->pm_level);
790 if (ch->pm_level > 3)
791 callout_init_mtx(&ch->pm_timer, &ch->mtx, 0);
780
781 ch->dev = dev;
782 ch->unit = (intptr_t)device_get_ivars(dev);
783 ch->caps = ctlr->caps;
784 ch->caps2 = ctlr->caps2;
785 ch->quirks = ctlr->quirks;
786 ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1,
787 mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF);
788 resource_int_value(device_get_name(dev),
789 device_get_unit(dev), "pm_level", &ch->pm_level);
790 if (ch->pm_level > 3)
791 callout_init_mtx(&ch->pm_timer, &ch->mtx, 0);
792 for (i = 0; i < 16; i++) {
793 ch->user[i].revision = 0;
794 ch->user[i].mode = 0;
795 ch->user[i].bytecount = 8192;
796 ch->user[i].tags = ch->numslots;
797 ch->curr[i] = ch->user[i];
798 }
792 /* Limit speed for my onboard JMicron external port.
793 * It is not eSATA really. */
794 if (pci_get_devid(ctlr->dev) == 0x2363197b &&
795 pci_get_subvendor(ctlr->dev) == 0x1043 &&
796 pci_get_subdevice(ctlr->dev) == 0x81e4 &&
797 ch->unit == 0)
798 ch->sata_rev = 1;
799 resource_int_value(device_get_name(dev),

--- 470 unchanged lines hidden (view full) ---

1270 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1271 /* Tagged command while untagged are active. */
1272 if (ch->numrslots != 0 && ch->numtslots == 0)
1273 return (1);
1274 /* Tagged command while tagged to other target is active. */
1275 if (ch->numtslots != 0 &&
1276 ch->taggedtarget != ccb->ccb_h.target_id)
1277 return (1);
799 /* Limit speed for my onboard JMicron external port.
800 * It is not eSATA really. */
801 if (pci_get_devid(ctlr->dev) == 0x2363197b &&
802 pci_get_subvendor(ctlr->dev) == 0x1043 &&
803 pci_get_subdevice(ctlr->dev) == 0x81e4 &&
804 ch->unit == 0)
805 ch->sata_rev = 1;
806 resource_int_value(device_get_name(dev),

--- 470 unchanged lines hidden (view full) ---

1277 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1278 /* Tagged command while untagged are active. */
1279 if (ch->numrslots != 0 && ch->numtslots == 0)
1280 return (1);
1281 /* Tagged command while tagged to other target is active. */
1282 if (ch->numtslots != 0 &&
1283 ch->taggedtarget != ccb->ccb_h.target_id)
1284 return (1);
1285 /* Tagged command while we have no supported tag free. */
1286 if (((~ch->oslots) & (0xffffffff >> (32 -
1287 ch->curr[ccb->ccb_h.target_id].tags))) == 0)
1288 return (1);
1278 } else {
1279 /* Untagged command while tagged are active. */
1280 if (ch->numrslots != 0 && ch->numtslots != 0)
1281 return (1);
1282 }
1283 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1284 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) {
1285 /* Atomic command while anything active. */

--- 7 unchanged lines hidden (view full) ---

1293}
1294
1295/* Must be called with channel locked. */
1296static void
1297ahci_begin_transaction(device_t dev, union ccb *ccb)
1298{
1299 struct ahci_channel *ch = device_get_softc(dev);
1300 struct ahci_slot *slot;
1289 } else {
1290 /* Untagged command while tagged are active. */
1291 if (ch->numrslots != 0 && ch->numtslots != 0)
1292 return (1);
1293 }
1294 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1295 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) {
1296 /* Atomic command while anything active. */

--- 7 unchanged lines hidden (view full) ---

1304}
1305
1306/* Must be called with channel locked. */
1307static void
1308ahci_begin_transaction(device_t dev, union ccb *ccb)
1309{
1310 struct ahci_channel *ch = device_get_softc(dev);
1311 struct ahci_slot *slot;
1301 int tag;
1312 int tag, tags;
1302
1303 /* Choose empty slot. */
1313
1314 /* Choose empty slot. */
1315 tags = ch->numslots;
1316 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1317 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA))
1318 tags = ch->curr[ccb->ccb_h.target_id].tags;
1304 tag = ch->lastslot;
1319 tag = ch->lastslot;
1305 while (ch->slot[tag].state != AHCI_SLOT_EMPTY) {
1306 if (++tag >= ch->numslots)
1320 while (1) {
1321 if (tag >= tags)
1307 tag = 0;
1322 tag = 0;
1308 KASSERT(tag != ch->lastslot, ("ahci: ALL SLOTS BUSY!"));
1309 }
1323 if (ch->slot[tag].state == AHCI_SLOT_EMPTY)
1324 break;
1325 tag++;
1326 };
1310 ch->lastslot = tag;
1311 /* Occupy chosen slot. */
1312 slot = &ch->slot[tag];
1313 slot->ccb = ccb;
1314 /* Stop PM timer. */
1315 if (ch->numrslots == 0 && ch->pm_level > 3)
1316 callout_stop(&ch->pm_timer);
1317 /* Update channel stats. */
1327 ch->lastslot = tag;
1328 /* Occupy chosen slot. */
1329 slot = &ch->slot[tag];
1330 slot->ccb = ccb;
1331 /* Stop PM timer. */
1332 if (ch->numrslots == 0 && ch->pm_level > 3)
1333 callout_stop(&ch->pm_timer);
1334 /* Update channel stats. */
1335 ch->oslots |= (1 << slot->slot);
1318 ch->numrslots++;
1319 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1320 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1321 ch->numtslots++;
1322 ch->taggedtarget = ccb->ccb_h.target_id;
1323 }
1324 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1325 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)))

--- 304 unchanged lines hidden (view full) ---

1630 }
1631 ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1632 break;
1633 default:
1634 ch->fatalerr = 1;
1635 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1636 }
1637 /* Free slot. */
1336 ch->numrslots++;
1337 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1338 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1339 ch->numtslots++;
1340 ch->taggedtarget = ccb->ccb_h.target_id;
1341 }
1342 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1343 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)))

--- 304 unchanged lines hidden (view full) ---

1648 }
1649 ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1650 break;
1651 default:
1652 ch->fatalerr = 1;
1653 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1654 }
1655 /* Free slot. */
1656 ch->oslots &= ~(1 << slot->slot);
1638 ch->rslots &= ~(1 << slot->slot);
1639 ch->aslots &= ~(1 << slot->slot);
1640 slot->state = AHCI_SLOT_EMPTY;
1641 slot->ccb = NULL;
1642 /* Update channel stats. */
1643 ch->numrslots--;
1644 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1645 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {

--- 13 unchanged lines hidden (view full) ---

1659 if (ch->readlog) {
1660 ahci_process_read_log(dev, ccb);
1661 /* If it was NCQ command error, put result on hold. */
1662 } else if (et == AHCI_ERR_NCQ) {
1663 ch->hold[slot->slot] = ccb;
1664 } else
1665 xpt_done(ccb);
1666 /* Unfreeze frozen command. */
1657 ch->rslots &= ~(1 << slot->slot);
1658 ch->aslots &= ~(1 << slot->slot);
1659 slot->state = AHCI_SLOT_EMPTY;
1660 slot->ccb = NULL;
1661 /* Update channel stats. */
1662 ch->numrslots--;
1663 if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1664 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {

--- 13 unchanged lines hidden (view full) ---

1678 if (ch->readlog) {
1679 ahci_process_read_log(dev, ccb);
1680 /* If it was NCQ command error, put result on hold. */
1681 } else if (et == AHCI_ERR_NCQ) {
1682 ch->hold[slot->slot] = ccb;
1683 } else
1684 xpt_done(ccb);
1685 /* Unfreeze frozen command. */
1667 if (ch->frozen && ch->numrslots == 0) {
1686 if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) {
1668 union ccb *fccb = ch->frozen;
1669 ch->frozen = NULL;
1670 ahci_begin_transaction(dev, fccb);
1671 xpt_release_simq(ch->sim, TRUE);
1672 }
1673 /* If we have no other active commands, ... */
1674 if (ch->rslots == 0) {
1675 /* if there was fatal error - reset port. */

--- 444 unchanged lines hidden (view full) ---

2120 case XPT_ABORT: /* Abort the specified CCB */
2121 /* XXX Implement */
2122 ccb->ccb_h.status = CAM_REQ_INVALID;
2123 xpt_done(ccb);
2124 break;
2125 case XPT_SET_TRAN_SETTINGS:
2126 {
2127 struct ccb_trans_settings *cts = &ccb->cts;
1687 union ccb *fccb = ch->frozen;
1688 ch->frozen = NULL;
1689 ahci_begin_transaction(dev, fccb);
1690 xpt_release_simq(ch->sim, TRUE);
1691 }
1692 /* If we have no other active commands, ... */
1693 if (ch->rslots == 0) {
1694 /* if there was fatal error - reset port. */

--- 444 unchanged lines hidden (view full) ---

2139 case XPT_ABORT: /* Abort the specified CCB */
2140 /* XXX Implement */
2141 ccb->ccb_h.status = CAM_REQ_INVALID;
2142 xpt_done(ccb);
2143 break;
2144 case XPT_SET_TRAN_SETTINGS:
2145 {
2146 struct ccb_trans_settings *cts = &ccb->cts;
2147 struct ahci_device *d;
2128
2148
2129 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) {
2149 if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
2150 d = &ch->curr[ccb->ccb_h.target_id];
2151 else
2152 d = &ch->user[ccb->ccb_h.target_id];
2153 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
2154 d->revision = cts->xport_specific.sata.revision;
2155 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE)
2156 d->mode = cts->xport_specific.sata.mode;
2157 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
2158 d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
2159 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS)
2160 d->tags = min(ch->numslots, cts->xport_specific.sata.tags);
2161 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM)
2130 ch->pm_present = cts->xport_specific.sata.pm_present;
2162 ch->pm_present = cts->xport_specific.sata.pm_present;
2131 }
2132 ccb->ccb_h.status = CAM_REQ_CMP;
2133 xpt_done(ccb);
2134 break;
2135 }
2136 case XPT_GET_TRAN_SETTINGS:
2137 /* Get default/user set transfer settings for the target */
2138 {
2139 struct ccb_trans_settings *cts = &ccb->cts;
2163 ccb->ccb_h.status = CAM_REQ_CMP;
2164 xpt_done(ccb);
2165 break;
2166 }
2167 case XPT_GET_TRAN_SETTINGS:
2168 /* Get default/user set transfer settings for the target */
2169 {
2170 struct ccb_trans_settings *cts = &ccb->cts;
2171 struct ahci_device *d;
2140 uint32_t status;
2141
2172 uint32_t status;
2173
2174 if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
2175 d = &ch->curr[ccb->ccb_h.target_id];
2176 else
2177 d = &ch->user[ccb->ccb_h.target_id];
2142 cts->protocol = PROTO_ATA;
2143 cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
2144 cts->transport = XPORT_SATA;
2145 cts->transport_version = XPORT_VERSION_UNSPECIFIED;
2146 cts->proto_specific.valid = 0;
2147 cts->xport_specific.sata.valid = 0;
2178 cts->protocol = PROTO_ATA;
2179 cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
2180 cts->transport = XPORT_SATA;
2181 cts->transport_version = XPORT_VERSION_UNSPECIFIED;
2182 cts->proto_specific.valid = 0;
2183 cts->xport_specific.sata.valid = 0;
2148 if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
2184 if (cts->type == CTS_TYPE_CURRENT_SETTINGS &&
2185 (ccb->ccb_h.target_id == 15 ||
2186 (ccb->ccb_h.target_id == 0 && !ch->pm_present))) {
2149 status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SS_SPD_MASK;
2187 status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SS_SPD_MASK;
2150 else
2151 status = ATA_INL(ch->r_mem, AHCI_P_SCTL) & ATA_SC_SPD_MASK;
2152 if (status & ATA_SS_SPD_GEN3) {
2153 cts->xport_specific.sata.bitrate = 600000;
2154 cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
2155 } else if (status & ATA_SS_SPD_GEN2) {
2156 cts->xport_specific.sata.bitrate = 300000;
2157 cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
2158 } else if (status & ATA_SS_SPD_GEN1) {
2159 cts->xport_specific.sata.bitrate = 150000;
2160 cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
2161 }
2162 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
2163 cts->xport_specific.sata.pm_present =
2164 (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_PMA) ?
2165 1 : 0;
2188 if (status & 0x0f0) {
2189 cts->xport_specific.sata.revision =
2190 (status & 0x0f0) >> 4;
2191 cts->xport_specific.sata.valid |=
2192 CTS_SATA_VALID_REVISION;
2193 }
2166 } else {
2194 } else {
2167 cts->xport_specific.sata.pm_present = ch->pm_present;
2195 cts->xport_specific.sata.revision = d->revision;
2196 cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
2168 }
2197 }
2198 cts->xport_specific.sata.mode = d->mode;
2199 cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
2200 cts->xport_specific.sata.bytecount = d->bytecount;
2201 cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT;
2202 cts->xport_specific.sata.pm_present = ch->pm_present;
2169 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM;
2203 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM;
2204 cts->xport_specific.sata.tags = d->tags;
2205 cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS;
2170 ccb->ccb_h.status = CAM_REQ_CMP;
2171 xpt_done(ccb);
2172 break;
2173 }
2174#if 0
2175 case XPT_CALC_GEOMETRY:
2176 {
2177 struct ccb_calc_geometry *ccg;

--- 87 unchanged lines hidden ---
2206 ccb->ccb_h.status = CAM_REQ_CMP;
2207 xpt_done(ccb);
2208 break;
2209 }
2210#if 0
2211 case XPT_CALC_GEOMETRY:
2212 {
2213 struct ccb_calc_geometry *ccg;

--- 87 unchanged lines hidden ---