MFp4:
Improve ATA mode/SATA revision control.
This commit is contained in:
parent
a6d42a0d62
commit
b447e682d6
@ -149,6 +149,7 @@
|
||||
.Op generic args
|
||||
.Op Fl c
|
||||
.Op Fl D Ar enable|disable
|
||||
.Op Fl M Ar mode
|
||||
.Op Fl O Ar offset
|
||||
.Op Fl q
|
||||
.Op Fl R Ar syncrate
|
||||
@ -705,6 +706,8 @@ Show or set current negotiation settings.
|
||||
This is the default.
|
||||
.It Fl D Ar enable|disable
|
||||
Enable or disable disconnection.
|
||||
.It Fl M Ar mode
|
||||
Set ATA mode.
|
||||
.It Fl O Ar offset
|
||||
Set the command delay offset.
|
||||
.It Fl q
|
||||
|
@ -125,7 +125,7 @@ struct camcontrol_opts {
|
||||
#ifndef MINIMALISTIC
|
||||
static const char scsicmd_opts[] = "a:c:i:o:r";
|
||||
static const char readdefect_opts[] = "f:GP";
|
||||
static const char negotiate_opts[] = "acD:O:qR:T:UW:";
|
||||
static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
|
||||
#endif
|
||||
|
||||
struct camcontrol_opts option_table[] = {
|
||||
@ -3112,6 +3112,7 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
int user_settings = 0;
|
||||
int retval = 0;
|
||||
int disc_enable = -1, tag_enable = -1;
|
||||
int mode = -1;
|
||||
int offset = -1;
|
||||
double syncrate = -1;
|
||||
int bus_width = -1;
|
||||
@ -3120,12 +3121,10 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
struct ccb_pathinq cpi;
|
||||
|
||||
ccb = cam_getccb(device);
|
||||
|
||||
if (ccb == NULL) {
|
||||
warnx("ratecontrol: error allocating ccb");
|
||||
return(1);
|
||||
}
|
||||
|
||||
while ((c = getopt(argc, argv, combinedopt)) != -1) {
|
||||
switch(c){
|
||||
case 'a':
|
||||
@ -3146,6 +3145,15 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
}
|
||||
change_settings = 1;
|
||||
break;
|
||||
case 'M':
|
||||
mode = ata_string2mode(optarg);
|
||||
if (mode < 0) {
|
||||
warnx("unknown mode '%s'", optarg);
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
change_settings = 1;
|
||||
break;
|
||||
case 'O':
|
||||
offset = strtol(optarg, NULL, 0);
|
||||
if (offset < 0) {
|
||||
@ -3160,7 +3168,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
break;
|
||||
case 'R':
|
||||
syncrate = atof(optarg);
|
||||
|
||||
if (syncrate < 0) {
|
||||
warnx("sync rate %f is < 0", syncrate);
|
||||
retval = 1;
|
||||
@ -3196,17 +3203,14 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bzero(&(&ccb->ccb_h)[1],
|
||||
sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
|
||||
|
||||
/*
|
||||
* Grab path inquiry information, so we can determine whether
|
||||
* or not the initiator is capable of the things that the user
|
||||
* requests.
|
||||
*/
|
||||
ccb->ccb_h.func_code = XPT_PATH_INQ;
|
||||
|
||||
if (cam_send_ccb(device, ccb) < 0) {
|
||||
perror("error sending XPT_PATH_INQ CCB");
|
||||
if (arglist & CAM_ARG_VERBOSE) {
|
||||
@ -3216,7 +3220,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||
warnx("XPT_PATH_INQ CCB failed");
|
||||
if (arglist & CAM_ARG_VERBOSE) {
|
||||
@ -3226,17 +3229,14 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
|
||||
|
||||
bzero(&(&ccb->ccb_h)[1],
|
||||
sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
|
||||
|
||||
if (quiet == 0)
|
||||
fprintf(stdout, "Current Parameters:\n");
|
||||
|
||||
if (quiet == 0) {
|
||||
fprintf(stdout, "%s parameters:\n",
|
||||
user_settings ? "User" : "Current");
|
||||
}
|
||||
retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
|
||||
|
||||
if (retval != 0)
|
||||
goto ratecontrol_bailout;
|
||||
|
||||
@ -3246,16 +3246,20 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
if (change_settings) {
|
||||
int didsettings = 0;
|
||||
struct ccb_trans_settings_spi *spi = NULL;
|
||||
struct ccb_trans_settings_ata *ata = NULL;
|
||||
struct ccb_trans_settings_sata *sata = NULL;
|
||||
struct ccb_trans_settings_scsi *scsi = NULL;
|
||||
|
||||
if (ccb->cts.transport == XPORT_SPI) {
|
||||
if (ccb->cts.transport == XPORT_SPI)
|
||||
spi = &ccb->cts.xport_specific.spi;
|
||||
spi->valid = 0;
|
||||
}
|
||||
if (ccb->cts.protocol == PROTO_SCSI) {
|
||||
if (ccb->cts.transport == XPORT_ATA)
|
||||
ata = &ccb->cts.xport_specific.ata;
|
||||
if (ccb->cts.transport == XPORT_SATA)
|
||||
sata = &ccb->cts.xport_specific.sata;
|
||||
if (ccb->cts.protocol == PROTO_SCSI)
|
||||
scsi = &ccb->cts.proto_specific.scsi;
|
||||
scsi->valid = 0;
|
||||
}
|
||||
ccb->cts.xport_specific.valid = 0;
|
||||
ccb->cts.proto_specific.valid = 0;
|
||||
if (spi && disc_enable != -1) {
|
||||
spi->valid |= CTS_SPI_VALID_DISC;
|
||||
if (disc_enable == 0)
|
||||
@ -3263,7 +3267,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
else
|
||||
spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
|
||||
}
|
||||
|
||||
if (scsi && tag_enable != -1) {
|
||||
if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
|
||||
warnx("HBA does not support tagged queueing, "
|
||||
@ -3271,21 +3274,16 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
scsi->valid |= CTS_SCSI_VALID_TQ;
|
||||
|
||||
if (tag_enable == 0)
|
||||
scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
|
||||
else
|
||||
scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
|
||||
didsettings++;
|
||||
}
|
||||
|
||||
if (spi && offset != -1) {
|
||||
if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
|
||||
warnx("HBA at %s%d is not cable of changing "
|
||||
"offset", cpi.dev_name,
|
||||
cpi.unit_number);
|
||||
warnx("HBA is not capable of changing offset");
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
@ -3293,28 +3291,23 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
spi->sync_offset = offset;
|
||||
didsettings++;
|
||||
}
|
||||
|
||||
if (spi && syncrate != -1) {
|
||||
int prelim_sync_period;
|
||||
u_int freq;
|
||||
|
||||
if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
|
||||
warnx("HBA at %s%d is not cable of changing "
|
||||
"transfer rates", cpi.dev_name,
|
||||
cpi.unit_number);
|
||||
warnx("HBA is not capable of changing "
|
||||
"transfer rates");
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
spi->valid |= CTS_SPI_VALID_SYNC_RATE;
|
||||
|
||||
/*
|
||||
* The sync rate the user gives us is in MHz.
|
||||
* We need to translate it into KHz for this
|
||||
* calculation.
|
||||
*/
|
||||
syncrate *= 1000;
|
||||
|
||||
/*
|
||||
* Next, we calculate a "preliminary" sync period
|
||||
* in tenths of a nanosecond.
|
||||
@ -3323,14 +3316,43 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
prelim_sync_period = 0;
|
||||
else
|
||||
prelim_sync_period = 10000000 / syncrate;
|
||||
|
||||
spi->sync_period =
|
||||
scsi_calc_syncparam(prelim_sync_period);
|
||||
|
||||
freq = scsi_calc_syncsrate(spi->sync_period);
|
||||
didsettings++;
|
||||
}
|
||||
|
||||
if (sata && syncrate != -1) {
|
||||
if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
|
||||
warnx("HBA is not capable of changing "
|
||||
"transfer rates");
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
sata->revision = ata_speed2revision(syncrate * 100);
|
||||
if (sata->revision < 0) {
|
||||
warnx("Invalid rate %f", syncrate);
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
sata->valid |= CTS_SATA_VALID_REVISION;
|
||||
didsettings++;
|
||||
}
|
||||
if ((ata || sata) && mode != -1) {
|
||||
if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
|
||||
warnx("HBA is not capable of changing "
|
||||
"transfer rates");
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
if (ata) {
|
||||
ata->mode = mode;
|
||||
ata->valid |= CTS_ATA_VALID_MODE;
|
||||
} else {
|
||||
sata->mode = mode;
|
||||
sata->valid |= CTS_SATA_VALID_MODE;
|
||||
}
|
||||
didsettings++;
|
||||
}
|
||||
/*
|
||||
* The bus_width argument goes like this:
|
||||
* 0 == 8 bit
|
||||
@ -3341,7 +3363,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
* number.
|
||||
*/
|
||||
if (spi && bus_width != -1) {
|
||||
|
||||
/*
|
||||
* We might as well validate things here with a
|
||||
* decipherable error message, rather than what
|
||||
@ -3365,17 +3386,19 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
|
||||
spi->bus_width = bus_width >> 4;
|
||||
didsettings++;
|
||||
}
|
||||
|
||||
if (didsettings == 0) {
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
if (!user_settings && (ata || sata)) {
|
||||
warnx("You can modify only user settings for ATA/SATA");
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
|
||||
|
||||
if (cam_send_ccb(device, ccb) < 0) {
|
||||
perror("error sending XPT_SET_TRAN_SETTINGS CCB");
|
||||
if (arglist & CAM_ARG_VERBOSE) {
|
||||
@ -3385,7 +3408,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
retval = 1;
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||
warnx("XPT_SET_TRANS_SETTINGS CCB failed");
|
||||
if (arglist & CAM_ARG_VERBOSE) {
|
||||
@ -3396,11 +3418,9 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
}
|
||||
|
||||
if (send_tur) {
|
||||
retval = testunitready(device, retry_count, timeout,
|
||||
(arglist & CAM_ARG_VERBOSE) ? 0 : 1);
|
||||
|
||||
/*
|
||||
* If the TUR didn't succeed, just bail.
|
||||
*/
|
||||
@ -3409,7 +3429,6 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
fprintf(stderr, "Test Unit Ready failed\n");
|
||||
goto ratecontrol_bailout;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user wants things quiet, there's no sense in
|
||||
* getting the transfer settings, if we're not going
|
||||
@ -3417,13 +3436,11 @@ ratecontrol(struct cam_device *device, int retry_count, int timeout,
|
||||
*/
|
||||
if (quiet != 0)
|
||||
goto ratecontrol_bailout;
|
||||
|
||||
fprintf(stdout, "New Parameters:\n");
|
||||
fprintf(stdout, "New parameters:\n");
|
||||
retval = get_print_cts(device, user_settings, 0, NULL);
|
||||
}
|
||||
|
||||
ratecontrol_bailout:
|
||||
|
||||
cam_freeccb(ccb);
|
||||
return(retval);
|
||||
}
|
||||
@ -4310,8 +4327,8 @@ usage(int verbose)
|
||||
" <all|bus[:target[:lun]]|off>\n"
|
||||
" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
|
||||
" camcontrol negotiate [dev_id][generic args] [-a][-c]\n"
|
||||
" [-D <enable|disable>][-O offset][-q]\n"
|
||||
" [-R syncrate][-v][-T <enable|disable>]\n"
|
||||
" [-D <enable|disable>][-M mode][-O offset]\n"
|
||||
" [-q][-R syncrate][-v][-T <enable|disable>]\n"
|
||||
" [-U][-W bus_width]\n"
|
||||
" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
|
||||
" camcontrol idle [dev_id][generic args][-t time]\n"
|
||||
@ -4402,6 +4419,7 @@ usage(int verbose)
|
||||
"-a send a test unit ready after negotiation\n"
|
||||
"-c report/set current negotiation settings\n"
|
||||
"-D <arg> \"enable\" or \"disable\" disconnection\n"
|
||||
"-M mode set ATA mode\n"
|
||||
"-O offset set command delay offset\n"
|
||||
"-q be quiet, don't report anything\n"
|
||||
"-R syncrate synchronization rate in MHz\n"
|
||||
|
@ -532,6 +532,35 @@ ata_mode2string(int mode)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ata_string2mode(char *str)
|
||||
{
|
||||
if (!strcasecmp(str, "PIO0")) return (ATA_PIO0);
|
||||
if (!strcasecmp(str, "PIO1")) return (ATA_PIO1);
|
||||
if (!strcasecmp(str, "PIO2")) return (ATA_PIO2);
|
||||
if (!strcasecmp(str, "PIO3")) return (ATA_PIO3);
|
||||
if (!strcasecmp(str, "PIO4")) return (ATA_PIO4);
|
||||
if (!strcasecmp(str, "WDMA0")) return (ATA_WDMA0);
|
||||
if (!strcasecmp(str, "WDMA1")) return (ATA_WDMA1);
|
||||
if (!strcasecmp(str, "WDMA2")) return (ATA_WDMA2);
|
||||
if (!strcasecmp(str, "UDMA0")) return (ATA_UDMA0);
|
||||
if (!strcasecmp(str, "UDMA16")) return (ATA_UDMA0);
|
||||
if (!strcasecmp(str, "UDMA1")) return (ATA_UDMA1);
|
||||
if (!strcasecmp(str, "UDMA25")) return (ATA_UDMA1);
|
||||
if (!strcasecmp(str, "UDMA2")) return (ATA_UDMA2);
|
||||
if (!strcasecmp(str, "UDMA33")) return (ATA_UDMA2);
|
||||
if (!strcasecmp(str, "UDMA3")) return (ATA_UDMA3);
|
||||
if (!strcasecmp(str, "UDMA44")) return (ATA_UDMA3);
|
||||
if (!strcasecmp(str, "UDMA4")) return (ATA_UDMA4);
|
||||
if (!strcasecmp(str, "UDMA66")) return (ATA_UDMA4);
|
||||
if (!strcasecmp(str, "UDMA5")) return (ATA_UDMA5);
|
||||
if (!strcasecmp(str, "UDMA100")) return (ATA_UDMA5);
|
||||
if (!strcasecmp(str, "UDMA6")) return (ATA_UDMA6);
|
||||
if (!strcasecmp(str, "UDMA133")) return (ATA_UDMA6);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
u_int
|
||||
ata_mode2speed(int mode)
|
||||
{
|
||||
@ -588,13 +617,16 @@ int
|
||||
ata_speed2revision(u_int speed)
|
||||
{
|
||||
switch (speed) {
|
||||
case 0:
|
||||
return (0);
|
||||
case 150000:
|
||||
default:
|
||||
return (1);
|
||||
case 300000:
|
||||
return (2);
|
||||
case 600000:
|
||||
return (3);
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,7 @@ int ata_max_umode(struct ata_params *ap);
|
||||
int ata_max_mode(struct ata_params *ap, int maxmode);
|
||||
|
||||
char * ata_mode2string(int mode);
|
||||
int ata_string2mode(char *str);
|
||||
u_int ata_mode2speed(int mode);
|
||||
u_int ata_revision2speed(int revision);
|
||||
int ata_speed2revision(u_int speed);
|
||||
|
@ -820,7 +820,7 @@ struct ccb_trans_settings_ata {
|
||||
u_int valid; /* Which fields to honor */
|
||||
#define CTS_ATA_VALID_MODE 0x01
|
||||
#define CTS_ATA_VALID_BYTECOUNT 0x02
|
||||
int mode; /* Mode */
|
||||
int mode; /* Mode */
|
||||
u_int bytecount; /* Length of PIO transaction */
|
||||
};
|
||||
|
||||
@ -831,9 +831,9 @@ struct ccb_trans_settings_sata {
|
||||
#define CTS_SATA_VALID_REVISION 0x04
|
||||
#define CTS_SATA_VALID_PM 0x08
|
||||
#define CTS_SATA_VALID_TAGS 0x10
|
||||
int mode; /* Legacy PATA mode */
|
||||
int mode; /* Legacy PATA mode */
|
||||
u_int bytecount; /* Length of PIO transaction */
|
||||
u_int revision; /* SATA revision */
|
||||
int revision; /* SATA revision */
|
||||
u_int pm_present; /* PM is present (XPT->SIM) */
|
||||
u_int tags; /* Number of allowed tags */
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -69,7 +69,7 @@ static void siis_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int er
|
||||
static void siis_execute_transaction(struct siis_slot *slot);
|
||||
static void siis_timeout(struct siis_slot *slot);
|
||||
static void siis_end_transaction(struct siis_slot *slot, enum siis_err_type et);
|
||||
static int siis_setup_fis(struct siis_cmd *ctp, union ccb *ccb, int tag);
|
||||
static int siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag);
|
||||
static void siis_dmainit(device_t dev);
|
||||
static void siis_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
|
||||
static void siis_dmafini(device_t dev);
|
||||
@ -415,21 +415,21 @@ siis_ch_attach(device_t dev)
|
||||
{
|
||||
struct siis_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);
|
||||
resource_int_value(device_get_name(dev),
|
||||
device_get_unit(dev), "pm_level", &ch->pm_level);
|
||||
resource_int_value(device_get_name(dev),
|
||||
device_get_unit(dev), "sata_rev", &sata_rev);
|
||||
for (i = 0; i < 16; i++) {
|
||||
ch->user[i].revision = 0;
|
||||
ch->user[i].revision = sata_rev;
|
||||
ch->user[i].mode = 0;
|
||||
ch->user[i].bytecount = 8192;
|
||||
ch->user[i].tags = SIIS_MAX_SLOTS;
|
||||
ch->curr[i] = ch->user[i];
|
||||
}
|
||||
resource_int_value(device_get_name(dev),
|
||||
device_get_unit(dev), "sata_rev", &ch->sata_rev);
|
||||
mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF);
|
||||
rid = ch->unit;
|
||||
if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
@ -974,7 +974,7 @@ siis_execute_transaction(struct siis_slot *slot)
|
||||
ctp->control |= htole16(SIIS_PRB_PACKET_WRITE);
|
||||
}
|
||||
/* Setup the FIS for this request */
|
||||
if (!siis_setup_fis(ctp, ccb, slot->slot)) {
|
||||
if (!siis_setup_fis(dev, ctp, ccb, slot->slot)) {
|
||||
device_printf(ch->dev, "Setting up SATA FIS failed\n");
|
||||
if (!ch->readlog)
|
||||
xpt_freeze_simq(ch->sim, 1);
|
||||
@ -1346,7 +1346,7 @@ static void
|
||||
siis_reset(device_t dev)
|
||||
{
|
||||
struct siis_channel *ch = device_get_softc(dev);
|
||||
int i, retry = 0;
|
||||
int i, retry = 0, sata_rev;
|
||||
uint32_t val;
|
||||
|
||||
if (bootverbose)
|
||||
@ -1390,11 +1390,12 @@ siis_reset(device_t dev)
|
||||
/* Disable port interrupts */
|
||||
ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF);
|
||||
/* Set speed limit. */
|
||||
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;
|
||||
@ -1446,8 +1447,9 @@ siis_reset(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
siis_setup_fis(struct siis_cmd *ctp, union ccb *ccb, int tag)
|
||||
siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag)
|
||||
{
|
||||
struct siis_channel *ch = device_get_softc(dev);
|
||||
u_int8_t *fis = &ctp->fis[0];
|
||||
|
||||
bzero(fis, 24);
|
||||
@ -1456,7 +1458,8 @@ siis_setup_fis(struct siis_cmd *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;
|
||||
|
@ -347,7 +347,7 @@ struct siis_slot {
|
||||
};
|
||||
|
||||
struct siis_device {
|
||||
u_int revision;
|
||||
int revision;
|
||||
int mode;
|
||||
u_int bytecount;
|
||||
u_int tags;
|
||||
@ -364,7 +364,6 @@ struct siis_channel {
|
||||
struct cam_sim *sim;
|
||||
struct cam_path *path;
|
||||
int pm_level; /* power management level */
|
||||
int sata_rev; /* Maximum allowed SATA generation */
|
||||
|
||||
struct siis_slot slot[SIIS_MAX_SLOTS];
|
||||
union ccb *hold[SIIS_MAX_SLOTS];
|
||||
|
Loading…
Reference in New Issue
Block a user