ata_xpt.c revision 243571
1272955Srodrigc/*- 2234949Sbapt * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org> 3234949Sbapt * All rights reserved. 4268899Sbapt * 5234949Sbapt * Redistribution and use in source and binary forms, with or without 6234949Sbapt * modification, are permitted provided that the following conditions 7234949Sbapt * are met: 8234949Sbapt * 1. Redistributions of source code must retain the above copyright 9234949Sbapt * notice, this list of conditions and the following disclaimer, 10234949Sbapt * without modification, immediately at the beginning of the file. 11234949Sbapt * 2. Redistributions in binary form must reproduce the above copyright 12234949Sbapt * notice, this list of conditions and the following disclaimer in the 13234949Sbapt * documentation and/or other materials provided with the distribution. 14234949Sbapt * 15234949Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16234949Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17234949Sbapt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18234949Sbapt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19234949Sbapt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20234949Sbapt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21234949Sbapt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22234949Sbapt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23234949Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24234949Sbapt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25234949Sbapt */ 26234949Sbapt 27234949Sbapt#include <sys/cdefs.h> 28234949Sbapt__FBSDID("$FreeBSD: head/sys/cam/ata/ata_xpt.c 243571 2012-11-26 20:07:10Z mav $"); 29234949Sbapt 30234949Sbapt#include <sys/param.h> 31272953Srodrigc#include <sys/bus.h> 32251143Sbapt#include <sys/endian.h> 33251143Sbapt#include <sys/systm.h> 34251143Sbapt#include <sys/types.h> 35251143Sbapt#include <sys/malloc.h> 36251143Sbapt#include <sys/kernel.h> 37251143Sbapt#include <sys/time.h> 38251143Sbapt#include <sys/conf.h> 39251143Sbapt#include <sys/fcntl.h> 40272953Srodrigc#include <sys/interrupt.h> 41251143Sbapt#include <sys/sbuf.h> 42251143Sbapt 43251143Sbapt#include <sys/lock.h> 44251143Sbapt#include <sys/mutex.h> 45251143Sbapt#include <sys/sysctl.h> 46251143Sbapt 47251143Sbapt#include <cam/cam.h> 48251143Sbapt#include <cam/cam_ccb.h> 49251143Sbapt#include <cam/cam_queue.h> 50251143Sbapt#include <cam/cam_periph.h> 51251143Sbapt#include <cam/cam_sim.h> 52251143Sbapt#include <cam/cam_xpt.h> 53251143Sbapt#include <cam/cam_xpt_sim.h> 54251143Sbapt#include <cam/cam_xpt_periph.h> 55251143Sbapt#include <cam/cam_xpt_internal.h> 56251143Sbapt#include <cam/cam_debug.h> 57272955Srodrigc 58234949Sbapt#include <cam/scsi/scsi_all.h> 59234949Sbapt#include <cam/scsi/scsi_message.h> 60234949Sbapt#include <cam/ata/ata_all.h> 61234949Sbapt#include <machine/stdarg.h> /* for xpt_print below */ 62234949Sbapt#include "opt_cam.h" 63234949Sbapt 64234949Sbaptstruct ata_quirk_entry { 65234949Sbapt struct scsi_inquiry_pattern inq_pat; 66234949Sbapt u_int8_t quirks; 67234949Sbapt#define CAM_QUIRK_MAXTAGS 0x01 68234949Sbapt u_int mintags; 69234949Sbapt u_int maxtags; 70234949Sbapt}; 71234949Sbapt 72234949Sbaptstatic periph_init_t probe_periph_init; 73234949Sbapt 74234949Sbaptstatic struct periph_driver probe_driver = 75234949Sbapt{ 76234949Sbapt probe_periph_init, "aprobe", 77234949Sbapt TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0, 78234949Sbapt CAM_PERIPH_DRV_EARLY 79234949Sbapt}; 80234949Sbapt 81234949SbaptPERIPHDRIVER_DECLARE(aprobe, probe_driver); 82272955Srodrigc 83234949Sbapttypedef enum { 84234949Sbapt PROBE_RESET, 85234949Sbapt PROBE_IDENTIFY, 86234949Sbapt PROBE_SPINUP, 87234949Sbapt PROBE_SETMODE, 88234949Sbapt PROBE_SETPM, 89234949Sbapt PROBE_SETAPST, 90234949Sbapt PROBE_SETDMAAA, 91234949Sbapt PROBE_SETAN, 92234949Sbapt PROBE_SET_MULTI, 93234949Sbapt PROBE_INQUIRY, 94234949Sbapt PROBE_FULL_INQUIRY, 95234949Sbapt PROBE_PM_PID, 96234949Sbapt PROBE_PM_PRV, 97234949Sbapt PROBE_IDENTIFY_SES, 98234949Sbapt PROBE_IDENTIFY_SAFTE, 99234949Sbapt PROBE_DONE, 100234949Sbapt PROBE_INVALID 101234949Sbapt} probe_action; 102234949Sbapt 103234949Sbaptstatic char *probe_action_text[] = { 104234949Sbapt "PROBE_RESET", 105234949Sbapt "PROBE_IDENTIFY", 106234949Sbapt "PROBE_SPINUP", 107234949Sbapt "PROBE_SETMODE", 108234949Sbapt "PROBE_SETPM", 109234949Sbapt "PROBE_SETAPST", 110234949Sbapt "PROBE_SETDMAAA", 111234949Sbapt "PROBE_SETAN", 112234949Sbapt "PROBE_SET_MULTI", 113234949Sbapt "PROBE_INQUIRY", 114234949Sbapt "PROBE_FULL_INQUIRY", 115234949Sbapt "PROBE_PM_PID", 116234949Sbapt "PROBE_PM_PRV", 117234949Sbapt "PROBE_IDENTIFY_SES", 118234949Sbapt "PROBE_IDENTIFY_SAFTE", 119272955Srodrigc "PROBE_DONE", 120234949Sbapt "PROBE_INVALID" 121234949Sbapt}; 122234949Sbapt 123234949Sbapt#define PROBE_SET_ACTION(softc, newaction) \ 124234949Sbaptdo { \ 125234949Sbapt char **text; \ 126234949Sbapt text = probe_action_text; \ 127234949Sbapt CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE, \ 128234949Sbapt ("Probe %s to %s\n", text[(softc)->action], \ 129234949Sbapt text[(newaction)])); \ 130234949Sbapt (softc)->action = (newaction); \ 131234949Sbapt} while(0) 132234949Sbapt 133234949Sbapttypedef enum { 134234949Sbapt PROBE_NO_ANNOUNCE = 0x04 135234949Sbapt} probe_flags; 136234949Sbapt 137234949Sbapttypedef struct { 138234949Sbapt TAILQ_HEAD(, ccb_hdr) request_ccbs; 139234949Sbapt struct ata_params ident_data; 140234949Sbapt probe_action action; 141234949Sbapt probe_flags flags; 142234949Sbapt uint32_t pm_pid; 143234949Sbapt uint32_t pm_prv; 144234949Sbapt int restart; 145234949Sbapt int spinup; 146234949Sbapt int faults; 147234949Sbapt u_int caps; 148234949Sbapt struct cam_periph *periph; 149234949Sbapt} probe_softc; 150234949Sbapt 151234949Sbaptstatic struct ata_quirk_entry ata_quirk_table[] = 152234949Sbapt{ 153234949Sbapt { 154234949Sbapt /* Default tagged queuing parameters for all devices */ 155234949Sbapt { 156234949Sbapt T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, 157234949Sbapt /*vendor*/"*", /*product*/"*", /*revision*/"*" 158234949Sbapt }, 159234949Sbapt /*quirks*/0, /*mintags*/0, /*maxtags*/0 160234949Sbapt }, 161234949Sbapt}; 162234949Sbapt 163234949Sbaptstatic const int ata_quirk_table_size = 164234949Sbapt sizeof(ata_quirk_table) / sizeof(*ata_quirk_table); 165234949Sbapt 166234949Sbaptstatic cam_status proberegister(struct cam_periph *periph, 167234949Sbapt void *arg); 168234949Sbaptstatic void probeschedule(struct cam_periph *probe_periph); 169234949Sbaptstatic void probestart(struct cam_periph *periph, union ccb *start_ccb); 170234949Sbaptstatic void proberequestdefaultnegotiation(struct cam_periph *periph); 171234949Sbaptstatic void probedone(struct cam_periph *periph, union ccb *done_ccb); 172234949Sbaptstatic void probecleanup(struct cam_periph *periph); 173234949Sbaptstatic void ata_find_quirk(struct cam_ed *device); 174251143Sbaptstatic void ata_scan_bus(struct cam_periph *periph, union ccb *ccb); 175251143Sbaptstatic void ata_scan_lun(struct cam_periph *periph, 176251143Sbapt struct cam_path *path, cam_flags flags, 177251143Sbapt union ccb *ccb); 178251143Sbaptstatic void xptscandone(struct cam_periph *periph, union ccb *done_ccb); 179251143Sbaptstatic struct cam_ed * 180251143Sbapt ata_alloc_device(struct cam_eb *bus, struct cam_et *target, 181251143Sbapt lun_id_t lun_id); 182251143Sbaptstatic void ata_device_transport(struct cam_path *path); 183251143Sbaptstatic void ata_get_transfer_settings(struct ccb_trans_settings *cts); 184251143Sbaptstatic void ata_set_transfer_settings(struct ccb_trans_settings *cts, 185251143Sbapt struct cam_ed *device, 186251143Sbapt int async_update); 187251143Sbaptstatic void ata_dev_async(u_int32_t async_code, 188251143Sbapt struct cam_eb *bus, 189251143Sbapt struct cam_et *target, 190251143Sbapt struct cam_ed *device, 191251143Sbapt void *async_arg); 192251143Sbaptstatic void ata_action(union ccb *start_ccb); 193251143Sbaptstatic void ata_announce_periph(struct cam_periph *periph); 194251143Sbapt 195251143Sbaptstatic int ata_dma = 1; 196251143Sbaptstatic int atapi_dma = 1; 197251143Sbapt 198251143SbaptTUNABLE_INT("hw.ata.ata_dma", &ata_dma); 199251143SbaptTUNABLE_INT("hw.ata.atapi_dma", &atapi_dma); 200251143Sbapt 201234949Sbaptstatic struct xpt_xport ata_xport = { 202234949Sbapt .alloc_device = ata_alloc_device, 203234949Sbapt .action = ata_action, 204234949Sbapt .async = ata_dev_async, 205234949Sbapt .announce = ata_announce_periph, 206234949Sbapt}; 207234949Sbapt 208234949Sbaptstruct xpt_xport * 209234949Sbaptata_get_xport(void) 210234949Sbapt{ 211234949Sbapt return (&ata_xport); 212234949Sbapt} 213234949Sbapt 214234949Sbaptstatic void 215234949Sbaptprobe_periph_init() 216234949Sbapt{ 217234949Sbapt} 218234949Sbapt 219234949Sbaptstatic cam_status 220234949Sbaptproberegister(struct cam_periph *periph, void *arg) 221234949Sbapt{ 222234949Sbapt union ccb *request_ccb; /* CCB representing the probe request */ 223251143Sbapt cam_status status; 224234949Sbapt probe_softc *softc; 225234949Sbapt 226234949Sbapt request_ccb = (union ccb *)arg; 227234949Sbapt if (request_ccb == NULL) { 228234949Sbapt printf("proberegister: no probe CCB, " 229234949Sbapt "can't register device\n"); 230234949Sbapt return(CAM_REQ_CMP_ERR); 231234949Sbapt } 232234949Sbapt 233234949Sbapt softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_ZERO | M_NOWAIT); 234234949Sbapt 235268899Sbapt if (softc == NULL) { 236251143Sbapt printf("proberegister: Unable to probe new device. " 237251143Sbapt "Unable to allocate softc\n"); 238251143Sbapt return(CAM_REQ_CMP_ERR); 239251143Sbapt } 240251143Sbapt TAILQ_INIT(&softc->request_ccbs); 241251143Sbapt TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, 242251143Sbapt periph_links.tqe); 243251143Sbapt softc->flags = 0; 244251143Sbapt periph->softc = softc; 245251143Sbapt softc->periph = periph; 246268899Sbapt softc->action = PROBE_INVALID; 247251143Sbapt status = cam_periph_acquire(periph); 248251143Sbapt if (status != CAM_REQ_CMP) { 249251143Sbapt return (status); 250251143Sbapt } 251251143Sbapt CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n")); 252251143Sbapt 253251143Sbapt /* 254251143Sbapt * Ensure nobody slip in until probe finish. 255251143Sbapt */ 256251143Sbapt cam_freeze_devq_arg(periph->path, 257251143Sbapt RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1); 258251143Sbapt probeschedule(periph); 259251143Sbapt return(CAM_REQ_CMP); 260251143Sbapt} 261251143Sbapt 262251143Sbaptstatic void 263251143Sbaptprobeschedule(struct cam_periph *periph) 264251143Sbapt{ 265251143Sbapt union ccb *ccb; 266251143Sbapt probe_softc *softc; 267251143Sbapt 268251143Sbapt softc = (probe_softc *)periph->softc; 269234949Sbapt ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs); 270234949Sbapt 271234949Sbapt if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) || 272234949Sbapt periph->path->device->protocol == PROTO_SATAPM || 273234949Sbapt periph->path->device->protocol == PROTO_SEMB) 274234949Sbapt PROBE_SET_ACTION(softc, PROBE_RESET); 275234949Sbapt else 276234949Sbapt PROBE_SET_ACTION(softc, PROBE_IDENTIFY); 277234949Sbapt 278234949Sbapt if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE) 279234949Sbapt softc->flags |= PROBE_NO_ANNOUNCE; 280234949Sbapt else 281234949Sbapt softc->flags &= ~PROBE_NO_ANNOUNCE; 282234949Sbapt 283251143Sbapt xpt_schedule(periph, CAM_PRIORITY_XPT); 284234949Sbapt} 285234949Sbapt 286234949Sbaptstatic void 287234949Sbaptprobestart(struct cam_periph *periph, union ccb *start_ccb) 288234949Sbapt{ 289234949Sbapt struct ccb_trans_settings cts; 290234949Sbapt struct ccb_ataio *ataio; 291234949Sbapt struct ccb_scsiio *csio; 292234949Sbapt probe_softc *softc; 293234949Sbapt struct cam_path *path; 294234949Sbapt struct ata_params *ident_buf; 295234949Sbapt 296234949Sbapt CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n")); 297234949Sbapt 298234949Sbapt softc = (probe_softc *)periph->softc; 299234949Sbapt path = start_ccb->ccb_h.path; 300234949Sbapt ataio = &start_ccb->ataio; 301234949Sbapt csio = &start_ccb->csio; 302234949Sbapt ident_buf = &periph->path->device->ident_data; 303234949Sbapt 304234949Sbapt if (softc->restart) { 305251143Sbapt softc->restart = 0; 306234949Sbapt if ((path->device->flags & CAM_DEV_UNCONFIGURED) || 307234949Sbapt path->device->protocol == PROTO_SATAPM || 308234949Sbapt path->device->protocol == PROTO_SEMB) 309234949Sbapt softc->action = PROBE_RESET; 310234949Sbapt else 311234949Sbapt softc->action = PROBE_IDENTIFY; 312234949Sbapt } 313234949Sbapt switch (softc->action) { 314234949Sbapt case PROBE_RESET: 315234949Sbapt cam_fill_ataio(ataio, 316234949Sbapt 0, 317234949Sbapt probedone, 318234949Sbapt /*flags*/CAM_DIR_NONE, 319234949Sbapt 0, 320234949Sbapt /*data_ptr*/NULL, 321234949Sbapt /*dxfer_len*/0, 322234949Sbapt 15 * 1000); 323251143Sbapt ata_reset_cmd(ataio); 324251143Sbapt break; 325234949Sbapt case PROBE_IDENTIFY: 326234949Sbapt cam_fill_ataio(ataio, 327234949Sbapt 1, 328251143Sbapt probedone, 329234949Sbapt /*flags*/CAM_DIR_IN, 330234949Sbapt 0, 331234949Sbapt /*data_ptr*/(u_int8_t *)&softc->ident_data, 332234949Sbapt /*dxfer_len*/sizeof(softc->ident_data), 333234949Sbapt 30 * 1000); 334234949Sbapt if (periph->path->device->protocol == PROTO_ATA) 335234949Sbapt ata_28bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0); 336234949Sbapt else 337234949Sbapt ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); 338234949Sbapt break; 339234949Sbapt case PROBE_SPINUP: 340234949Sbapt if (bootverbose) 341234949Sbapt xpt_print(path, "Spinning up device\n"); 342234949Sbapt cam_fill_ataio(ataio, 343234949Sbapt 1, 344234949Sbapt probedone, 345234949Sbapt /*flags*/CAM_DIR_NONE | CAM_HIGH_POWER, 346234949Sbapt 0, 347234949Sbapt /*data_ptr*/NULL, 348234949Sbapt /*dxfer_len*/0, 349234949Sbapt 30 * 1000); 350234949Sbapt ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_PUIS_SPINUP, 0, 0); 351234949Sbapt break; 352234949Sbapt case PROBE_SETMODE: 353234949Sbapt { 354234949Sbapt int mode, wantmode; 355234949Sbapt 356234949Sbapt mode = 0; 357234949Sbapt /* Fetch user modes from SIM. */ 358234949Sbapt bzero(&cts, sizeof(cts)); 359234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 360234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 361234949Sbapt cts.type = CTS_TYPE_USER_SETTINGS; 362234949Sbapt xpt_action((union ccb *)&cts); 363234949Sbapt if (path->device->transport == XPORT_ATA) { 364234949Sbapt if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE) 365234949Sbapt mode = cts.xport_specific.ata.mode; 366234949Sbapt } else { 367234949Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_MODE) 368234949Sbapt mode = cts.xport_specific.sata.mode; 369234949Sbapt } 370234949Sbapt if (periph->path->device->protocol == PROTO_ATA) { 371234949Sbapt if (ata_dma == 0 && (mode == 0 || mode > ATA_PIO_MAX)) 372234949Sbapt mode = ATA_PIO_MAX; 373234949Sbapt } else { 374234949Sbapt if (atapi_dma == 0 && (mode == 0 || mode > ATA_PIO_MAX)) 375234949Sbapt mode = ATA_PIO_MAX; 376234949Sbapt } 377234949Sbaptnegotiate: 378234949Sbapt /* Honor device capabilities. */ 379234949Sbapt wantmode = mode = ata_max_mode(ident_buf, mode); 380234949Sbapt /* Report modes to SIM. */ 381234949Sbapt bzero(&cts, sizeof(cts)); 382234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 383234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 384234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 385234949Sbapt if (path->device->transport == XPORT_ATA) { 386234949Sbapt cts.xport_specific.ata.mode = mode; 387234949Sbapt cts.xport_specific.ata.valid = CTS_ATA_VALID_MODE; 388234949Sbapt } else { 389234949Sbapt cts.xport_specific.sata.mode = mode; 390234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_MODE; 391234949Sbapt } 392234949Sbapt xpt_action((union ccb *)&cts); 393234949Sbapt /* Fetch current modes from SIM. */ 394234949Sbapt bzero(&cts, sizeof(cts)); 395234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 396234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 397234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 398234949Sbapt xpt_action((union ccb *)&cts); 399234949Sbapt if (path->device->transport == XPORT_ATA) { 400234949Sbapt if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE) 401234949Sbapt mode = cts.xport_specific.ata.mode; 402234949Sbapt } else { 403234949Sbapt if (cts.xport_specific.ata.valid & CTS_SATA_VALID_MODE) 404234949Sbapt mode = cts.xport_specific.sata.mode; 405234949Sbapt } 406251143Sbapt /* If SIM disagree - renegotiate. */ 407251143Sbapt if (mode != wantmode) 408251143Sbapt goto negotiate; 409234949Sbapt /* Remember what transport thinks about DMA. */ 410251143Sbapt if (mode < ATA_DMA) 411251143Sbapt path->device->inq_flags &= ~SID_DMA; 412251143Sbapt else 413251143Sbapt path->device->inq_flags |= SID_DMA; 414234949Sbapt xpt_async(AC_GETDEV_CHANGED, path, NULL); 415251143Sbapt cam_fill_ataio(ataio, 416234949Sbapt 1, 417234949Sbapt probedone, 418251143Sbapt /*flags*/CAM_DIR_NONE, 419251143Sbapt 0, 420251143Sbapt /*data_ptr*/NULL, 421251143Sbapt /*dxfer_len*/0, 422234949Sbapt 30 * 1000); 423251143Sbapt ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); 424234949Sbapt break; 425251143Sbapt } 426251143Sbapt case PROBE_SETPM: 427251143Sbapt cam_fill_ataio(ataio, 428234949Sbapt 1, 429234949Sbapt probedone, 430234949Sbapt CAM_DIR_NONE, 431234949Sbapt 0, 432234949Sbapt NULL, 433234949Sbapt 0, 434234949Sbapt 30*1000); 435234949Sbapt ata_28bit_cmd(ataio, ATA_SETFEATURES, 436234949Sbapt (softc->caps & CTS_SATA_CAPS_H_PMREQ) ? 0x10 : 0x90, 437234949Sbapt 0, 0x03); 438251143Sbapt break; 439234949Sbapt case PROBE_SETAPST: 440234949Sbapt cam_fill_ataio(ataio, 441234949Sbapt 1, 442234949Sbapt probedone, 443234949Sbapt CAM_DIR_NONE, 444234949Sbapt 0, 445234949Sbapt NULL, 446251143Sbapt 0, 447234949Sbapt 30*1000); 448234949Sbapt ata_28bit_cmd(ataio, ATA_SETFEATURES, 449234949Sbapt (softc->caps & CTS_SATA_CAPS_H_APST) ? 0x10 : 0x90, 450234949Sbapt 0, 0x07); 451234949Sbapt break; 452268899Sbapt case PROBE_SETDMAAA: 453234949Sbapt cam_fill_ataio(ataio, 454234949Sbapt 1, 455234949Sbapt probedone, 456234949Sbapt CAM_DIR_NONE, 457234949Sbapt 0, 458234949Sbapt NULL, 459234949Sbapt 0, 460234949Sbapt 30*1000); 461234949Sbapt ata_28bit_cmd(ataio, ATA_SETFEATURES, 462234949Sbapt (softc->caps & CTS_SATA_CAPS_H_DMAAA) ? 0x10 : 0x90, 463234949Sbapt 0, 0x02); 464234949Sbapt break; 465234949Sbapt case PROBE_SETAN: 466234949Sbapt /* Remember what transport thinks about AEN. */ 467234949Sbapt if (softc->caps & CTS_SATA_CAPS_H_AN) 468234949Sbapt path->device->inq_flags |= SID_AEN; 469234949Sbapt else 470234949Sbapt path->device->inq_flags &= ~SID_AEN; 471234949Sbapt xpt_async(AC_GETDEV_CHANGED, path, NULL); 472234949Sbapt cam_fill_ataio(ataio, 473234949Sbapt 1, 474234949Sbapt probedone, 475251143Sbapt CAM_DIR_NONE, 476234949Sbapt 0, 477234949Sbapt NULL, 478234949Sbapt 0, 479234949Sbapt 30*1000); 480234949Sbapt ata_28bit_cmd(ataio, ATA_SETFEATURES, 481234949Sbapt (softc->caps & CTS_SATA_CAPS_H_AN) ? 0x10 : 0x90, 482234949Sbapt 0, 0x05); 483234949Sbapt break; 484234949Sbapt case PROBE_SET_MULTI: 485234949Sbapt { 486234949Sbapt u_int sectors, bytecount; 487234949Sbapt 488234949Sbapt bytecount = 8192; /* SATA maximum */ 489234949Sbapt /* Fetch user bytecount from SIM. */ 490234949Sbapt bzero(&cts, sizeof(cts)); 491234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 492234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 493234949Sbapt cts.type = CTS_TYPE_USER_SETTINGS; 494234949Sbapt xpt_action((union ccb *)&cts); 495234949Sbapt if (path->device->transport == XPORT_ATA) { 496234949Sbapt if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) 497234949Sbapt bytecount = cts.xport_specific.ata.bytecount; 498234949Sbapt } else { 499234949Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) 500234949Sbapt bytecount = cts.xport_specific.sata.bytecount; 501234949Sbapt } 502234949Sbapt /* Honor device capabilities. */ 503234949Sbapt sectors = max(1, min(ident_buf->sectors_intr & 0xff, 504234949Sbapt bytecount / ata_logical_sector_size(ident_buf))); 505234949Sbapt /* Report bytecount to SIM. */ 506234949Sbapt bzero(&cts, sizeof(cts)); 507234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 508234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 509234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 510234949Sbapt if (path->device->transport == XPORT_ATA) { 511234949Sbapt cts.xport_specific.ata.bytecount = sectors * 512234949Sbapt ata_logical_sector_size(ident_buf); 513234949Sbapt cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; 514234949Sbapt } else { 515234949Sbapt cts.xport_specific.sata.bytecount = sectors * 516234949Sbapt ata_logical_sector_size(ident_buf); 517234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; 518234949Sbapt } 519234949Sbapt xpt_action((union ccb *)&cts); 520234949Sbapt /* Fetch current bytecount from SIM. */ 521234949Sbapt bzero(&cts, sizeof(cts)); 522234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 523234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 524268899Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 525268899Sbapt xpt_action((union ccb *)&cts); 526234949Sbapt if (path->device->transport == XPORT_ATA) { 527234949Sbapt if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) 528234949Sbapt bytecount = cts.xport_specific.ata.bytecount; 529234949Sbapt } else { 530268899Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) 531268899Sbapt bytecount = cts.xport_specific.sata.bytecount; 532234949Sbapt } 533234949Sbapt sectors = bytecount / ata_logical_sector_size(ident_buf); 534234949Sbapt 535234949Sbapt cam_fill_ataio(ataio, 536234949Sbapt 1, 537234949Sbapt probedone, 538234949Sbapt CAM_DIR_NONE, 539268899Sbapt 0, 540234949Sbapt NULL, 541234949Sbapt 0, 542234949Sbapt 30*1000); 543234949Sbapt ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, sectors); 544234949Sbapt break; 545234949Sbapt } 546234949Sbapt case PROBE_INQUIRY: 547234949Sbapt { 548234949Sbapt u_int bytecount; 549234949Sbapt 550234949Sbapt bytecount = 8192; /* SATA maximum */ 551234949Sbapt /* Fetch user bytecount from SIM. */ 552234949Sbapt bzero(&cts, sizeof(cts)); 553234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 554234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 555251143Sbapt cts.type = CTS_TYPE_USER_SETTINGS; 556251143Sbapt xpt_action((union ccb *)&cts); 557251143Sbapt if (path->device->transport == XPORT_ATA) { 558251143Sbapt if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) 559251143Sbapt bytecount = cts.xport_specific.ata.bytecount; 560251143Sbapt } else { 561251143Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) 562234949Sbapt bytecount = cts.xport_specific.sata.bytecount; 563234949Sbapt } 564234949Sbapt /* Honor device capabilities. */ 565234949Sbapt bytecount &= ~1; 566234949Sbapt bytecount = max(2, min(65534, bytecount)); 567234949Sbapt if (ident_buf->satacapabilities != 0x0000 && 568234949Sbapt ident_buf->satacapabilities != 0xffff) { 569234949Sbapt bytecount = min(8192, bytecount); 570234949Sbapt } 571234949Sbapt /* Report bytecount to SIM. */ 572234949Sbapt bzero(&cts, sizeof(cts)); 573234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 574234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 575234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 576234949Sbapt if (path->device->transport == XPORT_ATA) { 577234949Sbapt cts.xport_specific.ata.bytecount = bytecount; 578234949Sbapt cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; 579234949Sbapt } else { 580234949Sbapt cts.xport_specific.sata.bytecount = bytecount; 581234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; 582234949Sbapt } 583234949Sbapt xpt_action((union ccb *)&cts); 584234949Sbapt /* FALLTHROUGH */ 585234949Sbapt } 586234949Sbapt case PROBE_FULL_INQUIRY: 587234949Sbapt { 588234949Sbapt u_int inquiry_len; 589234949Sbapt struct scsi_inquiry_data *inq_buf = 590234949Sbapt &periph->path->device->inq_data; 591234949Sbapt 592234949Sbapt if (softc->action == PROBE_INQUIRY) 593234949Sbapt inquiry_len = SHORT_INQUIRY_LENGTH; 594234949Sbapt else 595234949Sbapt inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf); 596234949Sbapt /* 597234949Sbapt * Some parallel SCSI devices fail to send an 598234949Sbapt * ignore wide residue message when dealing with 599234949Sbapt * odd length inquiry requests. Round up to be 600234949Sbapt * safe. 601234949Sbapt */ 602234949Sbapt inquiry_len = roundup2(inquiry_len, 2); 603268899Sbapt scsi_inquiry(csio, 604234949Sbapt /*retries*/1, 605234949Sbapt probedone, 606234949Sbapt MSG_SIMPLE_Q_TAG, 607234949Sbapt (u_int8_t *)inq_buf, 608234949Sbapt inquiry_len, 609234949Sbapt /*evpd*/FALSE, 610234949Sbapt /*page_code*/0, 611234949Sbapt SSD_MIN_SIZE, 612234949Sbapt /*timeout*/60 * 1000); 613234949Sbapt break; 614234949Sbapt } 615234949Sbapt case PROBE_PM_PID: 616234949Sbapt cam_fill_ataio(ataio, 617251143Sbapt 1, 618234949Sbapt probedone, 619234949Sbapt /*flags*/CAM_DIR_NONE, 620234949Sbapt 0, 621234949Sbapt /*data_ptr*/NULL, 622234949Sbapt /*dxfer_len*/0, 623234949Sbapt 10 * 1000); 624234949Sbapt ata_pm_read_cmd(ataio, 0, 15); 625234949Sbapt break; 626234949Sbapt case PROBE_PM_PRV: 627234949Sbapt cam_fill_ataio(ataio, 628234949Sbapt 1, 629234949Sbapt probedone, 630234949Sbapt /*flags*/CAM_DIR_NONE, 631234949Sbapt 0, 632268899Sbapt /*data_ptr*/NULL, 633234949Sbapt /*dxfer_len*/0, 634234949Sbapt 10 * 1000); 635234949Sbapt ata_pm_read_cmd(ataio, 1, 15); 636234949Sbapt break; 637234949Sbapt case PROBE_IDENTIFY_SES: 638234949Sbapt cam_fill_ataio(ataio, 639234949Sbapt 1, 640234949Sbapt probedone, 641268899Sbapt /*flags*/CAM_DIR_IN, 642268899Sbapt 0, 643268899Sbapt /*data_ptr*/(u_int8_t *)&softc->ident_data, 644268899Sbapt /*dxfer_len*/sizeof(softc->ident_data), 645268899Sbapt 30 * 1000); 646268899Sbapt ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x02, 647268899Sbapt sizeof(softc->ident_data) / 4); 648268899Sbapt break; 649268899Sbapt case PROBE_IDENTIFY_SAFTE: 650268899Sbapt cam_fill_ataio(ataio, 651268899Sbapt 1, 652268899Sbapt probedone, 653268899Sbapt /*flags*/CAM_DIR_IN, 654268899Sbapt 0, 655268899Sbapt /*data_ptr*/(u_int8_t *)&softc->ident_data, 656268899Sbapt /*dxfer_len*/sizeof(softc->ident_data), 657268899Sbapt 30 * 1000); 658268899Sbapt ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x00, 659268899Sbapt sizeof(softc->ident_data) / 4); 660268899Sbapt break; 661268899Sbapt default: 662268899Sbapt panic("probestart: invalid action state 0x%x\n", softc->action); 663268899Sbapt } 664268899Sbapt xpt_action(start_ccb); 665268899Sbapt} 666268899Sbapt 667268899Sbaptstatic void 668268899Sbaptproberequestdefaultnegotiation(struct cam_periph *periph) 669268899Sbapt{ 670268899Sbapt struct ccb_trans_settings cts; 671268899Sbapt 672268899Sbapt xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); 673268899Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 674268899Sbapt cts.type = CTS_TYPE_USER_SETTINGS; 675268899Sbapt xpt_action((union ccb *)&cts); 676268899Sbapt if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 677268899Sbapt return; 678268899Sbapt cts.xport_specific.valid = 0; 679268899Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 680268899Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 681268899Sbapt xpt_action((union ccb *)&cts); 682268899Sbapt} 683268899Sbapt 684268899Sbaptstatic void 685268899Sbaptprobedone(struct cam_periph *periph, union ccb *done_ccb) 686268899Sbapt{ 687268899Sbapt struct ccb_trans_settings cts; 688268899Sbapt struct ata_params *ident_buf; 689268899Sbapt struct scsi_inquiry_data *inq_buf; 690268899Sbapt probe_softc *softc; 691268899Sbapt struct cam_path *path; 692268899Sbapt cam_status status; 693268899Sbapt u_int32_t priority; 694268899Sbapt u_int caps; 695234949Sbapt int changed = 1, found = 1; 696234949Sbapt static const uint8_t fake_device_id_hdr[8] = 697234949Sbapt {0, SVPD_DEVICE_ID, 0, 12, 698234949Sbapt SVPD_ID_CODESET_BINARY, SVPD_ID_TYPE_NAA, 0, 8}; 699234949Sbapt 700234949Sbapt CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n")); 701234949Sbapt 702234949Sbapt softc = (probe_softc *)periph->softc; 703234949Sbapt path = done_ccb->ccb_h.path; 704234949Sbapt priority = done_ccb->ccb_h.pinfo.priority; 705234949Sbapt ident_buf = &path->device->ident_data; 706234949Sbapt inq_buf = &path->device->inq_data; 707234949Sbapt 708234949Sbapt if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 709234949Sbapt if (cam_periph_error(done_ccb, 710234949Sbapt 0, softc->restart ? (SF_NO_RECOVERY | SF_NO_RETRY) : 0, 711234949Sbapt NULL) == ERESTART) 712234949Sbapt return; 713234949Sbapt if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { 714234949Sbapt /* Don't wedge the queue */ 715234949Sbapt xpt_release_devq(done_ccb->ccb_h.path, /*count*/1, 716234949Sbapt /*run_queue*/TRUE); 717234949Sbapt } 718234949Sbapt status = done_ccb->ccb_h.status & CAM_STATUS_MASK; 719234949Sbapt if (softc->restart) { 720234949Sbapt softc->faults++; 721234949Sbapt if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == 722234949Sbapt CAM_CMD_TIMEOUT) 723234949Sbapt softc->faults += 4; 724234949Sbapt if (softc->faults < 10) 725234949Sbapt goto done; 726234949Sbapt else 727234949Sbapt softc->restart = 0; 728234949Sbapt 729234949Sbapt /* Old PIO2 devices may not support mode setting. */ 730234949Sbapt } else if (softc->action == PROBE_SETMODE && 731234949Sbapt status == CAM_ATA_STATUS_ERROR && 732268899Sbapt ata_max_pmode(ident_buf) <= ATA_PIO2 && 733234949Sbapt (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0) { 734234949Sbapt goto noerror; 735234949Sbapt 736234949Sbapt /* 737234949Sbapt * Some old WD SATA disks report supported and enabled 738234949Sbapt * device-initiated interface power management, but return 739234949Sbapt * ABORT on attempt to disable it. 740234949Sbapt */ 741268899Sbapt } else if (softc->action == PROBE_SETPM && 742234949Sbapt status == CAM_ATA_STATUS_ERROR) { 743234949Sbapt goto noerror; 744234949Sbapt 745234949Sbapt /* 746234949Sbapt * Some HP SATA disks report supported DMA Auto-Activation, 747234949Sbapt * but return ABORT on attempt to enable it. 748234949Sbapt */ 749234949Sbapt } else if (softc->action == PROBE_SETDMAAA && 750234949Sbapt status == CAM_ATA_STATUS_ERROR) { 751234949Sbapt goto noerror; 752234949Sbapt 753234949Sbapt /* 754234949Sbapt * Some Samsung SSDs report supported Asynchronous Notification, 755234949Sbapt * but return ABORT on attempt to enable it. 756234949Sbapt */ 757234949Sbapt } else if (softc->action == PROBE_SETAN && 758234949Sbapt status == CAM_ATA_STATUS_ERROR) { 759251143Sbapt goto noerror; 760234949Sbapt 761234949Sbapt /* 762251143Sbapt * SES and SAF-TE SEPs have different IDENTIFY commands, 763234949Sbapt * but SATA specification doesn't tell how to identify them. 764234949Sbapt * Until better way found, just try another if first fail. 765234949Sbapt */ 766234949Sbapt } else if (softc->action == PROBE_IDENTIFY_SES && 767234949Sbapt status == CAM_ATA_STATUS_ERROR) { 768234949Sbapt PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE); 769234949Sbapt xpt_release_ccb(done_ccb); 770234949Sbapt xpt_schedule(periph, priority); 771234949Sbapt return; 772234949Sbapt } 773234949Sbapt 774234949Sbapt /* 775234949Sbapt * If we get to this point, we got an error status back 776234949Sbapt * from the inquiry and the error status doesn't require 777234949Sbapt * automatically retrying the command. Therefore, the 778234949Sbapt * inquiry failed. If we had inquiry information before 779234949Sbapt * for this device, but this latest inquiry command failed, 780234949Sbapt * the device has probably gone away. If this device isn't 781234949Sbapt * already marked unconfigured, notify the peripheral 782234949Sbapt * drivers that this device is no more. 783234949Sbapt */ 784234949Sbaptdevice_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 785234949Sbapt xpt_async(AC_LOST_DEVICE, path, NULL); 786234949Sbapt PROBE_SET_ACTION(softc, PROBE_INVALID); 787234949Sbapt found = 0; 788234949Sbapt goto done; 789234949Sbapt } 790234949Sbaptnoerror: 791234949Sbapt if (softc->restart) 792234949Sbapt goto done; 793234949Sbapt switch (softc->action) { 794234949Sbapt case PROBE_RESET: 795234949Sbapt { 796234949Sbapt int sign = (done_ccb->ataio.res.lba_high << 8) + 797234949Sbapt done_ccb->ataio.res.lba_mid; 798234949Sbapt CAM_DEBUG(path, CAM_DEBUG_PROBE, 799234949Sbapt ("SIGNATURE: %04x\n", sign)); 800234949Sbapt if (sign == 0x0000 && 801234949Sbapt done_ccb->ccb_h.target_id != 15) { 802234949Sbapt path->device->protocol = PROTO_ATA; 803234949Sbapt PROBE_SET_ACTION(softc, PROBE_IDENTIFY); 804251143Sbapt } else if (sign == 0x9669 && 805234949Sbapt done_ccb->ccb_h.target_id == 15) { 806251143Sbapt /* Report SIM that PM is present. */ 807251143Sbapt bzero(&cts, sizeof(cts)); 808251143Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 809234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 810251143Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 811234949Sbapt cts.xport_specific.sata.pm_present = 1; 812234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_PM; 813234949Sbapt xpt_action((union ccb *)&cts); 814234949Sbapt path->device->protocol = PROTO_SATAPM; 815234949Sbapt PROBE_SET_ACTION(softc, PROBE_PM_PID); 816234949Sbapt } else if (sign == 0xc33c && 817234949Sbapt done_ccb->ccb_h.target_id != 15) { 818234949Sbapt path->device->protocol = PROTO_SEMB; 819234949Sbapt PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SES); 820234949Sbapt } else if (sign == 0xeb14 && 821234949Sbapt done_ccb->ccb_h.target_id != 15) { 822251143Sbapt path->device->protocol = PROTO_SCSI; 823234949Sbapt PROBE_SET_ACTION(softc, PROBE_IDENTIFY); 824234949Sbapt } else { 825234949Sbapt if (done_ccb->ccb_h.target_id != 15) { 826234949Sbapt xpt_print(path, 827234949Sbapt "Unexpected signature 0x%04x\n", sign); 828234949Sbapt } 829251143Sbapt goto device_fail; 830234949Sbapt } 831234949Sbapt xpt_release_ccb(done_ccb); 832234949Sbapt xpt_schedule(periph, priority); 833234949Sbapt return; 834234949Sbapt } 835234949Sbapt case PROBE_IDENTIFY: 836234949Sbapt { 837234949Sbapt struct ccb_pathinq cpi; 838234949Sbapt int16_t *ptr; 839234949Sbapt 840234949Sbapt ident_buf = &softc->ident_data; 841234949Sbapt for (ptr = (int16_t *)ident_buf; 842234949Sbapt ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) { 843234949Sbapt *ptr = le16toh(*ptr); 844234949Sbapt } 845234949Sbapt if (strncmp(ident_buf->model, "FX", 2) && 846234949Sbapt strncmp(ident_buf->model, "NEC", 3) && 847234949Sbapt strncmp(ident_buf->model, "Pioneer", 7) && 848234949Sbapt strncmp(ident_buf->model, "SHARP", 5)) { 849234949Sbapt ata_bswap(ident_buf->model, sizeof(ident_buf->model)); 850234949Sbapt ata_bswap(ident_buf->revision, sizeof(ident_buf->revision)); 851234949Sbapt ata_bswap(ident_buf->serial, sizeof(ident_buf->serial)); 852234949Sbapt } 853234949Sbapt ata_btrim(ident_buf->model, sizeof(ident_buf->model)); 854234949Sbapt ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model)); 855234949Sbapt ata_btrim(ident_buf->revision, sizeof(ident_buf->revision)); 856234949Sbapt ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision)); 857234949Sbapt ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); 858234949Sbapt ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); 859234949Sbapt /* Device may need spin-up before IDENTIFY become valid. */ 860234949Sbapt if ((ident_buf->specconf == 0x37c8 || 861234949Sbapt ident_buf->specconf == 0x738c) && 862234949Sbapt ((ident_buf->config & ATA_RESP_INCOMPLETE) || 863234949Sbapt softc->spinup == 0)) { 864234949Sbapt PROBE_SET_ACTION(softc, PROBE_SPINUP); 865234949Sbapt xpt_release_ccb(done_ccb); 866234949Sbapt xpt_schedule(periph, priority); 867234949Sbapt return; 868234949Sbapt } 869234949Sbapt ident_buf = &path->device->ident_data; 870234949Sbapt if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { 871234949Sbapt /* Check that it is the same device. */ 872234949Sbapt if (bcmp(softc->ident_data.model, ident_buf->model, 873234949Sbapt sizeof(ident_buf->model)) || 874234949Sbapt bcmp(softc->ident_data.revision, ident_buf->revision, 875234949Sbapt sizeof(ident_buf->revision)) || 876234949Sbapt bcmp(softc->ident_data.serial, ident_buf->serial, 877234949Sbapt sizeof(ident_buf->serial))) { 878234949Sbapt /* Device changed. */ 879234949Sbapt xpt_async(AC_LOST_DEVICE, path, NULL); 880234949Sbapt } else { 881234949Sbapt bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); 882234949Sbapt changed = 0; 883234949Sbapt } 884234949Sbapt } 885234949Sbapt if (changed) { 886234949Sbapt bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); 887234949Sbapt /* Clean up from previous instance of this device */ 888234949Sbapt if (path->device->serial_num != NULL) { 889234949Sbapt free(path->device->serial_num, M_CAMXPT); 890234949Sbapt path->device->serial_num = NULL; 891234949Sbapt path->device->serial_num_len = 0; 892234949Sbapt } 893234949Sbapt if (path->device->device_id != NULL) { 894234949Sbapt free(path->device->device_id, M_CAMXPT); 895234949Sbapt path->device->device_id = NULL; 896234949Sbapt path->device->device_id_len = 0; 897234949Sbapt } 898234949Sbapt path->device->serial_num = 899234949Sbapt (u_int8_t *)malloc((sizeof(ident_buf->serial) + 1), 900234949Sbapt M_CAMXPT, M_NOWAIT); 901234949Sbapt if (path->device->serial_num != NULL) { 902234949Sbapt bcopy(ident_buf->serial, 903234949Sbapt path->device->serial_num, 904234949Sbapt sizeof(ident_buf->serial)); 905234949Sbapt path->device->serial_num[sizeof(ident_buf->serial)] 906234949Sbapt = '\0'; 907234949Sbapt path->device->serial_num_len = 908234949Sbapt strlen(path->device->serial_num); 909234949Sbapt } 910234949Sbapt if (ident_buf->enabled.extension & 911234949Sbapt ATA_SUPPORT_64BITWWN) { 912234949Sbapt path->device->device_id = 913234949Sbapt malloc(16, M_CAMXPT, M_NOWAIT); 914234949Sbapt if (path->device->device_id != NULL) { 915234949Sbapt path->device->device_id_len = 16; 916234949Sbapt bcopy(&fake_device_id_hdr, 917234949Sbapt path->device->device_id, 8); 918234949Sbapt bcopy(ident_buf->wwn, 919234949Sbapt path->device->device_id + 8, 8); 920234949Sbapt } 921234949Sbapt } 922234949Sbapt 923234949Sbapt path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; 924268899Sbapt xpt_async(AC_GETDEV_CHANGED, path, NULL); 925268899Sbapt } 926268899Sbapt if (ident_buf->satacapabilities & ATA_SUPPORT_NCQ) { 927268899Sbapt path->device->mintags = 2; 928268899Sbapt path->device->maxtags = 929268899Sbapt ATA_QUEUE_LEN(ident_buf->queue) + 1; 930268899Sbapt } 931268899Sbapt ata_find_quirk(path->device); 932268899Sbapt if (path->device->mintags != 0 && 933272953Srodrigc path->bus->sim->max_tagged_dev_openings != 0) { 934251143Sbapt /* Check if the SIM does not want queued commands. */ 935251143Sbapt bzero(&cpi, sizeof(cpi)); 936251143Sbapt xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); 937251143Sbapt cpi.ccb_h.func_code = XPT_PATH_INQ; 938251143Sbapt xpt_action((union ccb *)&cpi); 939251143Sbapt if (cpi.ccb_h.status == CAM_REQ_CMP && 940251143Sbapt (cpi.hba_inquiry & PI_TAG_ABLE)) { 941251143Sbapt /* Report SIM which tags are allowed. */ 942251143Sbapt bzero(&cts, sizeof(cts)); 943272953Srodrigc xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 944234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 945234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 946234949Sbapt cts.xport_specific.sata.tags = path->device->maxtags; 947234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS; 948234949Sbapt xpt_action((union ccb *)&cts); 949234949Sbapt } 950234949Sbapt } 951234949Sbapt ata_device_transport(path); 952234949Sbapt if (changed) 953234949Sbapt proberequestdefaultnegotiation(periph); 954234949Sbapt PROBE_SET_ACTION(softc, PROBE_SETMODE); 955234949Sbapt xpt_release_ccb(done_ccb); 956234949Sbapt xpt_schedule(periph, priority); 957234949Sbapt return; 958234949Sbapt } 959234949Sbapt case PROBE_SPINUP: 960234949Sbapt if (bootverbose) 961234949Sbapt xpt_print(path, "Spin-up done\n"); 962234949Sbapt softc->spinup = 1; 963234949Sbapt PROBE_SET_ACTION(softc, PROBE_IDENTIFY); 964234949Sbapt xpt_release_ccb(done_ccb); 965234949Sbapt xpt_schedule(periph, priority); 966234949Sbapt return; 967234949Sbapt case PROBE_SETMODE: 968234949Sbapt if (path->device->transport != XPORT_SATA) 969234949Sbapt goto notsata; 970234949Sbapt /* Set supported bits. */ 971234949Sbapt bzero(&cts, sizeof(cts)); 972234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 973234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 974234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 975234949Sbapt xpt_action((union ccb *)&cts); 976234949Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) 977234949Sbapt caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H; 978234949Sbapt else 979234949Sbapt caps = 0; 980234949Sbapt if (ident_buf->satacapabilities != 0xffff) { 981234949Sbapt if (ident_buf->satacapabilities & ATA_SUPPORT_IFPWRMNGTRCV) 982234949Sbapt caps |= CTS_SATA_CAPS_D_PMREQ; 983234949Sbapt if (ident_buf->satacapabilities & ATA_SUPPORT_HAPST) 984234949Sbapt caps |= CTS_SATA_CAPS_D_APST; 985234949Sbapt } 986234949Sbapt /* Mask unwanted bits. */ 987234949Sbapt bzero(&cts, sizeof(cts)); 988234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 989234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 990234949Sbapt cts.type = CTS_TYPE_USER_SETTINGS; 991234949Sbapt xpt_action((union ccb *)&cts); 992234949Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) 993234949Sbapt caps &= cts.xport_specific.sata.caps; 994234949Sbapt else 995234949Sbapt caps = 0; 996234949Sbapt /* Store result to SIM. */ 997234949Sbapt bzero(&cts, sizeof(cts)); 998234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 999234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 1000234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 1001234949Sbapt cts.xport_specific.sata.caps = caps; 1002234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS; 1003234949Sbapt xpt_action((union ccb *)&cts); 1004234949Sbapt softc->caps = caps; 1005234949Sbapt if ((ident_buf->satasupport & ATA_SUPPORT_IFPWRMNGT) && 1006234949Sbapt (!(softc->caps & CTS_SATA_CAPS_H_PMREQ)) != 1007234949Sbapt (!(ident_buf->sataenabled & ATA_SUPPORT_IFPWRMNGT))) { 1008234949Sbapt PROBE_SET_ACTION(softc, PROBE_SETPM); 1009234949Sbapt xpt_release_ccb(done_ccb); 1010234949Sbapt xpt_schedule(periph, priority); 1011234949Sbapt return; 1012234949Sbapt } 1013234949Sbapt /* FALLTHROUGH */ 1014234949Sbapt case PROBE_SETPM: 1015234949Sbapt if (ident_buf->satacapabilities != 0xffff && 1016234949Sbapt (ident_buf->satacapabilities & ATA_SUPPORT_DAPST) && 1017234949Sbapt (!(softc->caps & CTS_SATA_CAPS_H_APST)) != 1018234949Sbapt (!(ident_buf->sataenabled & ATA_ENABLED_DAPST))) { 1019234949Sbapt PROBE_SET_ACTION(softc, PROBE_SETAPST); 1020234949Sbapt xpt_release_ccb(done_ccb); 1021234949Sbapt xpt_schedule(periph, priority); 1022234949Sbapt return; 1023234949Sbapt } 1024234949Sbapt /* FALLTHROUGH */ 1025234949Sbapt case PROBE_SETAPST: 1026234949Sbapt if ((ident_buf->satasupport & ATA_SUPPORT_AUTOACTIVATE) && 1027234949Sbapt (!(softc->caps & CTS_SATA_CAPS_H_DMAAA)) != 1028234949Sbapt (!(ident_buf->sataenabled & ATA_SUPPORT_AUTOACTIVATE))) { 1029234949Sbapt PROBE_SET_ACTION(softc, PROBE_SETDMAAA); 1030234949Sbapt xpt_release_ccb(done_ccb); 1031234949Sbapt xpt_schedule(periph, priority); 1032234949Sbapt return; 1033234949Sbapt } 1034234949Sbapt /* FALLTHROUGH */ 1035234949Sbapt case PROBE_SETDMAAA: 1036234949Sbapt if ((ident_buf->satasupport & ATA_SUPPORT_ASYNCNOTIF) && 1037234949Sbapt (!(softc->caps & CTS_SATA_CAPS_H_AN)) != 1038234949Sbapt (!(ident_buf->sataenabled & ATA_SUPPORT_ASYNCNOTIF))) { 1039234949Sbapt PROBE_SET_ACTION(softc, PROBE_SETAN); 1040234949Sbapt xpt_release_ccb(done_ccb); 1041234949Sbapt xpt_schedule(periph, priority); 1042234949Sbapt return; 1043234949Sbapt } 1044234949Sbapt /* FALLTHROUGH */ 1045234949Sbapt case PROBE_SETAN: 1046234949Sbaptnotsata: 1047234949Sbapt if (path->device->protocol == PROTO_ATA) { 1048234949Sbapt PROBE_SET_ACTION(softc, PROBE_SET_MULTI); 1049234949Sbapt } else { 1050234949Sbapt PROBE_SET_ACTION(softc, PROBE_INQUIRY); 1051234949Sbapt } 1052234949Sbapt xpt_release_ccb(done_ccb); 1053234949Sbapt xpt_schedule(periph, priority); 1054234949Sbapt return; 1055234949Sbapt case PROBE_SET_MULTI: 1056234949Sbapt if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { 1057234949Sbapt path->device->flags &= ~CAM_DEV_UNCONFIGURED; 1058234949Sbapt xpt_acquire_device(path->device); 1059234949Sbapt done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; 1060234949Sbapt xpt_action(done_ccb); 1061234949Sbapt xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, 1062234949Sbapt done_ccb); 1063234949Sbapt } 1064234949Sbapt PROBE_SET_ACTION(softc, PROBE_DONE); 1065234949Sbapt break; 1066234949Sbapt case PROBE_INQUIRY: 1067234949Sbapt case PROBE_FULL_INQUIRY: 1068234949Sbapt { 1069234949Sbapt u_int8_t periph_qual, len; 1070234949Sbapt 1071234949Sbapt path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID; 1072234949Sbapt 1073234949Sbapt periph_qual = SID_QUAL(inq_buf); 1074234949Sbapt 1075234949Sbapt if (periph_qual != SID_QUAL_LU_CONNECTED) 1076234949Sbapt break; 1077234949Sbapt 1078234949Sbapt /* 1079234949Sbapt * We conservatively request only 1080234949Sbapt * SHORT_INQUIRY_LEN bytes of inquiry 1081234949Sbapt * information during our first try 1082234949Sbapt * at sending an INQUIRY. If the device 1083234949Sbapt * has more information to give, 1084234949Sbapt * perform a second request specifying 1085234949Sbapt * the amount of information the device 1086234949Sbapt * is willing to give. 1087234949Sbapt */ 1088272955Srodrigc len = inq_buf->additional_length 1089234949Sbapt + offsetof(struct scsi_inquiry_data, additional_length) + 1; 1090234949Sbapt if (softc->action == PROBE_INQUIRY 1091234949Sbapt && len > SHORT_INQUIRY_LENGTH) { 1092234949Sbapt PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY); 1093234949Sbapt xpt_release_ccb(done_ccb); 1094234949Sbapt xpt_schedule(periph, priority); 1095234949Sbapt return; 1096234949Sbapt } 1097234949Sbapt 1098251143Sbapt ata_device_transport(path); 1099234949Sbapt if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { 1100234949Sbapt path->device->flags &= ~CAM_DEV_UNCONFIGURED; 1101234949Sbapt xpt_acquire_device(path->device); 1102234949Sbapt done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; 1103234949Sbapt xpt_action(done_ccb); 1104234949Sbapt xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb); 1105234949Sbapt } 1106234949Sbapt PROBE_SET_ACTION(softc, PROBE_DONE); 1107234949Sbapt break; 1108268899Sbapt } 1109234949Sbapt case PROBE_PM_PID: 1110234949Sbapt if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0) 1111234949Sbapt bzero(ident_buf, sizeof(*ident_buf)); 1112234949Sbapt softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) + 1113234949Sbapt (done_ccb->ataio.res.lba_mid << 16) + 1114234949Sbapt (done_ccb->ataio.res.lba_low << 8) + 1115234949Sbapt done_ccb->ataio.res.sector_count; 1116234949Sbapt ((uint32_t *)ident_buf)[0] = softc->pm_pid; 1117234949Sbapt snprintf(ident_buf->model, sizeof(ident_buf->model), 1118234949Sbapt "Port Multiplier %08x", softc->pm_pid); 1119234949Sbapt PROBE_SET_ACTION(softc, PROBE_PM_PRV); 1120234949Sbapt xpt_release_ccb(done_ccb); 1121234949Sbapt xpt_schedule(periph, priority); 1122234949Sbapt return; 1123234949Sbapt case PROBE_PM_PRV: 1124234949Sbapt softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) + 1125234949Sbapt (done_ccb->ataio.res.lba_mid << 16) + 1126234949Sbapt (done_ccb->ataio.res.lba_low << 8) + 1127234949Sbapt done_ccb->ataio.res.sector_count; 1128234949Sbapt ((uint32_t *)ident_buf)[1] = softc->pm_prv; 1129234949Sbapt snprintf(ident_buf->revision, sizeof(ident_buf->revision), 1130234949Sbapt "%04x", softc->pm_prv); 1131234949Sbapt path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; 1132234949Sbapt ata_device_transport(path); 1133234949Sbapt if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) 1134234949Sbapt proberequestdefaultnegotiation(periph); 1135234949Sbapt /* Set supported bits. */ 1136234949Sbapt bzero(&cts, sizeof(cts)); 1137234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 1138234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 1139272955Srodrigc cts.type = CTS_TYPE_CURRENT_SETTINGS; 1140272955Srodrigc xpt_action((union ccb *)&cts); 1141272955Srodrigc if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) 1142234949Sbapt caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H; 1143234949Sbapt else 1144234949Sbapt caps = 0; 1145234949Sbapt /* All PMPs must support PM requests. */ 1146234949Sbapt caps |= CTS_SATA_CAPS_D_PMREQ; 1147234949Sbapt /* Mask unwanted bits. */ 1148234949Sbapt bzero(&cts, sizeof(cts)); 1149234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 1150234949Sbapt cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 1151234949Sbapt cts.type = CTS_TYPE_USER_SETTINGS; 1152234949Sbapt xpt_action((union ccb *)&cts); 1153234949Sbapt if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) 1154234949Sbapt caps &= cts.xport_specific.sata.caps; 1155234949Sbapt else 1156234949Sbapt caps = 0; 1157234949Sbapt /* Store result to SIM. */ 1158234949Sbapt bzero(&cts, sizeof(cts)); 1159234949Sbapt xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 1160234949Sbapt cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 1161234949Sbapt cts.type = CTS_TYPE_CURRENT_SETTINGS; 1162234949Sbapt cts.xport_specific.sata.caps = caps; 1163234949Sbapt cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS; 1164234949Sbapt xpt_action((union ccb *)&cts); 1165234949Sbapt softc->caps = caps; 1166234949Sbapt /* Remember what transport thinks about AEN. */ 1167234949Sbapt if (softc->caps & CTS_SATA_CAPS_H_AN) 1168234949Sbapt path->device->inq_flags |= SID_AEN; 1169268899Sbapt else 1170234949Sbapt path->device->inq_flags &= ~SID_AEN; 1171272955Srodrigc xpt_async(AC_GETDEV_CHANGED, path, NULL); 1172272955Srodrigc if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { 1173272955Srodrigc path->device->flags &= ~CAM_DEV_UNCONFIGURED; 1174272955Srodrigc xpt_acquire_device(path->device); 1175234949Sbapt done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; 1176234949Sbapt xpt_action(done_ccb); 1177234949Sbapt xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, 1178234949Sbapt done_ccb); 1179234949Sbapt } else { 1180234949Sbapt done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; 1181234949Sbapt xpt_action(done_ccb); 1182272955Srodrigc xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb); 1183234949Sbapt } 1184234949Sbapt PROBE_SET_ACTION(softc, PROBE_DONE); 1185234949Sbapt break; 1186234949Sbapt case PROBE_IDENTIFY_SES: 1187234949Sbapt case PROBE_IDENTIFY_SAFTE: 1188234949Sbapt if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { 1189234949Sbapt /* Check that it is the same device. */ 1190234949Sbapt if (bcmp(&softc->ident_data, ident_buf, 53)) { 1191234949Sbapt /* Device changed. */ 1192234949Sbapt xpt_async(AC_LOST_DEVICE, path, NULL); 1193234949Sbapt } else { 1194234949Sbapt bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); 1195234949Sbapt changed = 0; 1196234949Sbapt } 1197234949Sbapt } 1198234949Sbapt if (changed) { 1199234949Sbapt bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); 1200234949Sbapt /* Clean up from previous instance of this device */ 1201234949Sbapt if (path->device->device_id != NULL) { 1202234949Sbapt free(path->device->device_id, M_CAMXPT); 1203234949Sbapt path->device->device_id = NULL; 1204234949Sbapt path->device->device_id_len = 0; 1205234949Sbapt } 1206234949Sbapt path->device->device_id = 1207234949Sbapt malloc(16, M_CAMXPT, M_NOWAIT); 1208234949Sbapt if (path->device->device_id != NULL) { 1209234949Sbapt path->device->device_id_len = 16; 1210234949Sbapt bcopy(&fake_device_id_hdr, 1211234949Sbapt path->device->device_id, 8); 1212234949Sbapt bcopy(((uint8_t*)ident_buf) + 2, 1213234949Sbapt path->device->device_id + 8, 8); 1214 } 1215 1216 path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; 1217 } 1218 ata_device_transport(path); 1219 if (changed) 1220 proberequestdefaultnegotiation(periph); 1221 1222 if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { 1223 path->device->flags &= ~CAM_DEV_UNCONFIGURED; 1224 xpt_acquire_device(path->device); 1225 done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; 1226 xpt_action(done_ccb); 1227 xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, 1228 done_ccb); 1229 } 1230 PROBE_SET_ACTION(softc, PROBE_DONE); 1231 break; 1232 default: 1233 panic("probedone: invalid action state 0x%x\n", softc->action); 1234 } 1235done: 1236 if (softc->restart) { 1237 softc->restart = 0; 1238 xpt_release_ccb(done_ccb); 1239 probeschedule(periph); 1240 return; 1241 } 1242 xpt_release_ccb(done_ccb); 1243 CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n")); 1244 while ((done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs))) { 1245 TAILQ_REMOVE(&softc->request_ccbs, 1246 &done_ccb->ccb_h, periph_links.tqe); 1247 done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR; 1248 xpt_done(done_ccb); 1249 } 1250 cam_periph_invalidate(periph); 1251 cam_release_devq(periph->path, 1252 RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE); 1253 cam_periph_release_locked(periph); 1254} 1255 1256static void 1257probecleanup(struct cam_periph *periph) 1258{ 1259 free(periph->softc, M_CAMXPT); 1260} 1261 1262static void 1263ata_find_quirk(struct cam_ed *device) 1264{ 1265 struct ata_quirk_entry *quirk; 1266 caddr_t match; 1267 1268 match = cam_quirkmatch((caddr_t)&device->ident_data, 1269 (caddr_t)ata_quirk_table, 1270 ata_quirk_table_size, 1271 sizeof(*ata_quirk_table), ata_identify_match); 1272 1273 if (match == NULL) 1274 panic("xpt_find_quirk: device didn't match wildcard entry!!"); 1275 1276 quirk = (struct ata_quirk_entry *)match; 1277 device->quirk = quirk; 1278 if (quirk->quirks & CAM_QUIRK_MAXTAGS) { 1279 device->mintags = quirk->mintags; 1280 device->maxtags = quirk->maxtags; 1281 } 1282} 1283 1284typedef struct { 1285 union ccb *request_ccb; 1286 struct ccb_pathinq *cpi; 1287 int counter; 1288} ata_scan_bus_info; 1289 1290/* 1291 * To start a scan, request_ccb is an XPT_SCAN_BUS ccb. 1292 * As the scan progresses, xpt_scan_bus is used as the 1293 * callback on completion function. 1294 */ 1295static void 1296ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb) 1297{ 1298 struct cam_path *path; 1299 ata_scan_bus_info *scan_info; 1300 union ccb *work_ccb, *reset_ccb; 1301 cam_status status; 1302 1303 CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, 1304 ("xpt_scan_bus\n")); 1305 switch (request_ccb->ccb_h.func_code) { 1306 case XPT_SCAN_BUS: 1307 case XPT_SCAN_TGT: 1308 /* Find out the characteristics of the bus */ 1309 work_ccb = xpt_alloc_ccb_nowait(); 1310 if (work_ccb == NULL) { 1311 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1312 xpt_done(request_ccb); 1313 return; 1314 } 1315 xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path, 1316 request_ccb->ccb_h.pinfo.priority); 1317 work_ccb->ccb_h.func_code = XPT_PATH_INQ; 1318 xpt_action(work_ccb); 1319 if (work_ccb->ccb_h.status != CAM_REQ_CMP) { 1320 request_ccb->ccb_h.status = work_ccb->ccb_h.status; 1321 xpt_free_ccb(work_ccb); 1322 xpt_done(request_ccb); 1323 return; 1324 } 1325 1326 /* We may need to reset bus first, if we haven't done it yet. */ 1327 if ((work_ccb->cpi.hba_inquiry & 1328 (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) && 1329 !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) && 1330 !timevalisset(&request_ccb->ccb_h.path->bus->last_reset)) { 1331 reset_ccb = xpt_alloc_ccb_nowait(); 1332 if (reset_ccb == NULL) { 1333 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1334 xpt_free_ccb(work_ccb); 1335 xpt_done(request_ccb); 1336 return; 1337 } 1338 xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path, 1339 CAM_PRIORITY_NONE); 1340 reset_ccb->ccb_h.func_code = XPT_RESET_BUS; 1341 xpt_action(reset_ccb); 1342 if (reset_ccb->ccb_h.status != CAM_REQ_CMP) { 1343 request_ccb->ccb_h.status = reset_ccb->ccb_h.status; 1344 xpt_free_ccb(reset_ccb); 1345 xpt_free_ccb(work_ccb); 1346 xpt_done(request_ccb); 1347 return; 1348 } 1349 xpt_free_ccb(reset_ccb); 1350 } 1351 1352 /* Save some state for use while we probe for devices */ 1353 scan_info = (ata_scan_bus_info *) 1354 malloc(sizeof(ata_scan_bus_info), M_CAMXPT, M_NOWAIT); 1355 if (scan_info == NULL) { 1356 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1357 xpt_free_ccb(work_ccb); 1358 xpt_done(request_ccb); 1359 return; 1360 } 1361 scan_info->request_ccb = request_ccb; 1362 scan_info->cpi = &work_ccb->cpi; 1363 /* If PM supported, probe it first. */ 1364 if (scan_info->cpi->hba_inquiry & PI_SATAPM) 1365 scan_info->counter = scan_info->cpi->max_target; 1366 else 1367 scan_info->counter = 0; 1368 1369 work_ccb = xpt_alloc_ccb_nowait(); 1370 if (work_ccb == NULL) { 1371 free(scan_info, M_CAMXPT); 1372 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1373 xpt_done(request_ccb); 1374 break; 1375 } 1376 goto scan_next; 1377 case XPT_SCAN_LUN: 1378 work_ccb = request_ccb; 1379 /* Reuse the same CCB to query if a device was really found */ 1380 scan_info = (ata_scan_bus_info *)work_ccb->ccb_h.ppriv_ptr0; 1381 /* If there is PMP... */ 1382 if ((scan_info->cpi->hba_inquiry & PI_SATAPM) && 1383 (scan_info->counter == scan_info->cpi->max_target)) { 1384 if (work_ccb->ccb_h.status == CAM_REQ_CMP) { 1385 /* everything else will be probed by it */ 1386 /* Free the current request path- we're done with it. */ 1387 xpt_free_path(work_ccb->ccb_h.path); 1388 goto done; 1389 } else { 1390 struct ccb_trans_settings cts; 1391 1392 /* Report SIM that PM is absent. */ 1393 bzero(&cts, sizeof(cts)); 1394 xpt_setup_ccb(&cts.ccb_h, 1395 work_ccb->ccb_h.path, CAM_PRIORITY_NONE); 1396 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 1397 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1398 cts.xport_specific.sata.pm_present = 0; 1399 cts.xport_specific.sata.valid = CTS_SATA_VALID_PM; 1400 xpt_action((union ccb *)&cts); 1401 } 1402 } 1403 /* Free the current request path- we're done with it. */ 1404 xpt_free_path(work_ccb->ccb_h.path); 1405 if (scan_info->counter == 1406 ((scan_info->cpi->hba_inquiry & PI_SATAPM) ? 1407 0 : scan_info->cpi->max_target)) { 1408done: 1409 xpt_free_ccb(work_ccb); 1410 xpt_free_ccb((union ccb *)scan_info->cpi); 1411 request_ccb = scan_info->request_ccb; 1412 free(scan_info, M_CAMXPT); 1413 request_ccb->ccb_h.status = CAM_REQ_CMP; 1414 xpt_done(request_ccb); 1415 break; 1416 } 1417 /* Take next device. Wrap from max (PMP) to 0. */ 1418 scan_info->counter = (scan_info->counter + 1 ) % 1419 (scan_info->cpi->max_target + 1); 1420scan_next: 1421 status = xpt_create_path(&path, xpt_periph, 1422 scan_info->request_ccb->ccb_h.path_id, 1423 scan_info->counter, 0); 1424 if (status != CAM_REQ_CMP) { 1425 printf("xpt_scan_bus: xpt_create_path failed" 1426 " with status %#x, bus scan halted\n", 1427 status); 1428 xpt_free_ccb(work_ccb); 1429 xpt_free_ccb((union ccb *)scan_info->cpi); 1430 request_ccb = scan_info->request_ccb; 1431 free(scan_info, M_CAMXPT); 1432 request_ccb->ccb_h.status = status; 1433 xpt_done(request_ccb); 1434 break; 1435 } 1436 xpt_setup_ccb(&work_ccb->ccb_h, path, 1437 scan_info->request_ccb->ccb_h.pinfo.priority); 1438 work_ccb->ccb_h.func_code = XPT_SCAN_LUN; 1439 work_ccb->ccb_h.cbfcnp = ata_scan_bus; 1440 work_ccb->ccb_h.ppriv_ptr0 = scan_info; 1441 work_ccb->crcn.flags = scan_info->request_ccb->crcn.flags; 1442 xpt_action(work_ccb); 1443 break; 1444 default: 1445 break; 1446 } 1447} 1448 1449static void 1450ata_scan_lun(struct cam_periph *periph, struct cam_path *path, 1451 cam_flags flags, union ccb *request_ccb) 1452{ 1453 struct ccb_pathinq cpi; 1454 cam_status status; 1455 struct cam_path *new_path; 1456 struct cam_periph *old_periph; 1457 1458 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_scan_lun\n")); 1459 1460 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); 1461 cpi.ccb_h.func_code = XPT_PATH_INQ; 1462 xpt_action((union ccb *)&cpi); 1463 1464 if (cpi.ccb_h.status != CAM_REQ_CMP) { 1465 if (request_ccb != NULL) { 1466 request_ccb->ccb_h.status = cpi.ccb_h.status; 1467 xpt_done(request_ccb); 1468 } 1469 return; 1470 } 1471 1472 if (request_ccb == NULL) { 1473 request_ccb = xpt_alloc_ccb_nowait(); 1474 if (request_ccb == NULL) { 1475 xpt_print(path, "xpt_scan_lun: can't allocate CCB, " 1476 "can't continue\n"); 1477 return; 1478 } 1479 status = xpt_create_path(&new_path, xpt_periph, 1480 path->bus->path_id, 1481 path->target->target_id, 1482 path->device->lun_id); 1483 if (status != CAM_REQ_CMP) { 1484 xpt_print(path, "xpt_scan_lun: can't create path, " 1485 "can't continue\n"); 1486 xpt_free_ccb(request_ccb); 1487 return; 1488 } 1489 xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_XPT); 1490 request_ccb->ccb_h.cbfcnp = xptscandone; 1491 request_ccb->ccb_h.func_code = XPT_SCAN_LUN; 1492 request_ccb->crcn.flags = flags; 1493 } 1494 1495 if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) { 1496 if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) { 1497 probe_softc *softc; 1498 1499 softc = (probe_softc *)old_periph->softc; 1500 TAILQ_INSERT_TAIL(&softc->request_ccbs, 1501 &request_ccb->ccb_h, periph_links.tqe); 1502 softc->restart = 1; 1503 } else { 1504 request_ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1505 xpt_done(request_ccb); 1506 } 1507 } else { 1508 status = cam_periph_alloc(proberegister, NULL, probecleanup, 1509 probestart, "aprobe", 1510 CAM_PERIPH_BIO, 1511 request_ccb->ccb_h.path, NULL, 0, 1512 request_ccb); 1513 1514 if (status != CAM_REQ_CMP) { 1515 xpt_print(path, "xpt_scan_lun: cam_alloc_periph " 1516 "returned an error, can't continue probe\n"); 1517 request_ccb->ccb_h.status = status; 1518 xpt_done(request_ccb); 1519 } 1520 } 1521} 1522 1523static void 1524xptscandone(struct cam_periph *periph, union ccb *done_ccb) 1525{ 1526 1527 xpt_free_path(done_ccb->ccb_h.path); 1528 xpt_free_ccb(done_ccb); 1529} 1530 1531static struct cam_ed * 1532ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id) 1533{ 1534 struct cam_path path; 1535 struct ata_quirk_entry *quirk; 1536 struct cam_ed *device; 1537 struct cam_ed *cur_device; 1538 1539 device = xpt_alloc_device(bus, target, lun_id); 1540 if (device == NULL) 1541 return (NULL); 1542 1543 /* 1544 * Take the default quirk entry until we have inquiry 1545 * data and can determine a better quirk to use. 1546 */ 1547 quirk = &ata_quirk_table[ata_quirk_table_size - 1]; 1548 device->quirk = (void *)quirk; 1549 device->mintags = 0; 1550 device->maxtags = 0; 1551 bzero(&device->inq_data, sizeof(device->inq_data)); 1552 device->inq_flags = 0; 1553 device->queue_flags = 0; 1554 device->serial_num = NULL; 1555 device->serial_num_len = 0; 1556 1557 /* 1558 * XXX should be limited by number of CCBs this bus can 1559 * do. 1560 */ 1561 bus->sim->max_ccbs += device->ccbq.devq_openings; 1562 /* Insertion sort into our target's device list */ 1563 cur_device = TAILQ_FIRST(&target->ed_entries); 1564 while (cur_device != NULL && cur_device->lun_id < lun_id) 1565 cur_device = TAILQ_NEXT(cur_device, links); 1566 if (cur_device != NULL) { 1567 TAILQ_INSERT_BEFORE(cur_device, device, links); 1568 } else { 1569 TAILQ_INSERT_TAIL(&target->ed_entries, device, links); 1570 } 1571 target->generation++; 1572 if (lun_id != CAM_LUN_WILDCARD) { 1573 xpt_compile_path(&path, 1574 NULL, 1575 bus->path_id, 1576 target->target_id, 1577 lun_id); 1578 ata_device_transport(&path); 1579 xpt_release_path(&path); 1580 } 1581 1582 return (device); 1583} 1584 1585static void 1586ata_device_transport(struct cam_path *path) 1587{ 1588 struct ccb_pathinq cpi; 1589 struct ccb_trans_settings cts; 1590 struct scsi_inquiry_data *inq_buf = NULL; 1591 struct ata_params *ident_buf = NULL; 1592 1593 /* Get transport information from the SIM */ 1594 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); 1595 cpi.ccb_h.func_code = XPT_PATH_INQ; 1596 xpt_action((union ccb *)&cpi); 1597 1598 path->device->transport = cpi.transport; 1599 if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) 1600 inq_buf = &path->device->inq_data; 1601 if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) != 0) 1602 ident_buf = &path->device->ident_data; 1603 if (path->device->protocol == PROTO_ATA) { 1604 path->device->protocol_version = ident_buf ? 1605 ata_version(ident_buf->version_major) : cpi.protocol_version; 1606 } else if (path->device->protocol == PROTO_SCSI) { 1607 path->device->protocol_version = inq_buf ? 1608 SID_ANSI_REV(inq_buf) : cpi.protocol_version; 1609 } 1610 path->device->transport_version = ident_buf ? 1611 ata_version(ident_buf->version_major) : cpi.transport_version; 1612 1613 /* Tell the controller what we think */ 1614 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); 1615 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 1616 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1617 cts.transport = path->device->transport; 1618 cts.transport_version = path->device->transport_version; 1619 cts.protocol = path->device->protocol; 1620 cts.protocol_version = path->device->protocol_version; 1621 cts.proto_specific.valid = 0; 1622 if (ident_buf) { 1623 if (path->device->transport == XPORT_ATA) { 1624 cts.xport_specific.ata.atapi = 1625 (ident_buf->config == ATA_PROTO_CFA) ? 0 : 1626 ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 : 1627 ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0; 1628 cts.xport_specific.ata.valid = CTS_ATA_VALID_ATAPI; 1629 } else { 1630 cts.xport_specific.sata.atapi = 1631 (ident_buf->config == ATA_PROTO_CFA) ? 0 : 1632 ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 : 1633 ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0; 1634 cts.xport_specific.sata.valid = CTS_SATA_VALID_ATAPI; 1635 } 1636 } else 1637 cts.xport_specific.valid = 0; 1638 xpt_action((union ccb *)&cts); 1639} 1640 1641static void 1642ata_dev_advinfo(union ccb *start_ccb) 1643{ 1644 struct cam_ed *device; 1645 struct ccb_dev_advinfo *cdai; 1646 off_t amt; 1647 1648 start_ccb->ccb_h.status = CAM_REQ_INVALID; 1649 device = start_ccb->ccb_h.path->device; 1650 cdai = &start_ccb->cdai; 1651 switch(cdai->buftype) { 1652 case CDAI_TYPE_SCSI_DEVID: 1653 if (cdai->flags & CDAI_FLAG_STORE) 1654 return; 1655 cdai->provsiz = device->device_id_len; 1656 if (device->device_id_len == 0) 1657 break; 1658 amt = device->device_id_len; 1659 if (cdai->provsiz > cdai->bufsiz) 1660 amt = cdai->bufsiz; 1661 memcpy(cdai->buf, device->device_id, amt); 1662 break; 1663 case CDAI_TYPE_SERIAL_NUM: 1664 if (cdai->flags & CDAI_FLAG_STORE) 1665 return; 1666 cdai->provsiz = device->serial_num_len; 1667 if (device->serial_num_len == 0) 1668 break; 1669 amt = device->serial_num_len; 1670 if (cdai->provsiz > cdai->bufsiz) 1671 amt = cdai->bufsiz; 1672 memcpy(cdai->buf, device->serial_num, amt); 1673 break; 1674 case CDAI_TYPE_PHYS_PATH: 1675 if (cdai->flags & CDAI_FLAG_STORE) { 1676 if (device->physpath != NULL) 1677 free(device->physpath, M_CAMXPT); 1678 device->physpath_len = cdai->bufsiz; 1679 /* Clear existing buffer if zero length */ 1680 if (cdai->bufsiz == 0) 1681 break; 1682 device->physpath = malloc(cdai->bufsiz, M_CAMXPT, M_NOWAIT); 1683 if (device->physpath == NULL) { 1684 start_ccb->ccb_h.status = CAM_REQ_ABORTED; 1685 return; 1686 } 1687 memcpy(device->physpath, cdai->buf, cdai->bufsiz); 1688 } else { 1689 cdai->provsiz = device->physpath_len; 1690 if (device->physpath_len == 0) 1691 break; 1692 amt = device->physpath_len; 1693 if (cdai->provsiz > cdai->bufsiz) 1694 amt = cdai->bufsiz; 1695 memcpy(cdai->buf, device->physpath, amt); 1696 } 1697 break; 1698 default: 1699 return; 1700 } 1701 start_ccb->ccb_h.status = CAM_REQ_CMP; 1702 1703 if (cdai->flags & CDAI_FLAG_STORE) { 1704 int owned; 1705 1706 owned = mtx_owned(start_ccb->ccb_h.path->bus->sim->mtx); 1707 if (owned == 0) 1708 mtx_lock(start_ccb->ccb_h.path->bus->sim->mtx); 1709 xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path, 1710 (void *)(uintptr_t)cdai->buftype); 1711 if (owned == 0) 1712 mtx_unlock(start_ccb->ccb_h.path->bus->sim->mtx); 1713 } 1714} 1715 1716static void 1717ata_action(union ccb *start_ccb) 1718{ 1719 1720 switch (start_ccb->ccb_h.func_code) { 1721 case XPT_SET_TRAN_SETTINGS: 1722 { 1723 ata_set_transfer_settings(&start_ccb->cts, 1724 start_ccb->ccb_h.path->device, 1725 /*async_update*/FALSE); 1726 break; 1727 } 1728 case XPT_SCAN_BUS: 1729 case XPT_SCAN_TGT: 1730 ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb); 1731 break; 1732 case XPT_SCAN_LUN: 1733 ata_scan_lun(start_ccb->ccb_h.path->periph, 1734 start_ccb->ccb_h.path, start_ccb->crcn.flags, 1735 start_ccb); 1736 break; 1737 case XPT_GET_TRAN_SETTINGS: 1738 { 1739 ata_get_transfer_settings(&start_ccb->cts); 1740 break; 1741 } 1742 case XPT_SCSI_IO: 1743 { 1744 struct cam_ed *device; 1745 u_int maxlen = 0; 1746 1747 device = start_ccb->ccb_h.path->device; 1748 if (device->protocol == PROTO_SCSI && 1749 (device->flags & CAM_DEV_IDENTIFY_DATA_VALID)) { 1750 uint16_t p = 1751 device->ident_data.config & ATA_PROTO_MASK; 1752 1753 maxlen = 1754 (device->ident_data.config == ATA_PROTO_CFA) ? 0 : 1755 (p == ATA_PROTO_ATAPI_16) ? 16 : 1756 (p == ATA_PROTO_ATAPI_12) ? 12 : 0; 1757 } 1758 if (start_ccb->csio.cdb_len > maxlen) { 1759 start_ccb->ccb_h.status = CAM_REQ_INVALID; 1760 xpt_done(start_ccb); 1761 break; 1762 } 1763 xpt_action_default(start_ccb); 1764 break; 1765 } 1766 case XPT_DEV_ADVINFO: 1767 { 1768 ata_dev_advinfo(start_ccb); 1769 break; 1770 } 1771 default: 1772 xpt_action_default(start_ccb); 1773 break; 1774 } 1775} 1776 1777static void 1778ata_get_transfer_settings(struct ccb_trans_settings *cts) 1779{ 1780 struct ccb_trans_settings_ata *ata; 1781 struct ccb_trans_settings_scsi *scsi; 1782 struct cam_ed *device; 1783 struct cam_sim *sim; 1784 1785 device = cts->ccb_h.path->device; 1786 sim = cts->ccb_h.path->bus->sim; 1787 (*(sim->sim_action))(sim, (union ccb *)cts); 1788 1789 if (cts->protocol == PROTO_UNKNOWN || 1790 cts->protocol == PROTO_UNSPECIFIED) { 1791 cts->protocol = device->protocol; 1792 cts->protocol_version = device->protocol_version; 1793 } 1794 1795 if (cts->protocol == PROTO_ATA) { 1796 ata = &cts->proto_specific.ata; 1797 if ((ata->valid & CTS_ATA_VALID_TQ) == 0) { 1798 ata->valid |= CTS_ATA_VALID_TQ; 1799 if (cts->type == CTS_TYPE_USER_SETTINGS || 1800 (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || 1801 (device->inq_flags & SID_CmdQue) != 0) 1802 ata->flags |= CTS_ATA_FLAGS_TAG_ENB; 1803 } 1804 } 1805 if (cts->protocol == PROTO_SCSI) { 1806 scsi = &cts->proto_specific.scsi; 1807 if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) { 1808 scsi->valid |= CTS_SCSI_VALID_TQ; 1809 if (cts->type == CTS_TYPE_USER_SETTINGS || 1810 (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || 1811 (device->inq_flags & SID_CmdQue) != 0) 1812 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 1813 } 1814 } 1815 1816 if (cts->transport == XPORT_UNKNOWN || 1817 cts->transport == XPORT_UNSPECIFIED) { 1818 cts->transport = device->transport; 1819 cts->transport_version = device->transport_version; 1820 } 1821} 1822 1823static void 1824ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, 1825 int async_update) 1826{ 1827 struct ccb_pathinq cpi; 1828 struct ccb_trans_settings_ata *ata; 1829 struct ccb_trans_settings_scsi *scsi; 1830 struct cam_sim *sim; 1831 struct ata_params *ident_data; 1832 struct scsi_inquiry_data *inq_data; 1833 1834 if (device == NULL) { 1835 cts->ccb_h.status = CAM_PATH_INVALID; 1836 xpt_done((union ccb *)cts); 1837 return; 1838 } 1839 1840 if (cts->protocol == PROTO_UNKNOWN 1841 || cts->protocol == PROTO_UNSPECIFIED) { 1842 cts->protocol = device->protocol; 1843 cts->protocol_version = device->protocol_version; 1844 } 1845 1846 if (cts->protocol_version == PROTO_VERSION_UNKNOWN 1847 || cts->protocol_version == PROTO_VERSION_UNSPECIFIED) 1848 cts->protocol_version = device->protocol_version; 1849 1850 if (cts->protocol != device->protocol) { 1851 xpt_print(cts->ccb_h.path, "Uninitialized Protocol %x:%x?\n", 1852 cts->protocol, device->protocol); 1853 cts->protocol = device->protocol; 1854 } 1855 1856 if (cts->protocol_version > device->protocol_version) { 1857 if (bootverbose) { 1858 xpt_print(cts->ccb_h.path, "Down reving Protocol " 1859 "Version from %d to %d?\n", cts->protocol_version, 1860 device->protocol_version); 1861 } 1862 cts->protocol_version = device->protocol_version; 1863 } 1864 1865 if (cts->transport == XPORT_UNKNOWN 1866 || cts->transport == XPORT_UNSPECIFIED) { 1867 cts->transport = device->transport; 1868 cts->transport_version = device->transport_version; 1869 } 1870 1871 if (cts->transport_version == XPORT_VERSION_UNKNOWN 1872 || cts->transport_version == XPORT_VERSION_UNSPECIFIED) 1873 cts->transport_version = device->transport_version; 1874 1875 if (cts->transport != device->transport) { 1876 xpt_print(cts->ccb_h.path, "Uninitialized Transport %x:%x?\n", 1877 cts->transport, device->transport); 1878 cts->transport = device->transport; 1879 } 1880 1881 if (cts->transport_version > device->transport_version) { 1882 if (bootverbose) { 1883 xpt_print(cts->ccb_h.path, "Down reving Transport " 1884 "Version from %d to %d?\n", cts->transport_version, 1885 device->transport_version); 1886 } 1887 cts->transport_version = device->transport_version; 1888 } 1889 1890 sim = cts->ccb_h.path->bus->sim; 1891 ident_data = &device->ident_data; 1892 inq_data = &device->inq_data; 1893 if (cts->protocol == PROTO_ATA) 1894 ata = &cts->proto_specific.ata; 1895 else 1896 ata = NULL; 1897 if (cts->protocol == PROTO_SCSI) 1898 scsi = &cts->proto_specific.scsi; 1899 else 1900 scsi = NULL; 1901 xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); 1902 cpi.ccb_h.func_code = XPT_PATH_INQ; 1903 xpt_action((union ccb *)&cpi); 1904 1905 /* Sanity checking */ 1906 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0 1907 || (ata && (ident_data->satacapabilities & ATA_SUPPORT_NCQ) == 0) 1908 || (scsi && (INQ_DATA_TQ_ENABLED(inq_data)) == 0) 1909 || (device->queue_flags & SCP_QUEUE_DQUE) != 0 1910 || (device->mintags == 0)) { 1911 /* 1912 * Can't tag on hardware that doesn't support tags, 1913 * doesn't have it enabled, or has broken tag support. 1914 */ 1915 if (ata) 1916 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; 1917 if (scsi) 1918 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1919 } 1920 1921 /* Start/stop tags use. */ 1922 if (cts->type == CTS_TYPE_CURRENT_SETTINGS && 1923 ((ata && (ata->valid & CTS_ATA_VALID_TQ) != 0) || 1924 (scsi && (scsi->valid & CTS_SCSI_VALID_TQ) != 0))) { 1925 int nowt, newt = 0; 1926 1927 nowt = ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || 1928 (device->inq_flags & SID_CmdQue) != 0); 1929 if (ata) 1930 newt = (ata->flags & CTS_ATA_FLAGS_TAG_ENB) != 0; 1931 if (scsi) 1932 newt = (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0; 1933 1934 if (newt && !nowt) { 1935 /* 1936 * Delay change to use tags until after a 1937 * few commands have gone to this device so 1938 * the controller has time to perform transfer 1939 * negotiations without tagged messages getting 1940 * in the way. 1941 */ 1942 device->tag_delay_count = CAM_TAG_DELAY_COUNT; 1943 device->flags |= CAM_DEV_TAG_AFTER_COUNT; 1944 } else if (nowt && !newt) 1945 xpt_stop_tags(cts->ccb_h.path); 1946 } 1947 1948 if (async_update == FALSE) 1949 (*(sim->sim_action))(sim, (union ccb *)cts); 1950} 1951 1952/* 1953 * Handle any per-device event notifications that require action by the XPT. 1954 */ 1955static void 1956ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, 1957 struct cam_ed *device, void *async_arg) 1958{ 1959 cam_status status; 1960 struct cam_path newpath; 1961 1962 /* 1963 * We only need to handle events for real devices. 1964 */ 1965 if (target->target_id == CAM_TARGET_WILDCARD 1966 || device->lun_id == CAM_LUN_WILDCARD) 1967 return; 1968 1969 /* 1970 * We need our own path with wildcards expanded to 1971 * handle certain types of events. 1972 */ 1973 if ((async_code == AC_SENT_BDR) 1974 || (async_code == AC_BUS_RESET) 1975 || (async_code == AC_INQ_CHANGED)) 1976 status = xpt_compile_path(&newpath, NULL, 1977 bus->path_id, 1978 target->target_id, 1979 device->lun_id); 1980 else 1981 status = CAM_REQ_CMP_ERR; 1982 1983 if (status == CAM_REQ_CMP) { 1984 if (async_code == AC_INQ_CHANGED) { 1985 /* 1986 * We've sent a start unit command, or 1987 * something similar to a device that 1988 * may have caused its inquiry data to 1989 * change. So we re-scan the device to 1990 * refresh the inquiry data for it. 1991 */ 1992 ata_scan_lun(newpath.periph, &newpath, 1993 CAM_EXPECT_INQ_CHANGE, NULL); 1994 } else { 1995 /* We need to reinitialize device after reset. */ 1996 ata_scan_lun(newpath.periph, &newpath, 1997 0, NULL); 1998 } 1999 xpt_release_path(&newpath); 2000 } else if (async_code == AC_LOST_DEVICE && 2001 (device->flags & CAM_DEV_UNCONFIGURED) == 0) { 2002 device->flags |= CAM_DEV_UNCONFIGURED; 2003 xpt_release_device(device); 2004 } else if (async_code == AC_TRANSFER_NEG) { 2005 struct ccb_trans_settings *settings; 2006 2007 settings = (struct ccb_trans_settings *)async_arg; 2008 ata_set_transfer_settings(settings, device, 2009 /*async_update*/TRUE); 2010 } 2011} 2012 2013static void 2014ata_announce_periph(struct cam_periph *periph) 2015{ 2016 struct ccb_pathinq cpi; 2017 struct ccb_trans_settings cts; 2018 struct cam_path *path = periph->path; 2019 u_int speed; 2020 u_int mb; 2021 2022 mtx_assert(periph->sim->mtx, MA_OWNED); 2023 2024 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); 2025 cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 2026 cts.type = CTS_TYPE_CURRENT_SETTINGS; 2027 xpt_action((union ccb*)&cts); 2028 if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 2029 return; 2030 /* Ask the SIM for its base transfer speed */ 2031 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); 2032 cpi.ccb_h.func_code = XPT_PATH_INQ; 2033 xpt_action((union ccb *)&cpi); 2034 /* Report connection speed */ 2035 speed = cpi.base_transfer_speed; 2036 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) { 2037 struct ccb_trans_settings_pata *pata = 2038 &cts.xport_specific.ata; 2039 2040 if (pata->valid & CTS_ATA_VALID_MODE) 2041 speed = ata_mode2speed(pata->mode); 2042 } 2043 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { 2044 struct ccb_trans_settings_sata *sata = 2045 &cts.xport_specific.sata; 2046 2047 if (sata->valid & CTS_SATA_VALID_REVISION) 2048 speed = ata_revision2speed(sata->revision); 2049 } 2050 mb = speed / 1000; 2051 if (mb > 0) 2052 printf("%s%d: %d.%03dMB/s transfers", 2053 periph->periph_name, periph->unit_number, 2054 mb, speed % 1000); 2055 else 2056 printf("%s%d: %dKB/s transfers", periph->periph_name, 2057 periph->unit_number, speed); 2058 /* Report additional information about connection */ 2059 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) { 2060 struct ccb_trans_settings_pata *pata = 2061 &cts.xport_specific.ata; 2062 2063 printf(" ("); 2064 if (pata->valid & CTS_ATA_VALID_MODE) 2065 printf("%s, ", ata_mode2string(pata->mode)); 2066 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) 2067 printf("ATAPI %dbytes, ", pata->atapi); 2068 if (pata->valid & CTS_ATA_VALID_BYTECOUNT) 2069 printf("PIO %dbytes", pata->bytecount); 2070 printf(")"); 2071 } 2072 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { 2073 struct ccb_trans_settings_sata *sata = 2074 &cts.xport_specific.sata; 2075 2076 printf(" ("); 2077 if (sata->valid & CTS_SATA_VALID_REVISION) 2078 printf("SATA %d.x, ", sata->revision); 2079 else 2080 printf("SATA, "); 2081 if (sata->valid & CTS_SATA_VALID_MODE) 2082 printf("%s, ", ata_mode2string(sata->mode)); 2083 if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) 2084 printf("ATAPI %dbytes, ", sata->atapi); 2085 if (sata->valid & CTS_SATA_VALID_BYTECOUNT) 2086 printf("PIO %dbytes", sata->bytecount); 2087 printf(")"); 2088 } 2089 printf("\n"); 2090} 2091 2092