diff options
author | mav <mav@FreeBSD.org> | 2009-11-26 08:49:46 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2009-11-26 08:49:46 +0000 |
commit | 7c0d54bcfc79dce34d24170f6ae5ebb6e25b9e9f (patch) | |
tree | 580d695f05aa2ddcdc2101f3114e9dd4e0dd13d7 /sys/dev/ahci | |
parent | 2d9252d6c71a08629a451a1966338c6e119912d1 (diff) | |
download | FreeBSD-src-7c0d54bcfc79dce34d24170f6ae5ebb6e25b9e9f.zip FreeBSD-src-7c0d54bcfc79dce34d24170f6ae5ebb6e25b9e9f.tar.gz |
MFp4:
Improve ATA mode/SATA revision control.
Diffstat (limited to 'sys/dev/ahci')
-rw-r--r-- | sys/dev/ahci/ahci.c | 38 | ||||
-rw-r--r-- | sys/dev/ahci/ahci.h | 3 |
2 files changed, 22 insertions, 19 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 0cb67f4..3f6c9fc 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -72,7 +72,7 @@ static void ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int er static void ahci_execute_transaction(struct ahci_slot *slot); static void ahci_timeout(struct ahci_slot *slot); static void ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et); -static int ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb, int tag); +static int ahci_setup_fis(device_t dev, struct ahci_cmd_tab *ctp, union ccb *ccb, int tag); static void ahci_dmainit(device_t dev); static void ahci_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static void ahci_dmafini(device_t dev); @@ -776,7 +776,7 @@ 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 rid, error, i; + int rid, error, i, sata_rev = 0; ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); @@ -789,22 +789,22 @@ ahci_ch_attach(device_t dev) device_get_unit(dev), "pm_level", &ch->pm_level); if (ch->pm_level > 3) callout_init_mtx(&ch->pm_timer, &ch->mtx, 0); - for (i = 0; i < 16; i++) { - ch->user[i].revision = 0; - ch->user[i].mode = 0; - ch->user[i].bytecount = 8192; - ch->user[i].tags = ch->numslots; - ch->curr[i] = ch->user[i]; - } /* Limit speed for my onboard JMicron external port. * It is not eSATA really. */ if (pci_get_devid(ctlr->dev) == 0x2363197b && pci_get_subvendor(ctlr->dev) == 0x1043 && pci_get_subdevice(ctlr->dev) == 0x81e4 && ch->unit == 0) - ch->sata_rev = 1; + sata_rev = 1; resource_int_value(device_get_name(dev), - device_get_unit(dev), "sata_rev", &ch->sata_rev); + device_get_unit(dev), "sata_rev", &sata_rev); + for (i = 0; i < 16; i++) { + ch->user[i].revision = sata_rev; + ch->user[i].mode = 0; + ch->user[i].bytecount = 8192; + ch->user[i].tags = ch->numslots; + ch->curr[i] = ch->user[i]; + } rid = ch->unit; if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE))) @@ -1410,7 +1410,7 @@ ahci_execute_transaction(struct ahci_slot *slot) ctp = (struct ahci_cmd_tab *) (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))) { + if (!(fis_size = ahci_setup_fis(dev, ctp, ccb, slot->slot))) { device_printf(ch->dev, "Setting up SATA FIS failed\n"); ahci_end_transaction(slot, AHCI_ERR_INVALID); return; @@ -1983,8 +1983,9 @@ ahci_reset(device_t dev) } static int -ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb, int tag) +ahci_setup_fis(device_t dev, struct ahci_cmd_tab *ctp, union ccb *ccb, int tag) { + struct ahci_channel *ch = device_get_softc(dev); u_int8_t *fis = &ctp->cfis[0]; bzero(ctp->cfis, 64); @@ -1993,7 +1994,8 @@ ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb, int tag) if (ccb->ccb_h.func_code == XPT_SCSI_IO) { fis[1] |= 0x80; fis[2] = ATA_PACKET_CMD; - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) + if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && + ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) fis[3] = ATA_F_DMA; else { fis[5] = ccb->csio.dxfer_len; @@ -2073,6 +2075,7 @@ static int ahci_sata_phy_reset(device_t dev, int quick) { struct ahci_channel *ch = device_get_softc(dev); + int sata_rev; uint32_t val; if (quick) { @@ -2083,11 +2086,12 @@ ahci_sata_phy_reset(device_t dev, int quick) if (bootverbose) device_printf(dev, "hardware reset ...\n"); - if (ch->sata_rev == 1) + sata_rev = ch->user[ch->pm_present ? 15 : 0].revision; + if (sata_rev == 1) val = ATA_SC_SPD_SPEED_GEN1; - else if (ch->sata_rev == 2) + else if (sata_rev == 2) val = ATA_SC_SPD_SPEED_GEN2; - else if (ch->sata_rev == 3) + else if (sata_rev == 3) val = ATA_SC_SPD_SPEED_GEN3; else val = 0; diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index e4ae23c..e11f84f 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -341,7 +341,7 @@ struct ahci_slot { }; struct ahci_device { - u_int revision; + int revision; int mode; u_int bytecount; u_int tags; @@ -362,7 +362,6 @@ struct ahci_channel { int quirks; int numslots; /* Number of present slots */ int pm_level; /* power management level */ - int sata_rev; /* Maximum allowed SATA generation */ struct ahci_slot slot[AHCI_MAX_SLOTS]; union ccb *hold[AHCI_MAX_SLOTS]; |