atapi-cam.c revision 120315
1/*- 2 * Copyright (c) 2001-2003 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 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-cam.c 120315 2003-09-21 08:53:05Z thomas $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/kernel.h> 36#include <sys/malloc.h> 37#include <sys/ata.h> 38#include <sys/taskqueue.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41#include <machine/bus.h> 42 43#include <cam/cam.h> 44#include <cam/cam_ccb.h> 45#include <cam/cam_periph.h> 46#include <cam/cam_sim.h> 47#include <cam/cam_xpt_sim.h> 48#include <cam/cam_debug.h> 49#include <cam/scsi/scsi_all.h> 50 51#include <dev/ata/ata-all.h> 52 53/* hardware command descriptor block */ 54struct atapi_hcb { 55 struct atapi_xpt_softc *softc; 56 int unit; 57 int bus; 58 int target; 59 int lun; 60 union ccb *ccb; 61 int flags; 62#define QUEUED 0x0001 63 64 char *dxfer_alloc; 65 TAILQ_ENTRY(atapi_hcb) chain; 66}; 67 68/* private data associated with an ATA bus */ 69struct atapi_xpt_softc { 70 struct ata_channel *ata_ch; 71 struct cam_path *path; 72 struct cam_sim *sim; 73 int flags; 74#define BUS_REGISTERED 0x01 75#define RESOURCE_SHORTAGE 0x02 76 77 TAILQ_HEAD(,atapi_hcb) pending_hcbs; 78 LIST_ENTRY(atapi_xpt_softc) chain; 79}; 80 81enum reinit_reason { BOOT_ATTACH, ATTACH, RESET }; 82 83static struct mtx atapicam_softc_mtx; 84static LIST_HEAD(,atapi_xpt_softc) all_buses = LIST_HEAD_INITIALIZER(all_buses); 85 86/* CAM XPT methods */ 87static void atapi_action(struct cam_sim *, union ccb *); 88static void atapi_poll(struct cam_sim *); 89static void atapi_async(void *, u_int32_t, struct cam_path *, void *); 90static void atapi_async1(void *, u_int32_t, struct cam_path *, void *); 91static void atapi_cb(struct ata_request *); 92 93/* internal functions */ 94static void reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason); 95static void setup_dev(struct atapi_xpt_softc *, struct ata_device *); 96static void setup_async_cb(struct atapi_xpt_softc *, uint32_t); 97static void cam_rescan_callback(struct cam_periph *, union ccb *); 98static void cam_rescan(struct cam_sim *); 99static void free_hcb_and_ccb_done(struct atapi_hcb *, u_int32_t); 100static struct atapi_hcb *allocate_hcb(struct atapi_xpt_softc *, int, int, union ccb *); 101static void free_hcb(struct atapi_hcb *hcb); 102static void free_softc(struct atapi_xpt_softc *scp); 103static struct atapi_xpt_softc *get_softc(struct ata_channel *ata_ch); 104static struct ata_device *get_ata_device(struct atapi_xpt_softc *scp, int id); 105 106static MALLOC_DEFINE(M_ATACAM, "ATA CAM transport", "ATA driver CAM-XPT layer"); 107 108void 109atapi_cam_attach_bus(struct ata_channel *ata_ch) 110{ 111 struct atapi_xpt_softc *scp = NULL; 112 struct cam_devq *devq = NULL; 113 struct cam_sim *sim = NULL; 114 struct cam_path *path = NULL; 115 int unit; 116 117 GIANT_REQUIRED; 118 119 if (mtx_initialized(&atapicam_softc_mtx) == 0) 120 mtx_init(&atapicam_softc_mtx, "ATAPI/CAM softc mutex", NULL, MTX_DEF); 121 122 mtx_lock(&atapicam_softc_mtx); 123 124 LIST_FOREACH(scp, &all_buses, chain) { 125 if (scp->ata_ch == ata_ch) 126 break; 127 } 128 mtx_unlock(&atapicam_softc_mtx); 129 130 if (scp != NULL) 131 return; 132 133 if ((scp = malloc(sizeof(struct atapi_xpt_softc), 134 M_ATACAM, M_NOWAIT | M_ZERO)) == NULL) 135 goto error; 136 137 scp->ata_ch = ata_ch; 138 TAILQ_INIT(&scp->pending_hcbs); 139 LIST_INSERT_HEAD(&all_buses, scp, chain); 140 unit = device_get_unit(ata_ch->dev); 141 142 if ((devq = cam_simq_alloc(16)) == NULL) 143 goto error; 144 145 if ((sim = cam_sim_alloc(atapi_action, atapi_poll, "ata", 146 (void *)scp, unit, 1, 1, devq)) == NULL) { 147 cam_simq_free(devq); 148 goto error; 149 } 150 scp->sim = sim; 151 152 if (xpt_bus_register(sim, 0) != CAM_SUCCESS) { 153 goto error; 154 } 155 scp->flags |= BUS_REGISTERED; 156 157 if (xpt_create_path(&path, /*periph*/ NULL, 158 cam_sim_path(sim), CAM_TARGET_WILDCARD, 159 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 160 goto error; 161 } 162 scp->path = path; 163 164 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("Registered SIM for ata%d\n", unit)); 165 166 setup_async_cb(scp, AC_LOST_DEVICE); 167 reinit_bus(scp, cold ? BOOT_ATTACH : ATTACH); 168 return; 169 170error: 171 free_softc(scp); 172} 173 174void 175atapi_cam_detach_bus(struct ata_channel *ata_ch) 176{ 177 struct atapi_xpt_softc *scp = get_softc(ata_ch); 178 179 mtx_lock(&Giant); 180 free_softc(scp); 181 mtx_unlock(&Giant); 182} 183 184void 185atapi_cam_reinit_bus(struct ata_channel *ata_ch) { 186 struct atapi_xpt_softc *scp = get_softc(ata_ch); 187 188 /* 189 * scp might be null if the bus is being reinitialised during 190 * the boot-up sequence, before the ATAPI bus is registered. 191 */ 192 193 if (scp != NULL) { 194 mtx_lock(&Giant); 195 reinit_bus(scp, RESET); 196 mtx_unlock(&Giant); 197 } 198} 199 200static void 201reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason) { 202 203 GIANT_REQUIRED; 204 205 if (scp->ata_ch->devices & ATA_ATAPI_MASTER) 206 setup_dev(scp, &scp->ata_ch->device[MASTER]); 207 if (scp->ata_ch->devices & ATA_ATAPI_SLAVE) 208 setup_dev(scp, &scp->ata_ch->device[SLAVE]); 209 210 switch (reason) { 211 case BOOT_ATTACH: 212 break; 213 case RESET: 214 xpt_async(AC_BUS_RESET, scp->path, NULL); 215 /*FALLTHROUGH*/ 216 case ATTACH: 217 cam_rescan(scp->sim); 218 break; 219 } 220} 221 222static void 223setup_dev(struct atapi_xpt_softc *scp, struct ata_device *atp) 224{ 225 if (atp->softc == NULL) { 226 ata_set_name(atp, "atapicam", 227 2 * device_get_unit(atp->channel->dev) + 228 (atp->unit == ATA_MASTER) ? 0 : 1); 229 atp->softc = (void *)scp; 230 } 231} 232 233static void 234setup_async_cb(struct atapi_xpt_softc *scp, uint32_t events) 235{ 236 struct ccb_setasync csa; 237 238 GIANT_REQUIRED; 239 240 xpt_setup_ccb(&csa.ccb_h, scp->path, /*priority*/ 5); 241 csa.ccb_h.func_code = XPT_SASYNC_CB; 242 csa.event_enable = events; 243 csa.callback = &atapi_async; 244 csa.callback_arg = scp->sim; 245 xpt_action((union ccb *) &csa); 246} 247 248static void 249atapi_action(struct cam_sim *sim, union ccb *ccb) 250{ 251 struct atapi_xpt_softc *softc = (struct atapi_xpt_softc*)cam_sim_softc(sim); 252 struct ccb_hdr *ccb_h = &ccb->ccb_h; 253 struct atapi_hcb *hcb = NULL; 254 struct ata_request *request = NULL; 255 int unit = cam_sim_unit(sim); 256 int bus = cam_sim_bus(sim); 257 int len; 258 char *buf; 259 260 switch (ccb_h->func_code) { 261 case XPT_PATH_INQ: { 262 struct ccb_pathinq *cpi = &ccb->cpi; 263 264 cpi->version_num = 1; 265 cpi->hba_inquiry = 0; 266 cpi->target_sprt = 0; 267 cpi->hba_misc = PIM_NO_6_BYTE; 268 cpi->hba_eng_cnt = 0; 269 bzero(cpi->vuhba_flags, sizeof(cpi->vuhba_flags)); 270 cpi->max_target = 1; 271 cpi->max_lun = 0; 272 cpi->async_flags = 0; 273 cpi->hpath_id = 0; 274 cpi->initiator_id = 7; 275 strncpy(cpi->sim_vid, "FreeBSD", sizeof(cpi->sim_vid)); 276 strncpy(cpi->hba_vid, "ATAPI", sizeof(cpi->hba_vid)); 277 strncpy(cpi->dev_name, cam_sim_name(sim), sizeof cpi->dev_name); 278 cpi->unit_number = cam_sim_unit(sim); 279 cpi->bus_id = cam_sim_bus(sim); 280 cpi->base_transfer_speed = 3300; 281 282 if (softc->ata_ch && ccb_h->target_id != CAM_TARGET_WILDCARD) { 283 switch (softc->ata_ch->device[ccb_h->target_id].mode) { 284 case ATA_PIO1: 285 cpi->base_transfer_speed = 5200; 286 break; 287 case ATA_PIO2: 288 cpi->base_transfer_speed = 7000; 289 break; 290 case ATA_PIO3: 291 cpi->base_transfer_speed = 11000; 292 break; 293 case ATA_PIO4: 294 case ATA_DMA: 295 case ATA_WDMA2: 296 cpi->base_transfer_speed = 16000; 297 break; 298 case ATA_UDMA2: 299 cpi->base_transfer_speed = 33000; 300 break; 301 case ATA_UDMA4: 302 cpi->base_transfer_speed = 66000; 303 break; 304 case ATA_UDMA5: 305 cpi->base_transfer_speed = 100000; 306 break; 307 case ATA_UDMA6: 308 cpi->base_transfer_speed = 133000; 309 break; 310 default: 311 break; 312 } 313 } 314 ccb->ccb_h.status = CAM_REQ_CMP; 315 xpt_done(ccb); 316 return; 317 } 318 319 case XPT_RESET_DEV: { 320 int tid = ccb_h->target_id; 321 struct ata_device *dev = get_ata_device(softc, tid); 322 323 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("dev reset\n")); 324 ata_controlcmd(dev, ATA_ATAPI_RESET, 0, 0, 0); 325 ccb->ccb_h.status = CAM_REQ_CMP; 326 xpt_done(ccb); 327 return; 328 } 329 330 case XPT_RESET_BUS: 331 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("bus reset\n")); 332 ata_reinit(softc->ata_ch); 333 ccb->ccb_h.status = CAM_REQ_CMP; 334 xpt_done(ccb); 335 return; 336 337 case XPT_SET_TRAN_SETTINGS: 338 /* ignore these, we're not doing SCSI here */ 339 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, 340 ("SET_TRAN_SETTINGS not supported\n")); 341 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 342 xpt_done(ccb); 343 return; 344 345 case XPT_GET_TRAN_SETTINGS: { 346 struct ccb_trans_settings *cts = &ccb->cts; 347 348 /* 349 * XXX The default CAM transport code is very SCSI-specific and 350 * doesn't understand IDE speeds very well. Be silent about it 351 * here and let it default to what is set in XPT_PATH_INQ 352 */ 353 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("GET_TRAN_SETTINGS\n")); 354 cts->valid = (CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID); 355 cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); 356 ccb->ccb_h.status = CAM_REQ_CMP; 357 xpt_done(ccb); 358 return; 359 } 360 361 case XPT_CALC_GEOMETRY: { 362 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("CALC_GEOMETRY\n")); 363 cam_calc_geometry(&ccb->ccg, /*extended*/1); 364 xpt_done(ccb); 365 return; 366 } 367 368 case XPT_SCSI_IO: { 369 struct ccb_scsiio *csio = &ccb->csio; 370 int tid = ccb_h->target_id, lid = ccb_h->target_lun; 371 struct ata_device *dev = get_ata_device(softc, tid); 372 int request_flags = ATA_R_QUIET | ATA_R_ATAPI; 373 374 CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, ("XPT_SCSI_IO\n")); 375 376 /* check that this request was not aborted already */ 377 if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 378 printf("XPT_SCSI_IO received but already in progress?\n"); 379 xpt_done(ccb); 380 return; 381 } 382 if (dev == NULL) { 383 CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, 384 ("SCSI IO received for invalid device\n")); 385 goto action_invalid; 386 } 387 if (lid > 0) { 388 CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, 389 ("SCSI IO received for invalid lun %d\n", lid)); 390 goto action_invalid; 391 } 392 if (csio->cdb_len > sizeof request->u.atapi.ccb) { 393 CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, 394 ("CAM CCB too long for ATAPI")); 395 goto action_invalid; 396 } 397 if ((ccb_h->flags & CAM_SCATTER_VALID)) { 398 /* scatter-gather not supported */ 399 xpt_print_path(ccb_h->path); 400 printf("ATAPI/CAM does not support scatter-gather yet!\n"); 401 goto action_invalid; 402 } 403 404 switch (ccb_h->flags & CAM_DIR_MASK) { 405 case CAM_DIR_IN: 406 request_flags |= ATA_R_READ; 407 break; 408 case CAM_DIR_OUT: 409 request_flags |= ATA_R_WRITE; 410 break; 411 case CAM_DIR_NONE: 412 request_flags |= ATA_R_CONTROL; 413 break; 414 default: 415 ata_prtdev(dev, "unknown IO operation\n"); 416 goto action_invalid; 417 } 418 419 if ((hcb = allocate_hcb(softc, unit, bus, ccb)) == NULL) { 420 printf("cannot allocate ATAPI/CAM hcb\n"); 421 goto action_oom; 422 } 423 if ((request = ata_alloc_request()) == NULL) { 424 printf("cannot allocate ATAPI/CAM request\n"); 425 goto action_oom; 426 } 427 428 bcopy((ccb_h->flags & CAM_CDB_POINTER) ? 429 csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes, 430 request->u.atapi.ccb, csio->cdb_len); 431#ifdef CAMDEBUG 432 if (CAM_DEBUGGED(ccb_h->path, CAM_DEBUG_CDB)) { 433 char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; 434 435 printf("atapi_action: hcb@%p: %s\n", hcb, 436 scsi_cdb_string(request->u.atapi.ccb, cdb_str, sizeof(cdb_str))); 437 } 438#endif 439 440 len = csio->dxfer_len; 441 buf = csio->data_ptr; 442 443 /* some SCSI commands require special processing */ 444 switch (request->u.atapi.ccb[0]) { 445 case INQUIRY: { 446 /* 447 * many ATAPI devices seem to report more than 448 * SHORT_INQUIRY_LENGTH bytes of available INQUIRY 449 * information, but respond with some incorrect condition 450 * when actually asked for it, so we are going to pretend 451 * that only SHORT_INQUIRY_LENGTH are expected, anyway. 452 */ 453 struct scsi_inquiry *inq = (struct scsi_inquiry *) &request->u.atapi.ccb[0]; 454 455 if (inq->byte2 == 0 && inq->page_code == 0 && 456 inq->length > SHORT_INQUIRY_LENGTH) { 457 bzero(buf, len); 458 len = inq->length = SHORT_INQUIRY_LENGTH; 459 } 460 break; 461 } 462 case READ_6: 463 /* FALLTHROUGH */ 464 465 case WRITE_6: 466 CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, 467 ("Translating %s into _10 equivalent\n", 468 (request->u.atapi.ccb[0] == READ_6) ? "READ_6" : "WRITE_6")); 469 request->u.atapi.ccb[0] |= 0x20; 470 request->u.atapi.ccb[9] = request->u.atapi.ccb[5]; 471 request->u.atapi.ccb[8] = request->u.atapi.ccb[4]; 472 request->u.atapi.ccb[7] = 0; 473 request->u.atapi.ccb[6] = 0; 474 request->u.atapi.ccb[5] = request->u.atapi.ccb[3]; 475 request->u.atapi.ccb[4] = request->u.atapi.ccb[2]; 476 request->u.atapi.ccb[3] = request->u.atapi.ccb[1] & 0x1f; 477 request->u.atapi.ccb[2] = 0; 478 request->u.atapi.ccb[1] = 0; 479 break; 480 } 481 482 if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) { 483 /* ATA always transfers an even number of bytes */ 484 if ((buf = hcb->dxfer_alloc 485 = malloc(++len, M_ATACAM, M_NOWAIT | M_ZERO)) == NULL) { 486 printf("cannot allocate ATAPI/CAM buffer\n"); 487 goto action_oom; 488 } 489 } 490 request->device = dev; 491 request->driver = hcb; 492 request->data = buf; 493 request->bytecount = len; 494 request->transfersize = min(request->bytecount, 65534); 495 request->timeout = ccb_h->timeout; 496 request->retries = 2; 497 request->callback = &atapi_cb; 498 request->flags = request_flags; 499 500 TAILQ_INSERT_TAIL(&softc->pending_hcbs, hcb, chain); 501 hcb->flags |= QUEUED; 502 ccb_h->status |= CAM_SIM_QUEUED; 503 504 ata_queue_request(request); 505 return; 506 } 507 508 default: 509 CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, 510 ("unsupported function code 0x%02x\n", ccb_h->func_code)); 511 goto action_invalid; 512 } 513 514 /* NOTREACHED */ 515 516action_oom: 517 if (request != NULL) 518 ata_free_request(request); 519 if (hcb != NULL) 520 free_hcb(hcb); 521 xpt_print_path(ccb_h->path); 522 printf("out of memory, freezing queue.\n"); 523 softc->flags |= RESOURCE_SHORTAGE; 524 xpt_freeze_simq(sim, /*count*/ 1); 525 ccb_h->status = CAM_REQUEUE_REQ; 526 xpt_done(ccb); 527 return; 528 529action_invalid: 530 ccb_h->status = CAM_REQ_INVALID; 531 xpt_done(ccb); 532 return; 533} 534 535static void 536atapi_poll(struct cam_sim *sim) 537{ 538 /* do nothing - we do not actually service any interrupts */ 539 printf("atapi_poll called!\n"); 540} 541 542static void 543atapi_cb(struct ata_request *request) 544{ 545 struct atapi_hcb *hcb = (struct atapi_hcb *) request->driver; 546 struct ccb_scsiio *csio = &hcb->ccb->csio; 547 int hcb_status = request->result; 548 549 mtx_lock(&Giant); 550 551#ifdef CAMDEBUG 552 if (CAM_DEBUGGED(csio->ccb_h.path, CAM_DEBUG_CDB)) { 553 printf("atapi_cb: hcb@%p status = %02x: (sk = %02x%s%s%s)\n", 554 hcb, hcb_status, hcb_status >> 4, 555 (hcb_status & 4) ? " ABRT" : "", 556 (hcb_status & 2) ? " EOM" : "", 557 (hcb_status & 1) ? " ILI" : ""); 558 printf(" %s: cmd %02x\n", 559 request->device->name, request->u.atapi.ccb[0]); 560 } 561#endif 562 if (hcb_status != 0) { 563 csio->scsi_status = SCSI_STATUS_CHECK_COND; 564#if 0 565 /* 566 * XXX Temporarily disable autosense, as this seems to cause 567 * a missed ATA interrupt. 568 */ 569 if ((csio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) { 570 int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0, 571 sizeof(struct atapi_sense), 0, 0, 0, 0, 0, 0, 572 0, 0, 0, 0, 0 }; 573 574 if (ata_atapicmd(request->device, ccb, (caddr_t)&csio->sense_data, 575 sizeof(struct atapi_sense), ATA_R_READ, 30) == 0) 576 { 577 csio->ccb_h.status |= CAM_AUTOSNS_VALID; 578 } 579 } 580#endif 581 free_hcb_and_ccb_done(hcb, CAM_SCSI_STATUS_ERROR); 582 } 583 else { 584 if (((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) && 585 hcb->dxfer_alloc != NULL) 586 { 587 bcopy(hcb->dxfer_alloc, csio->data_ptr, csio->dxfer_len); 588 } 589 csio->scsi_status = SCSI_STATUS_OK; 590 free_hcb_and_ccb_done(hcb, CAM_REQ_CMP); 591 } 592 mtx_unlock(&Giant); 593} 594 595static void 596free_hcb_and_ccb_done(struct atapi_hcb *hcb, u_int32_t status) 597{ 598 struct atapi_xpt_softc *softc = hcb->softc; 599 union ccb *ccb = hcb->ccb; 600 601 GIANT_REQUIRED; 602 603 if (hcb != NULL) { 604 /* we're about to free a hcb, so the shortage has ended */ 605 if (softc->flags & RESOURCE_SHORTAGE) { 606 softc->flags &= ~RESOURCE_SHORTAGE; 607 status |= CAM_RELEASE_SIMQ; 608 } 609 free_hcb(hcb); 610 } 611 ccb->ccb_h.status = 612 status | (ccb->ccb_h.status & ~(CAM_STATUS_MASK | CAM_SIM_QUEUED)); 613 xpt_done(ccb); 614} 615 616static void 617atapi_async(void *callback_arg, u_int32_t code, 618 struct cam_path *path, void *arg) 619{ 620 mtx_lock(&Giant); 621 atapi_async1(callback_arg, code, path, arg); 622 mtx_unlock(&Giant); 623} 624 625static void 626atapi_async1(void *callback_arg, u_int32_t code, 627 struct cam_path* path, void *arg) 628{ 629 struct atapi_xpt_softc *softc; 630 struct cam_sim *sim; 631 int targ; 632 633 GIANT_REQUIRED; 634 635 sim = (struct cam_sim *) callback_arg; 636 softc = (struct atapi_xpt_softc *) cam_sim_softc(sim); 637 switch (code) { 638 case AC_LOST_DEVICE: 639 targ = xpt_path_target_id(path); 640 xpt_print_path(path); 641 if (targ == -1) 642 printf("Lost host adapter\n"); 643 else 644 printf("Lost target %d???\n", targ); 645 break; 646 647 default: 648 break; 649 } 650} 651 652static void 653cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) 654{ 655 if (ccb->ccb_h.status != CAM_REQ_CMP) { 656 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 657 ("Rescan failed, 0x%04x\n", ccb->ccb_h.status)); 658 } else { 659 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 660 ("Rescan succeeded\n")); 661 } 662 xpt_free_path(ccb->ccb_h.path); 663 free(ccb, M_ATACAM); 664} 665 666static void 667cam_rescan(struct cam_sim *sim) 668{ 669 struct cam_path *path; 670 union ccb *ccb = malloc(sizeof(union ccb), M_ATACAM, M_WAITOK | M_ZERO); 671 672 if (xpt_create_path(&path, xpt_periph, cam_sim_path(sim), 673 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) 674 return; 675 676 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("Rescanning ATAPI bus.\n")); 677 xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/); 678 ccb->ccb_h.func_code = XPT_SCAN_BUS; 679 ccb->ccb_h.cbfcnp = cam_rescan_callback; 680 ccb->crcn.flags = CAM_FLAG_NONE; 681 xpt_action(ccb); 682 /* scan is in progress now */ 683} 684 685static struct atapi_hcb * 686allocate_hcb(struct atapi_xpt_softc *softc, int unit, int bus, union ccb *ccb) 687{ 688 struct atapi_hcb *hcb = (struct atapi_hcb *) 689 malloc(sizeof(struct atapi_hcb), M_ATACAM, M_NOWAIT | M_ZERO); 690 691 if (hcb != NULL) { 692 hcb->softc = softc; 693 hcb->unit = unit; 694 hcb->bus = bus; 695 hcb->ccb = ccb; 696 } 697 return hcb; 698} 699 700static void 701free_hcb(struct atapi_hcb *hcb) 702{ 703 if ((hcb->flags & QUEUED) != 0) 704 TAILQ_REMOVE(&hcb->softc->pending_hcbs, hcb, chain); 705 if (hcb->dxfer_alloc != NULL) 706 free(hcb->dxfer_alloc, M_ATACAM); 707 free(hcb, M_ATACAM); 708} 709 710static void 711free_softc(struct atapi_xpt_softc *scp) 712{ 713 struct atapi_hcb *hcb; 714 715 GIANT_REQUIRED; 716 717 if (scp != NULL) { 718 TAILQ_FOREACH(hcb, &scp->pending_hcbs, chain) { 719 free_hcb_and_ccb_done(hcb, CAM_UNREC_HBA_ERROR); 720 } 721 if (scp->path != NULL) { 722 setup_async_cb(scp, 0); 723 xpt_free_path(scp->path); 724 } 725 if ((scp->flags & BUS_REGISTERED) != 0) { 726 if (xpt_bus_deregister(cam_sim_path(scp->sim)) == CAM_REQ_CMP) 727 scp->flags &= ~BUS_REGISTERED; 728 } 729 if (scp->sim != NULL) { 730 if ((scp->flags & BUS_REGISTERED) == 0) 731 cam_sim_free(scp->sim, /*free_devq*/TRUE); 732 else 733 printf("Can't free %s SIM (still registered)\n", 734 cam_sim_name(scp->sim)); 735 } 736 LIST_REMOVE(scp, chain); 737 free(scp, M_ATACAM); 738 } 739} 740 741static struct atapi_xpt_softc * 742get_softc(struct ata_channel *ata_ch) { 743 struct atapi_xpt_softc *scp = NULL; 744 745 mtx_lock(&atapicam_softc_mtx); 746 LIST_FOREACH(scp, &all_buses, chain) { 747 if (scp->ata_ch == ata_ch) 748 break; 749 } 750 mtx_unlock(&atapicam_softc_mtx); 751 return scp; 752} 753 754static struct ata_device * 755get_ata_device(struct atapi_xpt_softc *scp, int id) 756{ 757 int role = ATA_ATAPI_MASTER; 758 759 switch (id) { 760 case 1: 761 role = ATA_ATAPI_SLAVE; 762 /* FALLTHROUGH */ 763 764 case 0: 765 if (scp->ata_ch->devices & role) 766 return &scp->ata_ch->device[id]; 767 /* FALLTHROUGH */ 768 769 default: 770 return NULL; 771 } 772} 773