1 /*- 2 * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/module.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/bus.h> 35 #include <sys/conf.h> 36 #include <sys/endian.h> 37 #include <sys/malloc.h> 38 #include <sys/lock.h> 39 #include <sys/mutex.h> 40 #include <machine/stdarg.h> 41 #include <machine/resource.h> 42 #include <machine/bus.h> 43 #include <sys/rman.h> 44 #include <dev/led/led.h> 45 #include <dev/pci/pcivar.h> 46 #include <dev/pci/pcireg.h> 47 #include "ahci.h" 48 49 #include <cam/cam.h> 50 #include <cam/cam_ccb.h> 51 #include <cam/cam_sim.h> 52 #include <cam/cam_xpt_sim.h> 53 #include <cam/cam_debug.h> 54 #include <cam/scsi/scsi_ses.h> 55 56 /* local prototypes */ 57 static void ahciemaction(struct cam_sim *sim, union ccb *ccb); 58 static void ahciempoll(struct cam_sim *sim); 59 static int ahci_em_reset(device_t dev); 60 static void ahci_em_led(void *priv, int onoff); 61 static void ahci_em_setleds(device_t dev, int c); 62 63 static int 64 ahci_em_probe(device_t dev) 65 { 66 67 device_set_desc_copy(dev, "AHCI enclosure management bridge"); 68 return (0); 69 } 70 71 static int 72 ahci_em_attach(device_t dev) 73 { 74 device_t parent = device_get_parent(dev); 75 struct ahci_controller *ctlr = device_get_softc(parent); 76 struct ahci_enclosure *enc = device_get_softc(dev); 77 struct cam_devq *devq; 78 int i, c, rid, error; 79 char buf[32]; 80 81 enc->dev = dev; 82 enc->quirks = ctlr->quirks; 83 enc->channels = ctlr->channels; 84 enc->ichannels = ctlr->ichannels; 85 mtx_init(&enc->mtx, "AHCI enclosure lock", NULL, MTX_DEF); 86 rid = 0; 87 if (!(enc->r_memc = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 88 &rid, RF_ACTIVE))) 89 return (ENXIO); 90 enc->capsem = ATA_INL(enc->r_memc, 0); 91 rid = 1; 92 if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 93 &rid, RF_ACTIVE))) { 94 error = ENXIO; 95 goto err0; 96 } 97 if ((enc->capsem & (AHCI_EM_XMT | AHCI_EM_SMB)) == 0) { 98 rid = 2; 99 if (!(enc->r_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 100 &rid, RF_ACTIVE))) { 101 error = ENXIO; 102 goto err0; 103 } 104 } else 105 enc->r_memr = NULL; 106 mtx_lock(&enc->mtx); 107 ahci_em_reset(dev); 108 rid = ATA_IRQ_RID; 109 /* Create the device queue for our SIM. */ 110 devq = cam_simq_alloc(1); 111 if (devq == NULL) { 112 device_printf(dev, "Unable to allocate SIM queue\n"); 113 error = ENOMEM; 114 goto err1; 115 } 116 /* Construct SIM entry */ 117 enc->sim = cam_sim_alloc(ahciemaction, ahciempoll, "ahciem", enc, 118 device_get_unit(dev), &enc->mtx, 119 1, 0, devq); 120 if (enc->sim == NULL) { 121 cam_simq_free(devq); 122 device_printf(dev, "Unable to allocate SIM\n"); 123 error = ENOMEM; 124 goto err1; 125 } 126 if (xpt_bus_register(enc->sim, dev, 0) != CAM_SUCCESS) { 127 device_printf(dev, "unable to register xpt bus\n"); 128 error = ENXIO; 129 goto err2; 130 } 131 if (xpt_create_path(&enc->path, /*periph*/NULL, cam_sim_path(enc->sim), 132 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 133 device_printf(dev, "Unable to create path\n"); 134 error = ENXIO; 135 goto err3; 136 } 137 mtx_unlock(&enc->mtx); 138 if (bootverbose) { 139 device_printf(dev, "Caps:%s%s%s%s%s%s%s%s\n", 140 (enc->capsem & AHCI_EM_PM) ? " PM":"", 141 (enc->capsem & AHCI_EM_ALHD) ? " ALHD":"", 142 (enc->capsem & AHCI_EM_XMT) ? " XMT":"", 143 (enc->capsem & AHCI_EM_SMB) ? " SMB":"", 144 (enc->capsem & AHCI_EM_SGPIO) ? " SGPIO":"", 145 (enc->capsem & AHCI_EM_SES2) ? " SES-2":"", 146 (enc->capsem & AHCI_EM_SAFTE) ? " SAF-TE":"", 147 (enc->capsem & AHCI_EM_LED) ? " LED":""); 148 } 149 if ((enc->capsem & AHCI_EM_LED)) { 150 for (c = 0; c < enc->channels; c++) { 151 if ((enc->ichannels & (1 << c)) == 0) 152 continue; 153 for (i = 0; i < AHCI_NUM_LEDS; i++) { 154 enc->leds[c * AHCI_NUM_LEDS + i].dev = dev; 155 enc->leds[c * AHCI_NUM_LEDS + i].num = 156 c * AHCI_NUM_LEDS + i; 157 } 158 if ((enc->capsem & AHCI_EM_ALHD) == 0) { 159 snprintf(buf, sizeof(buf), "%s.%d.act", 160 device_get_nameunit(parent), c); 161 enc->leds[c * AHCI_NUM_LEDS + 0].led = 162 led_create(ahci_em_led, 163 &enc->leds[c * AHCI_NUM_LEDS + 0], buf); 164 } 165 snprintf(buf, sizeof(buf), "%s.%d.locate", 166 device_get_nameunit(parent), c); 167 enc->leds[c * AHCI_NUM_LEDS + 1].led = 168 led_create(ahci_em_led, 169 &enc->leds[c * AHCI_NUM_LEDS + 1], buf); 170 snprintf(buf, sizeof(buf), "%s.%d.fault", 171 device_get_nameunit(parent), c); 172 enc->leds[c * AHCI_NUM_LEDS + 2].led = 173 led_create(ahci_em_led, 174 &enc->leds[c * AHCI_NUM_LEDS + 2], buf); 175 } 176 } 177 return (0); 178 179 err3: 180 xpt_bus_deregister(cam_sim_path(enc->sim)); 181 err2: 182 cam_sim_free(enc->sim, /*free_devq*/TRUE); 183 err1: 184 mtx_unlock(&enc->mtx); 185 if (enc->r_memr) 186 bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr); 187 err0: 188 if (enc->r_memt) 189 bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); 190 bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); 191 mtx_destroy(&enc->mtx); 192 return (error); 193 } 194 195 static int 196 ahci_em_detach(device_t dev) 197 { 198 struct ahci_enclosure *enc = device_get_softc(dev); 199 int i; 200 201 for (i = 0; i < enc->channels * AHCI_NUM_LEDS; i++) { 202 if (enc->leds[i].led) 203 led_destroy(enc->leds[i].led); 204 } 205 mtx_lock(&enc->mtx); 206 xpt_async(AC_LOST_DEVICE, enc->path, NULL); 207 xpt_free_path(enc->path); 208 xpt_bus_deregister(cam_sim_path(enc->sim)); 209 cam_sim_free(enc->sim, /*free_devq*/TRUE); 210 mtx_unlock(&enc->mtx); 211 212 bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); 213 bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); 214 if (enc->r_memr) 215 bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr); 216 mtx_destroy(&enc->mtx); 217 return (0); 218 } 219 220 static int 221 ahci_em_reset(device_t dev) 222 { 223 struct ahci_enclosure *enc; 224 int i, timeout; 225 226 enc = device_get_softc(dev); 227 ATA_OUTL(enc->r_memc, 0, AHCI_EM_RST); 228 timeout = 1000; 229 while ((ATA_INL(enc->r_memc, 0) & AHCI_EM_RST) && 230 --timeout > 0) 231 DELAY(1000); 232 if (timeout == 0) { 233 device_printf(dev, "EM timeout\n"); 234 return (1); 235 } 236 for (i = 0; i < enc->channels; i++) 237 ahci_em_setleds(dev, i); 238 return (0); 239 } 240 241 static int 242 ahci_em_suspend(device_t dev) 243 { 244 struct ahci_enclosure *enc = device_get_softc(dev); 245 246 mtx_lock(&enc->mtx); 247 xpt_freeze_simq(enc->sim, 1); 248 mtx_unlock(&enc->mtx); 249 return (0); 250 } 251 252 static int 253 ahci_em_resume(device_t dev) 254 { 255 struct ahci_enclosure *enc = device_get_softc(dev); 256 257 mtx_lock(&enc->mtx); 258 ahci_em_reset(dev); 259 xpt_release_simq(enc->sim, TRUE); 260 mtx_unlock(&enc->mtx); 261 return (0); 262 } 263 264 devclass_t ahciem_devclass; 265 static device_method_t ahciem_methods[] = { 266 DEVMETHOD(device_probe, ahci_em_probe), 267 DEVMETHOD(device_attach, ahci_em_attach), 268 DEVMETHOD(device_detach, ahci_em_detach), 269 DEVMETHOD(device_suspend, ahci_em_suspend), 270 DEVMETHOD(device_resume, ahci_em_resume), 271 { 0, 0 } 272 }; 273 static driver_t ahciem_driver = { 274 "ahciem", 275 ahciem_methods, 276 sizeof(struct ahci_enclosure) 277 }; 278 DRIVER_MODULE(ahciem, ahci, ahciem_driver, ahciem_devclass, 0, 0); 279 280 static void 281 ahci_em_setleds(device_t dev, int c) 282 { 283 struct ahci_enclosure *enc; 284 int timeout; 285 int16_t val; 286 287 enc = device_get_softc(dev); 288 289 val = 0; 290 if (enc->status[c][2] & 0x80) /* Activity */ 291 val |= (1 << 0); 292 if (enc->status[c][2] & SESCTL_RQSID) /* Identification */ 293 val |= (1 << 3); 294 else if (enc->status[c][3] & SESCTL_RQSFLT) /* Fault */ 295 val |= (1 << 6); 296 else if (enc->status[c][1] & 0x02) /* Rebuild */ 297 val |= (1 << 6) | (1 << 3); 298 299 timeout = 10000; 300 while (ATA_INL(enc->r_memc, 0) & (AHCI_EM_TM | AHCI_EM_RST) && 301 --timeout > 0) 302 DELAY(100); 303 if (timeout == 0) 304 device_printf(dev, "Transmit timeout\n"); 305 ATA_OUTL(enc->r_memt, 0, (1 << 8) | (0 << 16) | (0 << 24)); 306 ATA_OUTL(enc->r_memt, 4, c | (0 << 8) | (val << 16)); 307 ATA_OUTL(enc->r_memc, 0, AHCI_EM_TM); 308 } 309 310 static void 311 ahci_em_led(void *priv, int onoff) 312 { 313 struct ahci_led *led; 314 struct ahci_enclosure *enc; 315 int c, l; 316 317 led = (struct ahci_led *)priv; 318 enc = device_get_softc(led->dev); 319 c = led->num / AHCI_NUM_LEDS; 320 l = led->num % AHCI_NUM_LEDS; 321 322 if (l == 0) { 323 if (onoff) 324 enc->status[c][2] |= 0x80; 325 else 326 enc->status[c][2] &= ~0x80; 327 } else if (l == 1) { 328 if (onoff) 329 enc->status[c][2] |= SESCTL_RQSID; 330 else 331 enc->status[c][2] &= ~SESCTL_RQSID; 332 } else if (l == 2) { 333 if (onoff) 334 enc->status[c][3] |= SESCTL_RQSFLT; 335 else 336 enc->status[c][3] &= SESCTL_RQSFLT; 337 } 338 ahci_em_setleds(led->dev, c); 339 } 340 341 static int 342 ahci_check_ids(device_t dev, union ccb *ccb) 343 { 344 345 if (ccb->ccb_h.target_id != 0) { 346 ccb->ccb_h.status = CAM_TID_INVALID; 347 xpt_done(ccb); 348 return (-1); 349 } 350 if (ccb->ccb_h.target_lun != 0) { 351 ccb->ccb_h.status = CAM_LUN_INVALID; 352 xpt_done(ccb); 353 return (-1); 354 } 355 return (0); 356 } 357 358 static void 359 ahci_em_emulate_ses_on_led(device_t dev, union ccb *ccb) 360 { 361 struct ahci_enclosure *enc; 362 struct ses_status_page *page; 363 struct ses_status_array_dev_slot *ads, *ads0; 364 struct ses_elm_desc_hdr *elmd; 365 uint8_t *buf; 366 int i; 367 368 enc = device_get_softc(dev); 369 buf = ccb->ataio.data_ptr; 370 371 /* General request validation. */ 372 if (ccb->ataio.cmd.command != ATA_SEP_ATTN || 373 ccb->ataio.dxfer_len < ccb->ataio.cmd.sector_count * 4) { 374 ccb->ccb_h.status = CAM_REQ_INVALID; 375 goto out; 376 } 377 378 /* SEMB IDENTIFY */ 379 if (ccb->ataio.cmd.features == 0xEC && 380 ccb->ataio.cmd.sector_count >= 16) { 381 bzero(buf, ccb->ataio.dxfer_len); 382 buf[0] = 64; /* Valid bytes. */ 383 buf[2] = 0x30; /* NAA Locally Assigned. */ 384 strncpy(&buf[3], device_get_nameunit(dev), 7); 385 strncpy(&buf[10], "AHCI ", SID_VENDOR_SIZE); 386 strncpy(&buf[18], "SGPIO Enclosure ", SID_PRODUCT_SIZE); 387 strncpy(&buf[34], "1.00", SID_REVISION_SIZE); 388 strncpy(&buf[39], "0001", 4); 389 strncpy(&buf[43], "S-E-S ", 6); 390 strncpy(&buf[49], "2.00", 4); 391 ccb->ccb_h.status = CAM_REQ_CMP; 392 goto out; 393 } 394 395 /* SEMB RECEIVE DIAGNOSTIC RESULT (0) */ 396 page = (struct ses_status_page *)buf; 397 if (ccb->ataio.cmd.lba_low == 0x02 && 398 ccb->ataio.cmd.features == 0x00 && 399 ccb->ataio.cmd.sector_count >= 2) { 400 bzero(buf, ccb->ataio.dxfer_len); 401 page->hdr.page_code = 0; 402 scsi_ulto2b(3, page->hdr.length); 403 buf[4] = 0; 404 buf[5] = 1; 405 buf[6] = 2; 406 ccb->ccb_h.status = CAM_REQ_CMP; 407 goto out; 408 } 409 410 /* SEMB RECEIVE DIAGNOSTIC RESULT (1) */ 411 if (ccb->ataio.cmd.lba_low == 0x02 && 412 ccb->ataio.cmd.features == 0x01 && 413 ccb->ataio.cmd.sector_count >= 13) { 414 struct ses_enc_desc *ed; 415 struct ses_elm_type_desc *td; 416 417 bzero(buf, ccb->ataio.dxfer_len); 418 page->hdr.page_code = 0x01; 419 scsi_ulto2b(4 + 4 + 36 + 4, page->hdr.length); 420 ed = (struct ses_enc_desc *)&buf[8]; 421 ed->byte0 = 0x11; 422 ed->subenc_id = 0; 423 ed->num_types = 1; 424 ed->length = 36; 425 strncpy(ed->vendor_id, "AHCI ", SID_VENDOR_SIZE); 426 strncpy(ed->product_id, "SGPIO Enclosure ", SID_PRODUCT_SIZE); 427 strncpy(ed->product_rev, " ", SID_REVISION_SIZE); 428 td = (struct ses_elm_type_desc *)ses_enc_desc_next(ed); 429 td->etype_elm_type = 0x17; 430 td->etype_maxelt = enc->channels; 431 td->etype_subenc = 0; 432 td->etype_txt_len = 0; 433 ccb->ccb_h.status = CAM_REQ_CMP; 434 goto out; 435 } 436 437 /* SEMB RECEIVE DIAGNOSTIC RESULT (2) */ 438 if (ccb->ataio.cmd.lba_low == 0x02 && 439 ccb->ataio.cmd.features == 0x02 && 440 ccb->ataio.cmd.sector_count >= (3 + enc->channels)) { 441 bzero(buf, ccb->ataio.dxfer_len); 442 page->hdr.page_code = 0x02; 443 scsi_ulto2b(4 + 4 * (1 + enc->channels), 444 page->hdr.length); 445 for (i = 0; i < enc->channels; i++) { 446 ads = &page->elements[i + 1].array_dev_slot; 447 memcpy(ads, enc->status[i], 4); 448 ads->common.bytes[0] |= 449 (enc->ichannels & (1 << i)) ? 450 SES_OBJSTAT_UNKNOWN : 451 SES_OBJSTAT_NOTINSTALLED; 452 } 453 ccb->ccb_h.status = CAM_REQ_CMP; 454 goto out; 455 } 456 457 /* SEMB SEND DIAGNOSTIC (2) */ 458 if (ccb->ataio.cmd.lba_low == 0x82 && 459 ccb->ataio.cmd.features == 0x02 && 460 ccb->ataio.cmd.sector_count >= (3 + enc->channels)) { 461 ads0 = &page->elements[0].array_dev_slot; 462 for (i = 0; i < enc->channels; i++) { 463 ads = &page->elements[i + 1].array_dev_slot; 464 if (ads->common.bytes[0] & SESCTL_CSEL) { 465 enc->status[i][0] = 0; 466 enc->status[i][1] = 467 ads->bytes[0] & 0x02; 468 enc->status[i][2] = 469 ads->bytes[1] & (0x80 | SESCTL_RQSID); 470 enc->status[i][3] = 471 ads->bytes[2] & SESCTL_RQSFLT; 472 ahci_em_setleds(dev, i); 473 } else if (ads0->common.bytes[0] & SESCTL_CSEL) { 474 enc->status[i][0] = 0; 475 enc->status[i][1] = 476 ads0->bytes[0] & 0x02; 477 enc->status[i][2] = 478 ads0->bytes[1] & (0x80 | SESCTL_RQSID); 479 enc->status[i][3] = 480 ads0->bytes[2] & SESCTL_RQSFLT; 481 ahci_em_setleds(dev, i); 482 } 483 } 484 ccb->ccb_h.status = CAM_REQ_CMP; 485 goto out; 486 } 487 488 /* SEMB RECEIVE DIAGNOSTIC RESULT (7) */ 489 if (ccb->ataio.cmd.lba_low == 0x02 && 490 ccb->ataio.cmd.features == 0x07 && 491 ccb->ataio.cmd.sector_count >= (3 + 3 * enc->channels)) { 492 bzero(buf, ccb->ataio.dxfer_len); 493 page->hdr.page_code = 0x07; 494 scsi_ulto2b(4 + 4 + 12 * enc->channels, 495 page->hdr.length); 496 for (i = 0; i < enc->channels; i++) { 497 elmd = (struct ses_elm_desc_hdr *)&buf[8 + 4 + 12 * i]; 498 scsi_ulto2b(8, elmd->length); 499 snprintf((char *)(elmd + 1), 9, "SLOT %03d", i); 500 } 501 ccb->ccb_h.status = CAM_REQ_CMP; 502 goto out; 503 } 504 505 ccb->ccb_h.status = CAM_REQ_INVALID; 506 out: 507 xpt_done(ccb); 508 } 509 510 static void 511 ahci_em_begin_transaction(device_t dev, union ccb *ccb) 512 { 513 struct ahci_enclosure *enc; 514 struct ata_res *res; 515 516 enc = device_get_softc(dev); 517 res = &ccb->ataio.res; 518 bzero(res, sizeof(*res)); 519 if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && 520 (ccb->ataio.cmd.control & ATA_A_RESET)) { 521 res->lba_high = 0xc3; 522 res->lba_mid = 0x3c; 523 ccb->ccb_h.status = CAM_REQ_CMP; 524 xpt_done(ccb); 525 return; 526 } 527 528 if (enc->capsem & AHCI_EM_LED) { 529 ahci_em_emulate_ses_on_led(dev, ccb); 530 return; 531 } else 532 device_printf(dev, "Unsupported enclosure interface\n"); 533 534 ccb->ccb_h.status = CAM_REQ_INVALID; 535 xpt_done(ccb); 536 } 537 538 static void 539 ahciemaction(struct cam_sim *sim, union ccb *ccb) 540 { 541 device_t dev, parent; 542 struct ahci_enclosure *enc; 543 544 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 545 ("ahciemaction func_code=%x\n", ccb->ccb_h.func_code)); 546 547 enc = cam_sim_softc(sim); 548 dev = enc->dev; 549 switch (ccb->ccb_h.func_code) { 550 case XPT_ATA_IO: /* Execute the requested I/O operation */ 551 if (ahci_check_ids(dev, ccb)) 552 return; 553 ahci_em_begin_transaction(dev, ccb); 554 return; 555 case XPT_RESET_BUS: /* Reset the specified bus */ 556 case XPT_RESET_DEV: /* Bus Device Reset the specified device */ 557 ahci_em_reset(dev); 558 ccb->ccb_h.status = CAM_REQ_CMP; 559 break; 560 case XPT_PATH_INQ: /* Path routing inquiry */ 561 { 562 struct ccb_pathinq *cpi = &ccb->cpi; 563 564 parent = device_get_parent(dev); 565 cpi->version_num = 1; /* XXX??? */ 566 cpi->hba_inquiry = PI_SDTR_ABLE; 567 cpi->target_sprt = 0; 568 cpi->hba_misc = PIM_SEQSCAN; 569 cpi->hba_eng_cnt = 0; 570 cpi->max_target = 0; 571 cpi->max_lun = 0; 572 cpi->initiator_id = 0; 573 cpi->bus_id = cam_sim_bus(sim); 574 cpi->base_transfer_speed = 150000; 575 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 576 strncpy(cpi->hba_vid, "AHCI", HBA_IDLEN); 577 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 578 cpi->unit_number = cam_sim_unit(sim); 579 cpi->transport = XPORT_SATA; 580 cpi->transport_version = XPORT_VERSION_UNSPECIFIED; 581 cpi->protocol = PROTO_ATA; 582 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; 583 cpi->maxio = MAXPHYS; 584 cpi->hba_vendor = pci_get_vendor(parent); 585 cpi->hba_device = pci_get_device(parent); 586 cpi->hba_subvendor = pci_get_subvendor(parent); 587 cpi->hba_subdevice = pci_get_subdevice(parent); 588 cpi->ccb_h.status = CAM_REQ_CMP; 589 break; 590 } 591 default: 592 ccb->ccb_h.status = CAM_REQ_INVALID; 593 break; 594 } 595 xpt_done(ccb); 596 } 597 598 static void 599 ahciempoll(struct cam_sim *sim) 600 { 601 602 } 603