From owner-p4-projects@FreeBSD.ORG Sat May 1 10:49:37 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 941F11065678; Sat, 1 May 2010 10:49:37 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 58C861065674 for ; Sat, 1 May 2010 10:49:37 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 465968FC0C for ; Sat, 1 May 2010 10:49:37 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o41Anbjj082604 for ; Sat, 1 May 2010 10:49:37 GMT (envelope-from mav@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o41Anb8n082602 for perforce@freebsd.org; Sat, 1 May 2010 10:49:37 GMT (envelope-from mav@freebsd.org) Date: Sat, 1 May 2010 10:49:37 GMT Message-Id: <201005011049.o41Anb8n082602@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mav@freebsd.org using -f From: Alexander Motin To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 177549 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 01 May 2010 10:49:37 -0000 http://p4web.freebsd.org/@@177549?ac=10 Change 177549 by mav@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 */