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