atapi-cam.c revision 101637
1/*- 2 * Copyright (c) 2001,2002 Thomas Quinot <thomas@cuivre.fr.eu.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 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD: head/sys/dev/ata/atapi-cam.c 101637 2002-08-10 11:56:03Z sos $ 29 */ 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/devicestat.h> 35#include <sys/kernel.h> 36#include <sys/malloc.h> 37#include <sys/ata.h> 38#include <machine/bus.h> 39 40#include <cam/cam.h> 41#include <cam/cam_ccb.h> 42#include <cam/cam_periph.h> 43#include <cam/cam_sim.h> 44#include <cam/cam_xpt_sim.h> 45#include <cam/cam_debug.h> 46#include <cam/scsi/scsi_all.h> 47 48#include <dev/ata/ata-all.h> 49#include <dev/ata/atapi-all.h> 50 51/* hardware command descriptor block */ 52struct atapi_hcb { 53 struct atapi_xpt_softc *softc; 54 int unit; 55 int bus; 56 int target; 57 int lun; 58 union ccb *ccb; 59 u_int8_t cmd[CAM_MAX_CDBLEN]; 60 int lags; 61#define DOING_AUTOSENSE 1 62 63 char *dxfer_alloc; 64 TAILQ_ENTRY(atapi_hcb) chain; 65}; 66 67/* private data associated with an ATA bus */ 68struct atapi_xpt_softc { 69 struct ata_channel *ata_ch; 70 struct cam_path *path; 71 struct cam_sim *sim; 72 int flags; 73#define BUS_REGISTERED 0x01 74#define RESOURCE_SHORTAGE 0x02 75 76 TAILQ_HEAD(,atapi_hcb) pending_hcbs; 77 LIST_ENTRY(atapi_xpt_softc) chain; 78}; 79 80static LIST_HEAD(,atapi_xpt_softc) all_buses = LIST_HEAD_INITIALIZER(all_buses); 81 82/* CAM XPT methods */ 83static void atapi_action(struct cam_sim *, union ccb *); 84static void atapi_poll(struct cam_sim *); 85static void atapi_async(void *, u_int32_t, struct cam_path *, void *); 86static void atapi_async1(void *, u_int32_t, struct cam_path *, void *); 87static int atapi_cb(struct atapi_request *); 88 89/* internal functions */ 90static void setup_dev(struct atapi_xpt_softc *, struct ata_device *); 91static void setup_async_cb(struct atapi_xpt_softc *, uint32_t); 92static void cam_rescan_callback(struct cam_periph *, union ccb *); 93static void cam_rescan(struct cam_sim *); 94static void free_hcb_and_ccb_done(struct atapi_hcb *, u_int32_t); 95static struct atapi_hcb *allocate_hcb(struct atapi_xpt_softc *, int, int, union ccb *); 96static void free_hcb(struct atapi_hcb *hcb); 97static void free_softc(struct atapi_xpt_softc *scp); 98static struct ata_device *get_ata_device(struct atapi_xpt_softc *scp, int id); 99 100static MALLOC_DEFINE(M_ATACAM, "ATA CAM transport", "ATA driver CAM-XPT layer"); 101 102void 103atapi_cam_attach_bus(struct ata_channel *ata_ch) 104{ 105 struct atapi_xpt_softc *scp = NULL; 106 struct cam_devq *devq = NULL; 107 struct cam_sim *sim = NULL; 108 struct cam_path *path = NULL; 109 int unit; 110 111 LIST_FOREACH(scp, &all_buses, chain) { 112 if (scp->ata_ch == ata_ch) 113 return; 114 } 115 116 if ((scp = malloc(sizeof(struct atapi_xpt_softc), 117 M_ATACAM, M_NOWAIT | M_ZERO)) == NULL) 118 goto error; 119 120 scp->ata_ch = ata_ch; 121 TAILQ_INIT(&scp->pending_hcbs); 122 LIST_INSERT_HEAD(&all_buses, scp, chain); 123 unit = device_get_unit(ata_ch->dev); 124 125 if ((devq = cam_simq_alloc(16)) == NULL) 126 goto error; 127 128 if ((sim = cam_sim_alloc(atapi_action, atapi_poll, "ata", 129 (void *)scp, unit, 1, 1, devq)) == NULL) { 130 cam_simq_free(devq); 131 goto error; 132 } 133 scp->sim = sim; 134 135 if (xpt_bus_register(sim, 0) != CAM_SUCCESS) { 136 goto error; 137 } 138 scp->flags |= BUS_REGISTERED; 139 140 if (xpt_create_path(&path, /*periph*/ NULL, 141 cam_sim_path(sim), CAM_TARGET_WILDCARD, 142 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 143 goto error; 144 } 145 scp->path = path; 146 147#ifdef CAMDEBUG 148 xpt_print_path(path); 149 printf("Registered SIM for ata%d\n", unit); 150#endif 151 152 setup_async_cb(scp, AC_LOST_DEVICE); 153 154 if (ata_ch->devices & ATA_ATAPI_MASTER) 155 setup_dev(scp, &ata_ch->device[MASTER]); 156 if (ata_ch->devices & ATA_ATAPI_SLAVE) 157 setup_dev(scp, &ata_ch->device[SLAVE]); 158 159 cam_rescan(sim); 160 return; 161 162error: 163 free_softc(scp); 164} 165 166void 167atapi_cam_detach_bus(struct ata_channel *ata_ch) 168{ 169 struct atapi_xpt_softc *scp; 170 171 LIST_FOREACH(scp, &all_buses, chain) { 172 if (scp->ata_ch == ata_ch) 173 free_softc(scp); 174 } 175} 176 177static void 178setup_dev(struct atapi_xpt_softc *scp, struct ata_device *atp) 179{ 180 if (atp->driver == NULL) { 181 ata_set_name(atp, "atapicam", 182 2 * device_get_unit(atp->channel->dev) + 183 (atp->unit == ATA_MASTER) ? 0 : 1); 184 atp->driver = (void *)scp; 185 } 186} 187 188static void 189setup_async_cb(struct atapi_xpt_softc *scp, uint32_t events) 190{ 191 struct ccb_setasync csa; 192 193 xpt_setup_ccb(&csa.ccb_h, scp->path, /*priority*/ 5); 194 csa.ccb_h.func_code = XPT_SASYNC_CB; 195 csa.event_enable = events; 196 csa.callback = &atapi_async; 197 csa.callback_arg = scp->sim; 198 xpt_action((union ccb *) &csa); 199} 200 201static void 202atapi_action(struct cam_sim *sim, union ccb *ccb) 203{ 204 struct atapi_xpt_softc *softc = (struct atapi_xpt_softc*)cam_sim_softc(sim); 205 struct ccb_hdr *ccb_h = &ccb->ccb_h; 206 struct atapi_hcb *hcb = NULL; 207 int unit = cam_sim_unit(sim); 208 int bus = cam_sim_bus(sim); 209 int len; 210 char *buf; 211 212 switch (ccb_h->func_code) { 213 case XPT_PATH_INQ: { 214 struct ccb_pathinq *cpi = &ccb->cpi; 215 216 cpi->version_num = 1; 217 cpi->hba_inquiry = 0; 218 cpi->hba_misc = 0; 219 cpi->hba_eng_cnt = 0; 220 bzero(cpi->vuhba_flags, sizeof(cpi->vuhba_flags)); 221 cpi->max_target = 1; 222 cpi->max_lun = 0; 223 cpi->async_flags = 0; 224 cpi->hpath_id = 0; 225 cpi->initiator_id = 7; 226 strncpy(cpi->sim_vid, "FreeBSD", sizeof(cpi->sim_vid)); 227 strncpy(cpi->hba_vid, "ATAPI", sizeof(cpi->hba_vid)); 228 strncpy(cpi->dev_name, cam_sim_name(sim), sizeof cpi->dev_name); 229 cpi->unit_number = cam_sim_unit(sim); 230 cpi->bus_id = cam_sim_bus(sim); 231 if (softc->ata_ch && ccb_h->target_id >= 0) { 232 switch (softc->ata_ch->device[ccb_h->target_id].mode) { 233 case ATA_PIO1: 234 cpi->base_transfer_speed = 5200; 235 break; 236 case ATA_PIO2: 237 cpi->base_transfer_speed = 7000; 238 break; 239 case ATA_PIO3: 240 cpi->base_transfer_speed = 11000; 241 break; 242 case ATA_PIO4: 243 case ATA_DMA: 244 case ATA_WDMA2: 245 cpi->base_transfer_speed = 16000; 246 break; 247 case ATA_UDMA2: 248 cpi->base_transfer_speed = 33000; 249 break; 250 case ATA_UDMA4: 251 cpi->base_transfer_speed = 66000; 252 break; 253 case ATA_UDMA5: 254 cpi->base_transfer_speed = 100000; 255 break; 256 case ATA_UDMA6: 257 cpi->base_transfer_speed = 133000; 258 break; 259 default: cpi->base_transfer_speed = 3300; 260 } 261 } 262 ccb->ccb_h.status = CAM_REQ_CMP; 263 xpt_done(ccb); 264 return; 265 } 266 267 case XPT_RESET_DEV: 268 /* should reset the device */ 269#ifdef CAMDEBUG 270 xpt_print_path(ccb->ccb_h.path); 271 printf("dev reset"); 272#endif 273 ccb->ccb_h.status = CAM_REQ_CMP; 274 xpt_done(ccb); 275 return; 276 277 case XPT_RESET_BUS: 278 /* should reset the ATA bus */ 279#ifdef CAMDEBUG 280 xpt_print_path(ccb->ccb_h.path); 281 printf("bus reset"); 282#endif 283 ccb->ccb_h.status = CAM_REQ_CMP; 284 xpt_done(ccb); 285 return; 286 287 case XPT_SET_TRAN_SETTINGS: 288 /* ignore these, we're not doing SCSI here */ 289 ccb->ccb_h.status = CAM_REQ_CMP; 290 xpt_done(ccb); 291 return; 292 293 case XPT_GET_TRAN_SETTINGS: { 294 struct ccb_trans_settings *cts = &ccb->cts; 295 296 cts->flags |= 297 (CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID | 298 CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_DISC_VALID | 299 CCB_TRANS_TQ_VALID); 300 cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); 301 cts->sync_period = 0; 302 cts->sync_offset = 0; 303 cts->bus_width = 16; 304 ccb->ccb_h.status = CAM_REQ_CMP; 305 xpt_done(ccb); 306 return; 307 } 308 309 case XPT_CALC_GEOMETRY: { 310 struct ccb_calc_geometry *ccg; 311 unsigned int size_mb; 312 unsigned int secs_per_cylinder; 313 int extended; 314 315 ccg = &ccb->ccg; 316 size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size); 317 extended = 1; 318 319 if (size_mb > 1024 && extended) { 320 ccg->heads = 255; 321 ccg->secs_per_track = 63; 322 } else { 323 ccg->heads = 64; 324 ccg->secs_per_track = 32; 325 } 326 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 327 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 328 ccb->ccb_h.status = CAM_REQ_CMP; 329 xpt_done(ccb); 330 return; 331 } 332 333 case XPT_SCSI_IO: { 334 struct ccb_scsiio *csio = &ccb->csio; 335 int tid = ccb_h->target_id, lid = ccb_h->target_lun; 336 struct ata_device *dev = get_ata_device(softc, tid); 337 338#ifdef CAMDEBUG 339 char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; 340 341 printf("XPT_SCSI_IO (b%d u%d t%d l%d)\n", bus, unit, tid, lid); 342#endif 343 /* check that this request was not aborted already */ 344 if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 345#ifdef CAMDEBUG 346 printf("Already in progress\n"); 347#endif 348 xpt_done(ccb); 349 return; 350 } 351 if (dev == NULL) { 352#ifdef CAMDEBUG 353 printf("Invalid target %d\n", tid); 354#endif 355 ccb_h->status = CAM_TID_INVALID; 356 xpt_done(ccb); 357 return; 358 } 359 if (lid > 0) { 360#ifdef CAMDEBUG 361 printf("Invalid LUN %d\n", lid); 362#endif 363 ccb_h->status = CAM_LUN_INVALID; 364 xpt_done(ccb); 365 return; 366 } 367 if ((ccb_h->flags & CAM_SCATTER_VALID)) { 368 /* scatter-gather not supported */ 369 xpt_print_path(ccb_h->path); 370 printf("ATAPI-CAM does not support scatter-gather yet!\n"); 371 break; 372 } 373 if ((hcb = allocate_hcb(softc, unit, bus, ccb)) == NULL) 374 goto action_oom; 375 376 ccb_h->status |= CAM_SIM_QUEUED; 377 378 bcopy((ccb_h->flags & CAM_CDB_POINTER) ? 379 csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes, 380 hcb->cmd, csio->cdb_len); 381#ifdef CAMDEBUG 382 printf("hcb@%p: %s\n", 383 hcb, scsi_cdb_string(hcb->cmd, cdb_str, sizeof(cdb_str))); 384#endif 385 386 len = csio->dxfer_len; 387 buf = csio->data_ptr; 388 389 /* some SCSI commands require special processing */ 390 switch (hcb->cmd[0]) { 391 case INQUIRY: { 392 /* 393 * many ATAPI devices seem to report more than 394 * SHORT_INQUIRY_LENGTH bytes of available INQUIRY 395 * information, but respond with some incorrect condition 396 * when actually asked for it, so we are going to pretend 397 * that only SHORT_INQUIRY_LENGTH are expected, anyway. 398 */ 399 struct scsi_inquiry *inq = (struct scsi_inquiry *) &hcb->cmd[0]; 400 401 if (inq->byte2 == 0 && inq->page_code == 0 && 402 inq->length > SHORT_INQUIRY_LENGTH) { 403 bzero(buf, len); 404 len = inq->length = SHORT_INQUIRY_LENGTH; 405 } 406 break; 407 } 408 case MODE_SELECT_6: 409 /* FALLTHROUGH */ 410 411 case MODE_SENSE_6: 412 /* 413 * not supported by ATAPI/MMC devices (per SCSI MMC spec) 414 * translate to _10 equivalent. 415 * (actually we should do this only if we have tried 416 * MODE_foo_6 and received ILLEGAL_REQUEST or 417 * INVALID COMMAND OPERATION CODE) 418 * alternative fix: behave like a honest CAM transport, 419 * do not muck with CDB contents, and change scsi_cd to 420 * always use MODE_SENSE_10 in cdgetmode(), or let scsi_cd 421 * know that this specific unit is an ATAPI/MMC one, 422 * and in /that case/ use MODE_SENSE_10 423 */ 424 425#ifdef CAMDEBUG 426 xpt_print_path(ccb_h->path); 427 printf("Translating %s into _10 equivalent\n", 428 (hcb->cmd[0] == MODE_SELECT_6) ? 429 "MODE_SELECT_6" : "MODE_SENSE_6"); 430#endif 431 hcb->cmd[0] |= 0x40; 432 hcb->cmd[6] = 0; 433 hcb->cmd[7] = 0; 434 hcb->cmd[8] = hcb->cmd[4]; 435 hcb->cmd[9] = hcb->cmd[5]; 436 hcb->cmd[4] = 0; 437 hcb->cmd[5] = 0; 438 break; 439 440 case READ_6: 441 /* FALLTHROUGH */ 442 443 case WRITE_6: 444#ifdef CAMDEBUG 445 xpt_print_path(ccb_h->path); 446 printf("Translating %s into _10 equivalent\n", 447 (hcb->cmd[0] == READ_6) ? "READ_6" : "WRITE_6"); 448#endif 449 hcb->cmd[0] |= 0x20; 450 hcb->cmd[9] = hcb->cmd[5]; 451 hcb->cmd[8] = hcb->cmd[4]; 452 hcb->cmd[7] = 0; 453 hcb->cmd[6] = 0; 454 hcb->cmd[5] = hcb->cmd[3]; 455 hcb->cmd[4] = hcb->cmd[2]; 456 hcb->cmd[3] = hcb->cmd[1] & 0x1f; 457 hcb->cmd[2] = 0; 458 hcb->cmd[1] = 0; 459 break; 460 } 461 462 if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) { 463 /* ATA always transfers an even number of bytes */ 464 if (!(buf = hcb->dxfer_alloc = malloc(++len, M_ATACAM, 465 M_NOWAIT | M_ZERO))) 466 goto action_oom; 467 } 468 TAILQ_INSERT_TAIL(&softc->pending_hcbs, hcb, chain); 469 if (atapi_queue_cmd(dev, hcb->cmd, buf, len, 470 (((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN) ? 471 ATPR_F_READ : 0) | ATPR_F_QUIET, 472 ccb_h->timeout, atapi_cb, (void *)hcb) == 0) 473 return; 474 break; 475 } 476 477 default: 478 printf("atapi-cam: unsupported function code 0x%02x\n", 479 ccb_h->func_code); 480 ccb_h->status = CAM_REQ_INVALID; 481 xpt_done(ccb); 482 return; 483 } 484 485action_oom: 486 if (hcb != NULL) 487 free_hcb(hcb); 488 xpt_print_path(ccb_h->path); 489 printf("Out of memory: freezing queue."); 490 softc->flags |= RESOURCE_SHORTAGE; 491 xpt_freeze_simq(sim, /*count*/ 1); 492 ccb_h->status = CAM_REQUEUE_REQ; 493 xpt_done(ccb); 494} 495 496static void 497atapi_poll(struct cam_sim *sim) 498{ 499 /* do nothing - we do not actually service any interrupts */ 500 printf("atapi_poll called!\n"); 501} 502 503int 504atapi_cb(struct atapi_request *req) 505{ 506 int s = splcam(); 507 struct atapi_hcb *hcb = (struct atapi_hcb *) req->driver; 508 struct ccb_scsiio *csio = &hcb->ccb->csio; 509 int hcb_status = req->result; 510 511#ifdef CAMDEBUG 512 printf("atapi_cb: hcb@%p status = %02x: (sk = %02x%s%s%s)\n", 513 hcb, hcb_status, hcb_status >> 4, 514 (hcb_status & 4) ? " ABRT" : "", 515 (hcb_status & 2) ? " EOM" : "", 516 (hcb_status & 1) ? " ILI" : ""); 517 printf(" %s: cmd %02x - sk=%02x asc=%02x ascq=%02x\n", 518 req->device->name, req->ccb[0], req->sense.sense_key, 519 req->sense.asc, req->sense.ascq); 520#endif 521 if (hcb_status != 0) { 522 hcb->ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 523 if ((hcb->ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) { 524 hcb->ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 525 bcopy((void *)&req->sense, (void *)&csio->sense_data, 526 sizeof(struct atapi_reqsense)); 527 } 528 free_hcb_and_ccb_done(hcb, CAM_SCSI_STATUS_ERROR); 529 } 530 else { 531 if (((hcb->ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) && 532 hcb->dxfer_alloc != NULL) 533 bcopy(hcb->dxfer_alloc, csio->data_ptr, csio->dxfer_len); 534 hcb->ccb->csio.scsi_status = SCSI_STATUS_OK; 535 free_hcb_and_ccb_done(hcb, CAM_REQ_CMP); 536 } 537 splx(s); 538 return 0; 539} 540 541static void 542free_hcb_and_ccb_done(struct atapi_hcb *hcb, u_int32_t status) 543{ 544 struct atapi_xpt_softc *softc = hcb->softc; 545 union ccb *ccb = hcb->ccb; 546 547 if (hcb != NULL) { 548 /* we're about to free a hcb, so the shortage has ended */ 549 if (softc->flags & RESOURCE_SHORTAGE) { 550 softc->flags &= ~RESOURCE_SHORTAGE; 551 status |= CAM_RELEASE_SIMQ; 552 } 553 free_hcb(hcb); 554 } 555 ccb->ccb_h.status = 556 status | (ccb->ccb_h.status & ~(CAM_STATUS_MASK | CAM_SIM_QUEUED)); 557 xpt_done(ccb); 558} 559 560static void 561atapi_async(void *callback_arg, u_int32_t code, 562 struct cam_path *path, void *arg) 563{ 564 int s = splcam(); 565 566 atapi_async1(callback_arg, code, path, arg); 567 splx(s); 568} 569 570static void 571atapi_async1(void *callback_arg, u_int32_t code, 572 struct cam_path* path, void *arg) 573{ 574 struct atapi_xpt_softc *softc; 575 struct cam_sim *sim; 576 int targ; 577 578 sim = (struct cam_sim *) callback_arg; 579 softc = (struct atapi_xpt_softc *) cam_sim_softc(sim); 580 switch (code) { 581 case AC_LOST_DEVICE: 582 targ = xpt_path_target_id(path); 583 xpt_print_path(path); 584 if (targ == -1) 585 printf("Lost host adapter\n"); 586 else 587 printf("Lost target %d???\n", targ); 588 break; 589 590 default: 591 break; 592 } 593} 594 595static void 596cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) 597{ 598#ifdef CAMDEBUG 599 xpt_print_path(ccb->ccb_h.path); 600 if (ccb->ccb_h.status != CAM_REQ_CMP) 601 printf("Rescan failed, 0x%04x\n", ccb->ccb_h.status); 602 else 603 printf("rescan succeeded\n"); 604#endif 605 xpt_free_path(ccb->ccb_h.path); 606 free(ccb, M_ATACAM); 607} 608 609static void 610cam_rescan(struct cam_sim *sim) 611{ 612 struct cam_path *path; 613 union ccb *ccb = malloc(sizeof(union ccb), M_ATACAM, M_WAITOK | M_ZERO); 614 615#ifdef CAMDEBUG 616 xpt_print_path(cam_sim_path(sim)); 617 printf ("rescanning ATAPI bus.\n"); 618#endif 619 if (xpt_create_path(&path, xpt_periph, cam_sim_path(sim), 620 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) 621 return; 622 623 xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/); 624 ccb->ccb_h.func_code = XPT_SCAN_BUS; 625 ccb->ccb_h.cbfcnp = cam_rescan_callback; 626 ccb->crcn.flags = CAM_FLAG_NONE; 627 xpt_action(ccb); 628 /* scan is in progress now */ 629} 630 631static struct atapi_hcb * 632allocate_hcb(struct atapi_xpt_softc *softc, int unit, int bus, union ccb *ccb) 633{ 634 struct atapi_hcb *hcb = (struct atapi_hcb *) 635 malloc(sizeof(struct atapi_hcb), M_ATACAM, M_NOWAIT | M_ZERO); 636 637 if (hcb != NULL) { 638 hcb->softc = softc; 639 hcb->unit = unit; 640 hcb->bus = bus; 641 hcb->ccb = ccb; 642 } 643 return hcb; 644} 645 646static void 647free_hcb(struct atapi_hcb *hcb) 648{ 649 TAILQ_REMOVE(&hcb->softc->pending_hcbs, hcb, chain); 650 if (hcb->dxfer_alloc != NULL) 651 free(hcb->dxfer_alloc, M_ATACAM); 652 free(hcb, M_ATACAM); 653} 654 655static void 656free_softc(struct atapi_xpt_softc *scp) 657{ 658 struct atapi_hcb *hcb; 659 660 if (scp != NULL) { 661 TAILQ_FOREACH(hcb, &scp->pending_hcbs, chain) { 662 free_hcb_and_ccb_done(hcb, CAM_UNREC_HBA_ERROR); 663 } 664 if (scp->path != NULL) { 665 setup_async_cb(scp, 0); 666 xpt_free_path(scp->path); 667 } 668 if ((scp->flags & BUS_REGISTERED) != 0) { 669 if (xpt_bus_deregister(cam_sim_path(scp->sim)) == CAM_REQ_CMP) 670 scp->flags &= ~BUS_REGISTERED; 671 } 672 if (scp->sim != NULL) { 673 if ((scp->flags & BUS_REGISTERED) == 0) 674 cam_sim_free(scp->sim, /*free_devq*/TRUE); 675 else 676 printf("Can't free %s SIM (still registered)\n", 677 cam_sim_name(scp->sim)); 678 } 679 LIST_REMOVE(scp, chain); 680 free(scp, M_ATACAM); 681 } 682} 683 684static struct ata_device * 685get_ata_device(struct atapi_xpt_softc *scp, int id) 686{ 687 int role = ATA_ATAPI_MASTER; 688 689 switch (id) { 690 case 1: 691 role = ATA_ATAPI_SLAVE; 692 /* FALLTHROUGH */ 693 694 case 0: 695 if (scp->ata_ch->devices & role) 696 return &scp->ata_ch->device[id]; 697 /* FALLTHROUGH */ 698 699 default: 700 return NULL; 701 } 702} 703