Deleted Added
full compact
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 ---