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