PERFORCE change 177549 for review
Alexander Motin
mav at FreeBSD.org
Sat May 1 10:49:37 UTC 2010
http://p4web.freebsd.org/@@177549?ac=10
Change 177549 by mav at mav_mavtest on 2010/05/01 10:49:14
Make SATA XPT negotiate some SATA-specific capabilities between
the device and the SIM.
Affected files ...
.. //depot/projects/scottl-camlock/src/sbin/camcontrol/camcontrol.c#40 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#87 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#41 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#109 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#39 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sbin/camcontrol/camcontrol.c#40 (text+ko) ====
@@ -123,7 +123,7 @@
};
#ifndef MINIMALISTIC
-static const char scsicmd_opts[] = "a:c:i:o:r";
+static const char scsicmd_opts[] = "a:c:dfi:o:r";
static const char readdefect_opts[] = "f:GP";
static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
#endif
@@ -2184,6 +2184,8 @@
int c, data_bytes = 0;
int cdb_len = 0;
int atacmd_len = 0;
+ int dmacmd = 0;
+ int fpdmacmd = 0;
int need_res = 0;
char *datastr = NULL, *tstr, *resstr = NULL;
int error = 0;
@@ -2246,6 +2248,12 @@
*/
optind += hook.got;
break;
+ case 'd':
+ dmacmd = 1;
+ break;
+ case 'f':
+ fpdmacmd = 1;
+ break;
case 'i':
if (arglist & CAM_ARG_CMD_OUT) {
warnx("command must either be "
@@ -2422,6 +2430,10 @@
bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
if (need_res)
ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
+ if (dmacmd)
+ ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
+ if (fpdmacmd)
+ ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
cam_fill_ataio(&ccb->ataio,
/*retries*/ retry_count,
@@ -2843,6 +2855,10 @@
fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
sata->tags);
}
+ if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
+ fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
+ sata->caps);
+ }
}
if (cts->protocol == PROTO_SCSI) {
struct ccb_trans_settings_scsi *scsi=
==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#87 (text+ko) ====
@@ -88,6 +88,9 @@
PROBE_IDENTIFY,
PROBE_SPINUP,
PROBE_SETMODE,
+ PROBE_SETPM,
+ PROBE_SETAPST,
+ PROBE_SETDMAAA,
PROBE_SET_MULTI,
PROBE_INQUIRY,
PROBE_FULL_INQUIRY,
@@ -101,6 +104,9 @@
"PROBE_IDENTIFY",
"PROBE_SPINUP",
"PROBE_SETMODE",
+ "PROBE_SETPM",
+ "PROBE_SETAPST",
+ "PROBE_SETDMAAA",
"PROBE_SET_MULTI",
"PROBE_INQUIRY",
"PROBE_FULL_INQUIRY",
@@ -132,6 +138,7 @@
uint32_t pm_prv;
int restart;
int spinup;
+ u_int caps;
struct cam_periph *periph;
} probe_softc;
@@ -393,6 +400,45 @@
ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
break;
}
+ case PROBE_SETPM:
+ cam_fill_ataio(ataio,
+ 1,
+ probedone,
+ CAM_DIR_NONE,
+ 0,
+ NULL,
+ 0,
+ 30*1000);
+ ata_28bit_cmd(ataio, ATA_SETFEATURES,
+ (softc->caps & CTS_SATA_CAPS_H_PMREQ) ? 0x10 : 0x90,
+ 0, 0x03);
+ break;
+ case PROBE_SETAPST:
+ cam_fill_ataio(ataio,
+ 1,
+ probedone,
+ CAM_DIR_NONE,
+ 0,
+ NULL,
+ 0,
+ 30*1000);
+ ata_28bit_cmd(ataio, ATA_SETFEATURES,
+ (softc->caps & CTS_SATA_CAPS_H_APST) ? 0x10 : 0x90,
+ 0, 0x07);
+ break;
+ case PROBE_SETDMAAA:
+ cam_fill_ataio(ataio,
+ 1,
+ probedone,
+ CAM_DIR_NONE,
+ 0,
+ NULL,
+ 0,
+ 30*1000);
+ ata_28bit_cmd(ataio, ATA_SETFEATURES,
+ (softc->caps & CTS_SATA_CAPS_H_DMAAA) ? 0x10 : 0x90,
+ 0, 0x02);
+ break;
case PROBE_SET_MULTI:
{
u_int sectors, bytecount;
@@ -879,6 +925,69 @@
xpt_schedule(periph, priority);
return;
case PROBE_SETMODE:
+ {
+ u_int caps = 0;
+
+ if (path->device->transport != XPORT_SATA)
+ goto notsata;
+ /* Set supported bits. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
+ cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ xpt_action((union ccb *)&cts);
+ if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
+ caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H;
+ if (ident_buf->satacapabilities != 0xffff) {
+ if (ident_buf->satacapabilities & ATA_SUPPORT_IFPWRMNGTRCV)
+ caps |= CTS_SATA_CAPS_D_PMREQ;
+ if (ident_buf->satacapabilities & ATA_SUPPORT_HAPST)
+ caps |= CTS_SATA_CAPS_D_APST;
+ }
+ /* Mask unwanted bits. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
+ cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_USER_SETTINGS;
+ xpt_action((union ccb *)&cts);
+ if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
+ caps &= cts.xport_specific.sata.caps;
+ /* Store result to SIM. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
+ cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ cts.xport_specific.sata.caps = caps;
+ cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS;
+ xpt_action((union ccb *)&cts);
+ softc->caps = caps;
+ if (ident_buf->satasupport & ATA_SUPPORT_IFPWRMNGT) {
+ PROBE_SET_ACTION(softc, PROBE_SETPM);
+ xpt_release_ccb(done_ccb);
+ xpt_schedule(periph, priority);
+ return;
+ }
+ /* FALLTHROUGH */
+ }
+ case PROBE_SETPM:
+ if (ident_buf->satacapabilities != 0xffff &&
+ ident_buf->satacapabilities & ATA_SUPPORT_DAPST) {
+ PROBE_SET_ACTION(softc, PROBE_SETAPST);
+ xpt_release_ccb(done_ccb);
+ xpt_schedule(periph, priority);
+ return;
+ }
+ /* FALLTHROUGH */
+ case PROBE_SETAPST:
+ if (ident_buf->satasupport & ATA_SUPPORT_AUTOACTIVATE) {
+ PROBE_SET_ACTION(softc, PROBE_SETDMAAA);
+ xpt_release_ccb(done_ccb);
+ xpt_schedule(periph, priority);
+ return;
+ }
+ /* FALLTHROUGH */
+ case PROBE_SETDMAAA:
+notsata:
if (path->device->protocol == PROTO_ATA) {
PROBE_SET_ACTION(softc, PROBE_SET_MULTI);
} else {
==== //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#41 (text+ko) ====
@@ -837,12 +837,21 @@
#define CTS_SATA_VALID_PM 0x08
#define CTS_SATA_VALID_TAGS 0x10
#define CTS_SATA_VALID_ATAPI 0x20
+#define CTS_SATA_VALID_CAPS 0x40
int mode; /* Legacy PATA mode */
u_int bytecount; /* Length of PIO transaction */
int revision; /* SATA revision */
u_int pm_present; /* PM is present (XPT->SIM) */
u_int tags; /* Number of allowed tags */
u_int atapi; /* Length of ATAPI CDB */
+ u_int caps; /* Device and host SATA caps. */
+#define CTS_SATA_CAPS_H 0x0000ffff
+#define CTS_SATA_CAPS_H_PMREQ 0x00000001
+#define CTS_SATA_CAPS_H_APST 0x00000002
+#define CTS_SATA_CAPS_H_DMAAA 0x00000010 /* Auto-activation */
+#define CTS_SATA_CAPS_D 0xffff0000
+#define CTS_SATA_CAPS_D_PMREQ 0x00010000
+#define CTS_SATA_CAPS_D_APST 0x00020000
};
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#109 (text+ko) ====
@@ -860,7 +860,14 @@
ch->user[i].mode = 0;
ch->user[i].bytecount = 8192;
ch->user[i].tags = ch->numslots;
+ ch->user[i].caps = 0;
ch->curr[i] = ch->user[i];
+ if (ch->pm_level) {
+ ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ |
+ CTS_SATA_CAPS_H_APST |
+ CTS_SATA_CAPS_D_PMREQ | CTS_SATA_CAPS_D_APST;
+ }
+ ch->user[i].caps |= CTS_SATA_CAPS_H_DMAAA;
}
rid = ch->unit;
if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@@ -2464,6 +2471,8 @@
ch->pm_present = cts->xport_specific.sata.pm_present;
if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI)
d->atapi = cts->xport_specific.sata.atapi;
+ if (cts->xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
+ d->caps = cts->xport_specific.sata.caps;
ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
@@ -2496,9 +2505,23 @@
cts->xport_specific.sata.valid |=
CTS_SATA_VALID_REVISION;
}
+ cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D;
+ if (ch->pm_level) {
+ if (ch->caps & (AHCI_CAP_PSC | AHCI_CAP_SSC))
+ cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ;
+ if (ch->caps2 & AHCI_CAP2_APST)
+ cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_APST;
+ if (ch->caps & AHCI_CAP_SNCQ)
+ cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_DMAAA;
+ cts->xport_specific.sata.caps &=
+ ch->user[ccb->ccb_h.target_id].caps;
+ }
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
} else {
cts->xport_specific.sata.revision = d->revision;
cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
+ cts->xport_specific.sata.caps = d->caps;
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
}
cts->xport_specific.sata.mode = d->mode;
cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#39 (text+ko) ====
@@ -372,6 +372,7 @@
u_int bytecount;
u_int atapi;
u_int tags;
+ u_int caps;
};
/* structure describing an ATA channel */
More information about the p4-projects
mailing list