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 (BUS_PROBE_DEFAULT); 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 mtx_destroy(&enc->mtx); 90 return (ENXIO); 91 } 92 enc->capsem = ATA_INL(enc->r_memc, 0); 93 rid = 1; 94 if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 95 &rid, RF_ACTIVE))) { 96 error = ENXIO; 97 goto err0; 98 } 99 if ((enc->capsem & (AHCI_EM_XMT | AHCI_EM_SMB)) == 0) { 100 rid = 2; 101 if (!(enc->r_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 102 &rid, RF_ACTIVE))) { 103 error = ENXIO; 104 goto err0; 105 } 106 } else 107 enc->r_memr = NULL; 108 mtx_lock(&enc->mtx); 109 if (ahci_em_reset(dev) != 0) { 110 error = ENXIO; 111 goto err1; 112 } 113 rid = ATA_IRQ_RID; 114 /* Create the device queue for our SIM. */ 115 devq = cam_simq_alloc(1); 116 if (devq == NULL) { 117 device_printf(dev, "Unable to allocate SIM queue\n"); 118 error = ENOMEM; 119 goto err1; 120 } 121 /* Construct SIM entry */ 122 enc->sim = cam_sim_alloc(ahciemaction, ahciempoll, "ahciem", enc, 123 device_get_unit(dev), &enc->mtx, 124 1, 0, devq); 125 if (enc->sim == NULL) { 126 cam_simq_free(devq); 127 device_printf(dev, "Unable to allocate SIM\n"); 128 error = ENOMEM; 129 goto err1; 130 } 131 if (xpt_bus_register(enc->sim, dev, 0) != CAM_SUCCESS) { 132 device_printf(dev, "unable to register xpt bus\n"); 133 error = ENXIO; 134 goto err2; 135 } 136 if (xpt_create_path(&enc->path, /*periph*/NULL, cam_sim_path(enc->sim), 137 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 138 device_printf(dev, "Unable to create path\n"); 139 error = ENXIO; 140 goto err3; 141 } 142 mtx_unlock(&enc->mtx); 143 if (bootverbose) { 144 device_printf(dev, "Caps:%s%s%s%s%s%s%s%s\n", 145 (enc->capsem & AHCI_EM_PM) ? " PM":"", 146 (enc->capsem & AHCI_EM_ALHD) ? " ALHD":"", 147 (enc->capsem & AHCI_EM_XMT) ? " XMT":"", 148 (enc->capsem & AHCI_EM_SMB) ? " SMB":"", 149 (enc->capsem & AHCI_EM_SGPIO) ? " SGPIO":"", 150 (enc->capsem & AHCI_EM_SES2) ? " SES-2":"", 151 (enc->capsem & AHCI_EM_SAFTE) ? " SAF-TE":"", 152 (enc->capsem & AHCI_EM_LED) ? " LED":""); 153 } 154 if ((enc->capsem & AHCI_EM_LED)) { 155 for (c = 0; c < enc->channels; c++) { 156 if ((enc->ichannels & (1 << c)) == 0) 157 continue; 158 for (i = 0; i < AHCI_NUM_LEDS; i++) { 159 enc->leds[c * AHCI_NUM_LEDS + i].dev = dev; 160 enc->leds[c * AHCI_NUM_LEDS + i].num = 161 c * AHCI_NUM_LEDS + i; 162 } 163 if ((enc->capsem & AHCI_EM_ALHD) == 0) { 164 snprintf(buf, sizeof(buf), "%s.%d.act", 165 device_get_nameunit(parent), c); 166 enc->leds[c * AHCI_NUM_LEDS + 0].led = 167 led_create(ahci_em_led, 168 &enc->leds[c * AHCI_NUM_LEDS + 0], buf); 169 } 170 snprintf(buf, sizeof(buf), "%s.%d.locate", 171 device_get_nameunit(parent), c); 172 enc->leds[c * AHCI_NUM_LEDS + 1].led = 173 led_create(ahci_em_led, 174 &enc->leds[c * AHCI_NUM_LEDS + 1], buf); 175 snprintf(buf, sizeof(buf), "%s.%d.fault", 176 device_get_nameunit(parent), c); 177 enc->leds[c * AHCI_NUM_LEDS + 2].led = 178 led_create(ahci_em_led, 179 &enc->leds[c * AHCI_NUM_LEDS + 2], buf); 180 } 181 } 182 return (0); 183 184 err3: 185 xpt_bus_deregister(cam_sim_path(enc->sim)); 186 err2: 187 cam_sim_free(enc->sim, /*free_devq*/TRUE); 188 err1: 189 mtx_unlock(&enc->mtx); 190 if (enc->r_memr) 191 bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr); 192 err0: 193 if (enc->r_memt) 194 bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); 195 bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); 196 mtx_destroy(&enc->mtx); 197 return (error); 198 } 199 200 static int 201 ahci_em_detach(device_t dev) 202 { 203 struct ahci_enclosure *enc = device_get_softc(dev); 204 int i; 205 206 for (i = 0; i < enc->channels * AHCI_NUM_LEDS; i++) { 207 if (enc->leds[i].led) 208 led_destroy(enc->leds[i].led); 209 } 210 mtx_lock(&enc->mtx); 211 xpt_async(AC_LOST_DEVICE, enc->path, NULL); 212 xpt_free_path(enc->path); 213 xpt_bus_deregister(cam_sim_path(enc->sim)); 214 cam_sim_free(enc->sim, /*free_devq*/TRUE); 215 mtx_unlock(&enc->mtx); 216 217 bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); 218 bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); 219 if (enc->r_memr) 220 bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr); 221 mtx_destroy(&enc->mtx); 222 return (0); 223 } 224 225 static int 226 ahci_em_reset(device_t dev) 227 { 228 struct ahci_enclosure *enc; 229 int i, timeout; 230 231 enc = device_get_softc(dev); 232 ATA_OUTL(enc->r_memc, 0, AHCI_EM_RST); 233 timeout = 1000; 234 while ((ATA_INL(enc->r_memc, 0) & AHCI_EM_RST) && 235 --timeout > 0) 236 DELAY(1000); 237 if (timeout == 0) { 238 device_printf(dev, "EM timeout\n"); 239 return (1); 240 } 241 for (i = 0; i < enc->channels; i++) 242 ahci_em_setleds(dev, i); 243 return (0); 244 } 245 246 static int 247 ahci_em_suspend(device_t dev) 248 { 249 struct ahci_enclosure *enc = device_get_softc(dev); 250 251 mtx_lock(&enc->mtx); 252 xpt_freeze_simq(enc->sim, 1); 253 mtx_unlock(&enc->mtx); 254 return (0); 255 } 256 257 static int 258 ahci_em_resume(device_t dev) 259 { 260 struct ahci_enclosure *enc = device_get_softc(dev); 261 262 mtx_lock(&enc->mtx); 263 ahci_em_reset(dev); 264 xpt_release_simq(enc->sim, TRUE); 265 mtx_unlock(&enc->mtx); 266 return (0); 267 } 268 269 devclass_t ahciem_devclass; 270 static device_method_t ahciem_methods[] = { 271 DEVMETHOD(device_probe, ahci_em_probe), 272 DEVMETHOD(device_attach, ahci_em_attach), 273 DEVMETHOD(device_detach, ahci_em_detach), 274 DEVMETHOD(device_suspend, ahci_em_suspend), 275 DEVMETHOD(device_resume, ahci_em_resume), 276 DEVMETHOD_END 277 }; 278 static driver_t ahciem_driver = { 279 "ahciem", 280 ahciem_methods, 281 sizeof(struct ahci_enclosure) 282 }; 283 DRIVER_MODULE(ahciem, ahci, ahciem_driver, ahciem_devclass, NULL, NULL); 284 285 static void 286 ahci_em_setleds(device_t dev, int c) 287 { 288 struct ahci_enclosure *enc; 289 int timeout; 290 int16_t val; 291 292 enc = device_get_softc(dev); 293 294 val = 0; 295 if (enc->status[c][2] & 0x80) /* Activity */ 296 val |= (1 << 0); 297 if (enc->status[c][2] & SESCTL_RQSID) /* Identification */ 298 val |= (1 << 3); 299 else if (enc->status[c][3] & SESCTL_RQSFLT) /* Fault */ 300 val |= (1 << 6); 301 else if (enc->status[c][1] & 0x02) /* Rebuild */ 302 val |= (1 << 6) | (1 << 3); 303 304 timeout = 10000; 305 while (ATA_INL(enc->r_memc, 0) & (AHCI_EM_TM | AHCI_EM_RST) && 306 --timeout > 0) 307 DELAY(100); 308 if (timeout == 0) 309 device_printf(dev, "Transmit timeout\n"); 310 ATA_OUTL(enc->r_memt, 0, (1 << 8) | (0 << 16) | (0 << 24)); 311 ATA_OUTL(enc->r_memt, 4, c | (0 << 8) | (val << 16)); 312 ATA_OUTL(enc->r_memc, 0, AHCI_EM_TM); 313 } 314 315 static void 316 ahci_em_led(void *priv, int onoff) 317 { 318 struct ahci_led *led; 319 struct ahci_enclosure *enc; 320 int c, l; 321 322 led = (struct ahci_led *)priv; 323 enc = device_get_softc(led->dev); 324 c = led->num / AHCI_NUM_LEDS; 325 l = led->num % AHCI_NUM_LEDS; 326 327 if (l == 0) { 328 if (onoff) 329 enc->status[c][2] |= 0x80; 330 else 331 enc->status[c][2] &= ~0x80; 332 } else if (l == 1) { 333 if (onoff) 334 enc->status[c][2] |= SESCTL_RQSID; 335 else 336 enc->status[c][2] &= ~SESCTL_RQSID; 337 } else if (l == 2) { 338 if (onoff) 339 enc->status[c][3] |= SESCTL_RQSFLT; 340 else 341 enc->status[c][3] &= SESCTL_RQSFLT; 342 } 343 ahci_em_setleds(led->dev, c); 344 } 345 346 static int 347 ahci_check_ids(union ccb *ccb) 348 { 349 350 if (ccb->ccb_h.target_id != 0) { 351 ccb->ccb_h.status = CAM_TID_INVALID; 352 xpt_done(ccb); 353 return (-1); 354 } 355 if (ccb->ccb_h.target_lun != 0) { 356 ccb->ccb_h.status = CAM_LUN_INVALID; 357 xpt_done(ccb); 358 return (-1); 359 } 360 return (0); 361 } 362 363 static void 364 ahci_em_emulate_ses_on_led(device_t dev, union ccb *ccb) 365 { 366 struct ahci_enclosure *enc; 367 struct ses_status_page *page; 368 struct ses_status_array_dev_slot *ads, *ads0; 369 struct ses_elm_desc_hdr *elmd; 370 uint8_t *buf; 371 int i; 372 373 enc = device_get_softc(dev); 374 buf = ccb->ataio.data_ptr; 375 376 /* General request validation. */ 377 if (ccb->ataio.cmd.command != ATA_SEP_ATTN || 378 ccb->ataio.dxfer_len < ccb->ataio.cmd.sector_count * 4) { 379 ccb->ccb_h.status = CAM_REQ_INVALID; 380 goto out; 381 } 382 383 /* SEMB IDENTIFY */ 384 if (ccb->ataio.cmd.features == 0xEC && 385 ccb->ataio.cmd.sector_count >= 16) { 386 bzero(buf, ccb->ataio.dxfer_len); 387 buf[0] = 64; /* Valid bytes. */ 388 buf[2] = 0x30; /* NAA Locally Assigned. */ 389 strncpy(&buf[3], device_get_nameunit(dev), 7); 390 strncpy(&buf[10], "AHCI ", SID_VENDOR_SIZE); 391 strncpy(&buf[18], "SGPIO Enclosure ", SID_PRODUCT_SIZE); 392 strncpy(&buf[34], "1.00", SID_REVISION_SIZE); 393 strncpy(&buf[39], "0001", 4); 394 strncpy(&buf[43], "S-E-S ", 6); 395 strncpy(&buf[49], "2.00", 4); 396 ccb->ccb_h.status = CAM_REQ_CMP; 397 goto out; 398 } 399 400 /* SEMB RECEIVE DIAGNOSTIC RESULT (0) */ 401 page = (struct ses_status_page *)buf; 402 if (ccb->ataio.cmd.lba_low == 0x02 && 403 ccb->ataio.cmd.features == 0x00 && 404 ccb->ataio.cmd.sector_count >= 2) { 405 bzero(buf, ccb->ataio.dxfer_len); 406 page->hdr.page_code = 0; 407 scsi_ulto2b(4, page->hdr.length); 408 buf[4] = 0; 409 buf[5] = 1; 410 buf[6] = 2; 411 buf[7] = 7; 412 ccb->ccb_h.status = CAM_REQ_CMP; 413 goto out; 414 } 415 416 /* SEMB RECEIVE DIAGNOSTIC RESULT (1) */ 417 if (ccb->ataio.cmd.lba_low == 0x02 && 418 ccb->ataio.cmd.features == 0x01 && 419 ccb->ataio.cmd.sector_count >= 13) { 420 struct ses_enc_desc *ed; 421 struct ses_elm_type_desc *td; 422 423 bzero(buf, ccb->ataio.dxfer_len); 424 page->hdr.page_code = 0x01; 425 scsi_ulto2b(4 + 4 + 36 + 4, page->hdr.length); 426 ed = (struct ses_enc_desc *)&buf[8]; 427 ed->byte0 = 0x11; 428 ed->subenc_id = 0; 429 ed->num_types = 1; 430 ed->length = 36; 431 strncpy(ed->vendor_id, "AHCI ", SID_VENDOR_SIZE); 432 strncpy(ed->product_id, "SGPIO Enclosure ", SID_PRODUCT_SIZE); 433 strncpy(ed->product_rev, " ", SID_REVISION_SIZE); 434 td = (struct ses_elm_type_desc *)ses_enc_desc_next(ed); 435 td->etype_elm_type = 0x17; 436 td->etype_maxelt = enc->channels; 437 td->etype_subenc = 0; 438 td->etype_txt_len = 0; 439 ccb->ccb_h.status = CAM_REQ_CMP; 440 goto out; 441 } 442 443 /* SEMB RECEIVE DIAGNOSTIC RESULT (2) */ 444 if (ccb->ataio.cmd.lba_low == 0x02 && 445 ccb->ataio.cmd.features == 0x02 && 446 ccb->ataio.cmd.sector_count >= (3 + enc->channels)) { 447 bzero(buf, ccb->ataio.dxfer_len); 448 page->hdr.page_code = 0x02; 449 scsi_ulto2b(4 + 4 * (1 + enc->channels), 450 page->hdr.length); 451 for (i = 0; i < enc->channels; i++) { 452 ads = &page->elements[i + 1].array_dev_slot; 453 memcpy(ads, enc->status[i], 4); 454 ads->common.bytes[0] |= 455 (enc->ichannels & (1 << i)) ? 456 SES_OBJSTAT_UNKNOWN : 457 SES_OBJSTAT_NOTINSTALLED; 458 } 459 ccb->ccb_h.status = CAM_REQ_CMP; 460 goto out; 461 } 462 463 /* SEMB SEND DIAGNOSTIC (2) */ 464 if (ccb->ataio.cmd.lba_low == 0x82 && 465 ccb->ataio.cmd.features == 0x02 && 466 ccb->ataio.cmd.sector_count >= (3 + enc->channels)) { 467 ads0 = &page->elements[0].array_dev_slot; 468 for (i = 0; i < enc->channels; i++) { 469 ads = &page->elements[i + 1].array_dev_slot; 470 if (ads->common.bytes[0] & SESCTL_CSEL) { 471 enc->status[i][0] = 0; 472 enc->status[i][1] = 473 ads->bytes[0] & 0x02; 474 enc->status[i][2] = 475 ads->bytes[1] & (0x80 | SESCTL_RQSID); 476 enc->status[i][3] = 477 ads->bytes[2] & SESCTL_RQSFLT; 478 ahci_em_setleds(dev, i); 479 } else if (ads0->common.bytes[0] & SESCTL_CSEL) { 480 enc->status[i][0] = 0; 481 enc->status[i][1] = 482 ads0->bytes[0] & 0x02; 483 enc->status[i][2] = 484 ads0->bytes[1] & (0x80 | SESCTL_RQSID); 485 enc->status[i][3] = 486 ads0->bytes[2] & SESCTL_RQSFLT; 487 ahci_em_setleds(dev, i); 488 } 489 } 490 ccb->ccb_h.status = CAM_REQ_CMP; 491 goto out; 492 } 493 494 /* SEMB RECEIVE DIAGNOSTIC RESULT (7) */ 495 if (ccb->ataio.cmd.lba_low == 0x02 && 496 ccb->ataio.cmd.features == 0x07 && 497 ccb->ataio.cmd.sector_count >= (3 + 3 * enc->channels)) { 498 bzero(buf, ccb->ataio.dxfer_len); 499 page->hdr.page_code = 0x07; 500 scsi_ulto2b(4 + 4 + 12 * enc->channels, 501 page->hdr.length); 502 for (i = 0; i < enc->channels; i++) { 503 elmd = (struct ses_elm_desc_hdr *)&buf[8 + 4 + 12 * i]; 504 scsi_ulto2b(8, elmd->length); 505 snprintf((char *)(elmd + 1), 9, "SLOT %03d", i); 506 } 507 ccb->ccb_h.status = CAM_REQ_CMP; 508 goto out; 509 } 510 511 ccb->ccb_h.status = CAM_REQ_INVALID; 512 out: 513 xpt_done(ccb); 514 } 515 516 static void 517 ahci_em_begin_transaction(device_t dev, union ccb *ccb) 518 { 519 struct ahci_enclosure *enc; 520 struct ata_res *res; 521 522 enc = device_get_softc(dev); 523 res = &ccb->ataio.res; 524 bzero(res, sizeof(*res)); 525 if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && 526 (ccb->ataio.cmd.control & ATA_A_RESET)) { 527 res->lba_high = 0xc3; 528 res->lba_mid = 0x3c; 529 ccb->ccb_h.status = CAM_REQ_CMP; 530 xpt_done(ccb); 531 return; 532 } 533 534 if (enc->capsem & AHCI_EM_LED) { 535 ahci_em_emulate_ses_on_led(dev, ccb); 536 return; 537 } else 538 device_printf(dev, "Unsupported enclosure interface\n"); 539 540 ccb->ccb_h.status = CAM_REQ_INVALID; 541 xpt_done(ccb); 542 } 543 544 static void 545 ahciemaction(struct cam_sim *sim, union ccb *ccb) 546 { 547 device_t dev, parent; 548 struct ahci_enclosure *enc; 549 550 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 551 ("ahciemaction func_code=%x\n", ccb->ccb_h.func_code)); 552 553 enc = cam_sim_softc(sim); 554 dev = enc->dev; 555 switch (ccb->ccb_h.func_code) { 556 case XPT_ATA_IO: /* Execute the requested I/O operation */ 557 if (ahci_check_ids(ccb)) 558 return; 559 ahci_em_begin_transaction(dev, ccb); 560 return; 561 case XPT_RESET_BUS: /* Reset the specified bus */ 562 case XPT_RESET_DEV: /* Bus Device Reset the specified device */ 563 ahci_em_reset(dev); 564 ccb->ccb_h.status = CAM_REQ_CMP; 565 break; 566 case XPT_PATH_INQ: /* Path routing inquiry */ 567 { 568 struct ccb_pathinq *cpi = &ccb->cpi; 569 570 parent = device_get_parent(dev); 571 cpi->version_num = 1; /* XXX??? */ 572 cpi->hba_inquiry = PI_SDTR_ABLE; 573 cpi->target_sprt = 0; 574 cpi->hba_misc = PIM_SEQSCAN; 575 cpi->hba_eng_cnt = 0; 576 cpi->max_target = 0; 577 cpi->max_lun = 0; 578 cpi->initiator_id = 0; 579 cpi->bus_id = cam_sim_bus(sim); 580 cpi->base_transfer_speed = 150000; 581 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 582 strncpy(cpi->hba_vid, "AHCI", HBA_IDLEN); 583 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 584 cpi->unit_number = cam_sim_unit(sim); 585 cpi->transport = XPORT_SATA; 586 cpi->transport_version = XPORT_VERSION_UNSPECIFIED; 587 cpi->protocol = PROTO_ATA; 588 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; 589 cpi->maxio = MAXPHYS; 590 cpi->hba_vendor = pci_get_vendor(parent); 591 cpi->hba_device = pci_get_device(parent); 592 cpi->hba_subvendor = pci_get_subvendor(parent); 593 cpi->hba_subdevice = pci_get_subdevice(parent); 594 cpi->ccb_h.status = CAM_REQ_CMP; 595 break; 596 } 597 default: 598 ccb->ccb_h.status = CAM_REQ_INVALID; 599 break; 600 } 601 xpt_done(ccb); 602 } 603 604 static void 605 ahciempoll(struct cam_sim *sim) 606 { 607 608 } 609