siis.c (199333) | siis.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/siis/siis.c 199333 2009-11-16 20:54:47Z mav $"); | 28__FBSDID("$FreeBSD: head/sys/dev/siis/siis.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> --- 373 unchanged lines hidden (view full) --- 410 return (0); 411} 412 413static int 414siis_ch_attach(device_t dev) 415{ 416 struct siis_channel *ch = device_get_softc(dev); 417 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> --- 373 unchanged lines hidden (view full) --- 410 return (0); 411} 412 413static int 414siis_ch_attach(device_t dev) 415{ 416 struct siis_channel *ch = device_get_softc(dev); 417 struct cam_devq *devq; |
418 int rid, error; | 418 int rid, error, i; |
419 420 ch->dev = dev; 421 ch->unit = (intptr_t)device_get_ivars(dev); 422 resource_int_value(device_get_name(dev), 423 device_get_unit(dev), "pm_level", &ch->pm_level); | 419 420 ch->dev = dev; 421 ch->unit = (intptr_t)device_get_ivars(dev); 422 resource_int_value(device_get_name(dev), 423 device_get_unit(dev), "pm_level", &ch->pm_level); |
424 for (i = 0; i < 16; i++) { 425 ch->user[i].revision = 0; 426 ch->user[i].mode = 0; 427 ch->user[i].bytecount = 8192; 428 ch->user[i].tags = SIIS_MAX_SLOTS; 429 ch->curr[i] = ch->user[i]; 430 } |
|
424 resource_int_value(device_get_name(dev), 425 device_get_unit(dev), "sata_rev", &ch->sata_rev); 426 mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF); 427 rid = ch->unit; 428 if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 429 &rid, RF_ACTIVE))) 430 return (ENXIO); 431 siis_dmainit(dev); --- 396 unchanged lines hidden (view full) --- 828/* Must be called with channel locked. */ 829static int 830siis_check_collision(device_t dev, union ccb *ccb) 831{ 832 struct siis_channel *ch = device_get_softc(dev); 833 834 mtx_assert(&ch->mtx, MA_OWNED); 835 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && | 431 resource_int_value(device_get_name(dev), 432 device_get_unit(dev), "sata_rev", &ch->sata_rev); 433 mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF); 434 rid = ch->unit; 435 if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 436 &rid, RF_ACTIVE))) 437 return (ENXIO); 438 siis_dmainit(dev); --- 396 unchanged lines hidden (view full) --- 835/* Must be called with channel locked. */ 836static int 837siis_check_collision(device_t dev, union ccb *ccb) 838{ 839 struct siis_channel *ch = device_get_softc(dev); 840 841 mtx_assert(&ch->mtx, MA_OWNED); 842 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && |
843 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { 844 /* Tagged command while we have no supported tag free. */ 845 if (((~ch->oslots) & (0x7fffffff >> (31 - 846 ch->curr[ccb->ccb_h.target_id].tags))) == 0) 847 return (1); 848 } 849 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && |
|
836 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { 837 /* Atomic command while anything active. */ 838 if (ch->numrslots != 0) 839 return (1); 840 } 841 /* We have some atomic command running. */ 842 if (ch->aslots != 0) 843 return (1); 844 return (0); 845} 846 847/* Must be called with channel locked. */ 848static void 849siis_begin_transaction(device_t dev, union ccb *ccb) 850{ 851 struct siis_channel *ch = device_get_softc(dev); 852 struct siis_slot *slot; | 850 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { 851 /* Atomic command while anything active. */ 852 if (ch->numrslots != 0) 853 return (1); 854 } 855 /* We have some atomic command running. */ 856 if (ch->aslots != 0) 857 return (1); 858 return (0); 859} 860 861/* Must be called with channel locked. */ 862static void 863siis_begin_transaction(device_t dev, union ccb *ccb) 864{ 865 struct siis_channel *ch = device_get_softc(dev); 866 struct siis_slot *slot; |
853 int tag; | 867 int tag, tags; |
854 855 mtx_assert(&ch->mtx, MA_OWNED); 856 /* Choose empty slot. */ | 868 869 mtx_assert(&ch->mtx, MA_OWNED); 870 /* Choose empty slot. */ |
857 tag = ch->lastslot; 858 while (ch->slot[tag].state != SIIS_SLOT_EMPTY) { 859 if (++tag >= SIIS_MAX_SLOTS) 860 tag = 0; 861 KASSERT(tag != ch->lastslot, ("siis: ALL SLOTS BUSY!")); 862 } 863 ch->lastslot = tag; | 871 tags = SIIS_MAX_SLOTS; 872 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 873 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) 874 tags = ch->curr[ccb->ccb_h.target_id].tags; 875 tag = fls((~ch->oslots) & (0x7fffffff >> (31 - tags))) - 1; |
864 /* Occupy chosen slot. */ 865 slot = &ch->slot[tag]; 866 slot->ccb = ccb; 867 /* Update channel stats. */ | 876 /* Occupy chosen slot. */ 877 slot = &ch->slot[tag]; 878 slot->ccb = ccb; 879 /* Update channel stats. */ |
880 ch->oslots |= (1 << slot->slot); |
|
868 ch->numrslots++; 869 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 870 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { 871 ch->numtslots[ccb->ccb_h.target_id]++; 872 } 873 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 874 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) 875 ch->aslots |= (1 << slot->slot); --- 237 unchanged lines hidden (view full) --- 1113 case SIIS_ERR_TIMEOUT: 1114 ch->fatalerr = 1; 1115 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1116 break; 1117 default: 1118 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1119 } 1120 /* Free slot. */ | 881 ch->numrslots++; 882 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 883 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { 884 ch->numtslots[ccb->ccb_h.target_id]++; 885 } 886 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 887 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) 888 ch->aslots |= (1 << slot->slot); --- 237 unchanged lines hidden (view full) --- 1126 case SIIS_ERR_TIMEOUT: 1127 ch->fatalerr = 1; 1128 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1129 break; 1130 default: 1131 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1132 } 1133 /* Free slot. */ |
1134 ch->oslots &= ~(1 << slot->slot); |
|
1121 ch->rslots &= ~(1 << slot->slot); 1122 ch->aslots &= ~(1 << slot->slot); 1123 if (et != SIIS_ERR_TIMEOUT) { 1124 if (ch->toslots == (1 << slot->slot)) 1125 xpt_release_simq(ch->sim, TRUE); 1126 ch->toslots &= ~(1 << slot->slot); 1127 } 1128 slot->state = SIIS_SLOT_EMPTY; --- 9 unchanged lines hidden (view full) --- 1138 siis_process_read_log(dev, ccb); 1139 /* If it was NCQ command error, put result on hold. */ 1140 } else if (et == SIIS_ERR_NCQ) { 1141 ch->hold[slot->slot] = ccb; 1142 ch->numhslots++; 1143 } else 1144 xpt_done(ccb); 1145 /* Unfreeze frozen command. */ | 1135 ch->rslots &= ~(1 << slot->slot); 1136 ch->aslots &= ~(1 << slot->slot); 1137 if (et != SIIS_ERR_TIMEOUT) { 1138 if (ch->toslots == (1 << slot->slot)) 1139 xpt_release_simq(ch->sim, TRUE); 1140 ch->toslots &= ~(1 << slot->slot); 1141 } 1142 slot->state = SIIS_SLOT_EMPTY; --- 9 unchanged lines hidden (view full) --- 1152 siis_process_read_log(dev, ccb); 1153 /* If it was NCQ command error, put result on hold. */ 1154 } else if (et == SIIS_ERR_NCQ) { 1155 ch->hold[slot->slot] = ccb; 1156 ch->numhslots++; 1157 } else 1158 xpt_done(ccb); 1159 /* Unfreeze frozen command. */ |
1146 if (ch->frozen && ch->numrslots == 0) { | 1160 if (ch->frozen && !siis_check_collision(dev, ch->frozen)) { |
1147 union ccb *fccb = ch->frozen; 1148 ch->frozen = NULL; 1149 siis_begin_transaction(dev, fccb); 1150 xpt_release_simq(ch->sim, TRUE); 1151 } 1152 /* If we have no other active commands, ... */ 1153 if (ch->rslots == 0) { 1154 /* if there were timeouts or fatal error - reset port. */ --- 394 unchanged lines hidden (view full) --- 1549 case XPT_ABORT: /* Abort the specified CCB */ 1550 /* XXX Implement */ 1551 ccb->ccb_h.status = CAM_REQ_INVALID; 1552 xpt_done(ccb); 1553 break; 1554 case XPT_SET_TRAN_SETTINGS: 1555 { 1556 struct ccb_trans_settings *cts = &ccb->cts; | 1161 union ccb *fccb = ch->frozen; 1162 ch->frozen = NULL; 1163 siis_begin_transaction(dev, fccb); 1164 xpt_release_simq(ch->sim, TRUE); 1165 } 1166 /* If we have no other active commands, ... */ 1167 if (ch->rslots == 0) { 1168 /* if there were timeouts or fatal error - reset port. */ --- 394 unchanged lines hidden (view full) --- 1563 case XPT_ABORT: /* Abort the specified CCB */ 1564 /* XXX Implement */ 1565 ccb->ccb_h.status = CAM_REQ_INVALID; 1566 xpt_done(ccb); 1567 break; 1568 case XPT_SET_TRAN_SETTINGS: 1569 { 1570 struct ccb_trans_settings *cts = &ccb->cts; |
1571 struct siis_device *d; |
|
1557 | 1572 |
1573 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 1574 d = &ch->curr[ccb->ccb_h.target_id]; 1575 else 1576 d = &ch->user[ccb->ccb_h.target_id]; 1577 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) 1578 d->revision = cts->xport_specific.sata.revision; 1579 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) 1580 d->mode = cts->xport_specific.sata.mode; 1581 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) 1582 d->bytecount = min(8192, cts->xport_specific.sata.bytecount); 1583 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) 1584 d->tags = min(SIIS_MAX_SLOTS, cts->xport_specific.sata.tags); |
|
1558 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { 1559 ch->pm_present = cts->xport_specific.sata.pm_present; 1560 if (ch->pm_present) 1561 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); 1562 else 1563 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); 1564 } 1565 ccb->ccb_h.status = CAM_REQ_CMP; 1566 xpt_done(ccb); 1567 break; 1568 } 1569 case XPT_GET_TRAN_SETTINGS: 1570 /* Get default/user set transfer settings for the target */ 1571 { 1572 struct ccb_trans_settings *cts = &ccb->cts; | 1585 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { 1586 ch->pm_present = cts->xport_specific.sata.pm_present; 1587 if (ch->pm_present) 1588 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); 1589 else 1590 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); 1591 } 1592 ccb->ccb_h.status = CAM_REQ_CMP; 1593 xpt_done(ccb); 1594 break; 1595 } 1596 case XPT_GET_TRAN_SETTINGS: 1597 /* Get default/user set transfer settings for the target */ 1598 { 1599 struct ccb_trans_settings *cts = &ccb->cts; |
1600 struct siis_device *d; |
|
1573 uint32_t status; 1574 | 1601 uint32_t status; 1602 |
1603 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 1604 d = &ch->curr[ccb->ccb_h.target_id]; 1605 else 1606 d = &ch->user[ccb->ccb_h.target_id]; |
|
1575 cts->protocol = PROTO_ATA; 1576 cts->protocol_version = PROTO_VERSION_UNSPECIFIED; 1577 cts->transport = XPORT_SATA; 1578 cts->transport_version = XPORT_VERSION_UNSPECIFIED; 1579 cts->proto_specific.valid = 0; 1580 cts->xport_specific.sata.valid = 0; | 1607 cts->protocol = PROTO_ATA; 1608 cts->protocol_version = PROTO_VERSION_UNSPECIFIED; 1609 cts->transport = XPORT_SATA; 1610 cts->transport_version = XPORT_VERSION_UNSPECIFIED; 1611 cts->proto_specific.valid = 0; 1612 cts->xport_specific.sata.valid = 0; |
1581 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) | 1613 if (cts->type == CTS_TYPE_CURRENT_SETTINGS && 1614 (ccb->ccb_h.target_id == 15 || 1615 (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { |
1582 status = ATA_INL(ch->r_mem, SIIS_P_SSTS) & ATA_SS_SPD_MASK; | 1616 status = ATA_INL(ch->r_mem, SIIS_P_SSTS) & ATA_SS_SPD_MASK; |
1583 else 1584 status = ATA_INL(ch->r_mem, SIIS_P_SCTL) & ATA_SC_SPD_MASK; 1585 if (status & ATA_SS_SPD_GEN3) { 1586 cts->xport_specific.sata.bitrate = 600000; 1587 cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; 1588 } else if (status & ATA_SS_SPD_GEN2) { 1589 cts->xport_specific.sata.bitrate = 300000; 1590 cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; 1591 } else if (status & ATA_SS_SPD_GEN1) { 1592 cts->xport_specific.sata.bitrate = 150000; 1593 cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; | 1617 if (status & 0x0f0) { 1618 cts->xport_specific.sata.revision = 1619 (status & 0x0f0) >> 4; 1620 cts->xport_specific.sata.valid |= 1621 CTS_SATA_VALID_REVISION; 1622 } 1623 } else { 1624 cts->xport_specific.sata.revision = d->revision; 1625 cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; |
1594 } | 1626 } |
1627 cts->xport_specific.sata.mode = d->mode; 1628 cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; 1629 cts->xport_specific.sata.bytecount = d->bytecount; 1630 cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; |
|
1595 cts->xport_specific.sata.pm_present = ch->pm_present; 1596 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; | 1631 cts->xport_specific.sata.pm_present = ch->pm_present; 1632 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; |
1633 cts->xport_specific.sata.tags = d->tags; 1634 cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; |
|
1597 ccb->ccb_h.status = CAM_REQ_CMP; 1598 xpt_done(ccb); 1599 break; 1600 } 1601#if 0 1602 case XPT_CALC_GEOMETRY: 1603 { 1604 struct ccb_calc_geometry *ccg; --- 78 unchanged lines hidden --- | 1635 ccb->ccb_h.status = CAM_REQ_CMP; 1636 xpt_done(ccb); 1637 break; 1638 } 1639#if 0 1640 case XPT_CALC_GEOMETRY: 1641 { 1642 struct ccb_calc_geometry *ccg; --- 78 unchanged lines hidden --- |