Date: Sun, 14 Jun 2009 06:43:53 GMT From: Alexander Motin <mav@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 164322 for review Message-ID: <200906140643.n5E6hrml059771@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=164322 Change 164322 by mav@mav_mavbook on 2009/06/14 06:43:45 Give SATA SIM information about PM probe result. It allows to avoid some reset command timeouts. Fix some probing issues. Affected files ... .. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#19 edit .. //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#22 edit .. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#26 edit .. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#12 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#19 (text+ko) ==== @@ -650,7 +650,7 @@ if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { int sign = (done_ccb->ataio.res.lba_high << 8) + done_ccb->ataio.res.lba_mid; - printf("SIGNATURE: %04x\n", sign); + xpt_print(path, "SIGNATURE: %04x\n", sign); if (sign == 0x0000 && done_ccb->ccb_h.target_id != 15) { path->device->protocol = PROTO_ATA; @@ -664,8 +664,10 @@ path->device->protocol = PROTO_SCSI; PROBE_SET_ACTION(softc, PROBE_IDENTIFY); } else { - xpt_print(path, - "Unexpected signature 0x%04x\n", sign); + if (done_ccb->ccb_h.target_id != 15) { + xpt_print(path, + "Unexpected signature 0x%04x\n", sign); + } xpt_release_ccb(done_ccb); break; } @@ -945,6 +947,7 @@ if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7) softc->pm_ports = 5; printf("PM ports: %d\n", softc->pm_ports); + softc->pm_step = 0; PROBE_SET_ACTION(softc, PROBE_PM_RESET); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); @@ -972,6 +975,7 @@ } else { softc->pm_step = 0; DELAY(5000); + printf("PM reset done\n"); PROBE_SET_ACTION(softc, PROBE_PM_CONNECT); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); @@ -999,7 +1003,9 @@ return; } else { softc->pm_step = 0; + softc->pm_try = 0; softc->pm_found = 0x8000; + printf("PM connect done\n"); PROBE_SET_ACTION(softc, PROBE_PM_CHECK); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); @@ -1025,15 +1031,17 @@ (done_ccb->ataio.res.lba_low << 8) + done_ccb->ataio.res.sector_count; if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) { - printf("PM found: %d - %08x\n", softc->pm_step, res); + printf("PM status: %d - %08x\n", softc->pm_step, res); softc->pm_found |= (1 << softc->pm_step); softc->pm_step++; } else { if (softc->pm_try < 100) { DELAY(10000); softc->pm_try++; - } else + } else { + printf("PM status: %d - %08x\n", softc->pm_step, res); softc->pm_step++; + } } if (softc->pm_step < softc->pm_ports) { xpt_release_ccb(done_ccb); @@ -1145,6 +1153,7 @@ struct cam_path *path; ata_scan_bus_info *scan_info; union ccb *work_ccb; + struct ccb_trans_settings cts; cam_status status; CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, @@ -1180,7 +1189,14 @@ scan_info->request_ccb = request_ccb; scan_info->cpi = &work_ccb->cpi; scan_info->found = 0x8001; - + /* Report SIM that we have no knowledge about PM presence. */ + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, scan_info->request_ccb->ccb_h.path, 1); + cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + cts.type = CTS_TYPE_CURRENT_SETTINGS; + cts.xport_specific.sata.pm_present = 0; + cts.xport_specific.sata.valid = CTS_SATA_VALID_PM; + xpt_action((union ccb *)&cts); /* If PM supported, probe it first. */ if (scan_info->cpi->hba_inquiry & PI_SATAPM) scan_info->counter = 15; @@ -1203,8 +1219,17 @@ */ xpt_free_path(work_ccb->ccb_h.path); if (scan_info->counter == 15 && - work_ccb->ccb_h.ppriv_field1 != 0) + work_ccb->ccb_h.ppriv_field1 != 0) { scan_info->found = work_ccb->ccb_h.ppriv_field1; + /* Report SIM that PM is present. */ + bzero(&cts, sizeof(cts)); + xpt_setup_ccb(&cts.ccb_h, scan_info->request_ccb->ccb_h.path, 1); + cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; + cts.type = CTS_TYPE_CURRENT_SETTINGS; + cts.xport_specific.sata.pm_present = 1; + cts.xport_specific.sata.valid = CTS_SATA_VALID_PM; + xpt_action((union ccb *)&cts); + } take_next: /* Take next device. Wrap from 15 (PM) to 0. */ scan_info->counter = (scan_info->counter + 1 ) & 0x0f; ==== //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#22 (text+ko) ==== @@ -216,6 +216,7 @@ PROTO_SCSI, /* Small Computer System Interface */ PROTO_ATA, /* AT Attachment */ PROTO_ATAPI, /* AT Attachment Packetized Interface */ + PROTO_SATAPM, /* SATA Port Multiplier */ } cam_proto; typedef enum { @@ -503,6 +504,7 @@ PI_WIDE_16 = 0x20, /* Supports 16 bit wide SCSI */ PI_SDTR_ABLE = 0x10, /* Supports SDTR message */ PI_LINKED_CDB = 0x08, /* Supports linked CDBs */ + PI_SATAPM = 0x04, /* Supports SATA PM */ PI_TAG_ABLE = 0x02, /* Supports tag queue messages */ PI_SOFT_RST = 0x01 /* Supports soft reset alternative */ } pi_inqflag; @@ -778,8 +780,10 @@ struct ccb_trans_settings_sata { u_int valid; /* Which fields to honor */ -#define CTS_SATA_VALID_SPEED 0x1000 +#define CTS_SATA_VALID_SPEED 0x01 +#define CTS_SATA_VALID_PM 0x02 u_int32_t bitrate; /* Mbps */ + u_int pm_present; /* PM is present (XPT->SIM) */ }; /* Get/Set transfer rate/width/disconnection/tag queueing settings */ ==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#26 (text+ko) ==== @@ -1256,8 +1256,8 @@ ATA_OUTL(ch->r_mem, AHCI_P_IS, 0xFFFFFFFF); /* Start operations on this channel */ cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); - ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST | AHCI_P_CMD_PMA); -// (ch->devices & ATA_PORTMULTIPLIER ? AHCI_P_CMD_PMA : 0)); + ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST | + (ch->pm_present ? AHCI_P_CMD_PMA : 0)); } static void @@ -1556,10 +1556,16 @@ xpt_done(ccb); break; case XPT_SET_TRAN_SETTINGS: - /* XXX Implement */ - ccb->ccb_h.status = CAM_PROVIDE_FAIL; + { + struct ccb_trans_settings *cts = &ccb->cts; + + if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { + ch->pm_present = cts->xport_specific.sata.pm_present; + } + ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; + } case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { @@ -1571,19 +1577,29 @@ cts->transport = XPORT_SATA; cts->transport_version = 2; cts->proto_specific.valid = 0; - cts->xport_specific.sata.valid = CTS_SATA_VALID_SPEED; + cts->xport_specific.sata.valid = 0; if (cts->type == CTS_TYPE_CURRENT_SETTINGS) status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SS_SPD_MASK; else - status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SC_SPD_MASK; - if (status & ATA_SS_SPD_GEN3) + status = ATA_INL(ch->r_mem, AHCI_P_SCTL) & ATA_SC_SPD_MASK; + if (status & ATA_SS_SPD_GEN3) { cts->xport_specific.sata.bitrate = 600000; - else if (status & ATA_SS_SPD_GEN2) + cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; + } else if (status & ATA_SS_SPD_GEN2) { cts->xport_specific.sata.bitrate = 300000; - else if (status & ATA_SS_SPD_GEN1) + cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; + } else if (status & ATA_SS_SPD_GEN1) { cts->xport_specific.sata.bitrate = 150000; - else - cts->xport_specific.sata.valid = 0; + cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED; + } + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + cts->xport_specific.sata.pm_present = + (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_PMA) ? + 1 : 0; + } else { + cts->xport_specific.sata.pm_present = ch->pm_present; + } + cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; ==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#12 (text+ko) ==== @@ -342,6 +342,7 @@ struct ahci_slot slot[AHCI_MAX_SLOTS]; struct mtx mtx; /* state lock */ int devices; /* What is present */ + int pm_present; /* PM presence reported */ uint32_t rslots; /* Running slots */ uint32_t aslots; /* Slots with atomic commands */ int numrslots; /* Number of running slots */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906140643.n5E6hrml059771>