1 /*- 2 * Copyright (c) 2009 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 32 #ifdef _KERNEL 33 #include <sys/systm.h> 34 #include <sys/kernel.h> 35 #include <sys/bio.h> 36 #include <sys/sysctl.h> 37 #include <sys/taskqueue.h> 38 #include <sys/lock.h> 39 #include <sys/mutex.h> 40 #include <sys/conf.h> 41 #include <sys/devicestat.h> 42 #include <sys/eventhandler.h> 43 #include <sys/malloc.h> 44 #include <sys/cons.h> 45 #include <geom/geom_disk.h> 46 #endif /* _KERNEL */ 47 48 #ifndef _KERNEL 49 #include <stdio.h> 50 #include <string.h> 51 #endif /* _KERNEL */ 52 53 #include <cam/cam.h> 54 #include <cam/cam_ccb.h> 55 #include <cam/cam_periph.h> 56 #include <cam/cam_xpt_periph.h> 57 #include <cam/cam_sim.h> 58 59 #include <cam/ata/ata_all.h> 60 61 #ifdef _KERNEL 62 63 #define ATA_MAX_28BIT_LBA 268435455UL 64 65 typedef enum { 66 ADA_STATE_NORMAL 67 } ada_state; 68 69 typedef enum { 70 ADA_FLAG_PACK_INVALID = 0x001, 71 ADA_FLAG_CAN_48BIT = 0x002, 72 ADA_FLAG_CAN_FLUSHCACHE = 0x004, 73 ADA_FLAG_CAN_NCQ = 0x008, 74 ADA_FLAG_TAGGED_QUEUING = 0x010, 75 ADA_FLAG_NEED_OTAG = 0x020, 76 ADA_FLAG_WENT_IDLE = 0x040, 77 ADA_FLAG_RETRY_UA = 0x080, 78 ADA_FLAG_OPEN = 0x100, 79 ADA_FLAG_SCTX_INIT = 0x200 80 } ada_flags; 81 82 typedef enum { 83 ADA_Q_NONE = 0x00, 84 ADA_Q_NO_SYNC_CACHE = 0x01, 85 ADA_Q_NO_6_BYTE = 0x02, 86 ADA_Q_NO_PREVENT = 0x04 87 } ada_quirks; 88 89 typedef enum { 90 ADA_CCB_PROBE = 0x01, 91 ADA_CCB_PROBE2 = 0x02, 92 ADA_CCB_BUFFER_IO = 0x03, 93 ADA_CCB_WAITING = 0x04, 94 ADA_CCB_DUMP = 0x05, 95 ADA_CCB_TYPE_MASK = 0x0F, 96 ADA_CCB_RETRY_UA = 0x10 97 } ada_ccb_state; 98 99 /* Offsets into our private area for storing information */ 100 #define ccb_state ppriv_field0 101 #define ccb_bp ppriv_ptr1 102 103 struct disk_params { 104 u_int8_t heads; 105 u_int32_t cylinders; 106 u_int8_t secs_per_track; 107 u_int32_t secsize; /* Number of bytes/sector */ 108 u_int64_t sectors; /* total number sectors */ 109 }; 110 111 struct ada_softc { 112 struct bio_queue_head bio_queue; 113 SLIST_ENTRY(ada_softc) links; 114 LIST_HEAD(, ccb_hdr) pending_ccbs; 115 ada_state state; 116 ada_flags flags; 117 ada_quirks quirks; 118 int ordered_tag_count; 119 int outstanding_cmds; 120 struct disk_params params; 121 struct disk *disk; 122 union ccb saved_ccb; 123 struct task sysctl_task; 124 struct sysctl_ctx_list sysctl_ctx; 125 struct sysctl_oid *sysctl_tree; 126 struct callout sendordered_c; 127 }; 128 129 struct ada_quirk_entry { 130 struct scsi_inquiry_pattern inq_pat; 131 ada_quirks quirks; 132 }; 133 134 //static struct ada_quirk_entry ada_quirk_table[] = 135 //{ 136 //}; 137 138 static disk_strategy_t adastrategy; 139 static dumper_t adadump; 140 static periph_init_t adainit; 141 static void adaasync(void *callback_arg, u_int32_t code, 142 struct cam_path *path, void *arg); 143 static void adasysctlinit(void *context, int pending); 144 static periph_ctor_t adaregister; 145 static periph_dtor_t adacleanup; 146 static periph_start_t adastart; 147 static periph_oninv_t adaoninvalidate; 148 static void adadone(struct cam_periph *periph, 149 union ccb *done_ccb); 150 static int adaerror(union ccb *ccb, u_int32_t cam_flags, 151 u_int32_t sense_flags); 152 static void adasetgeom(struct cam_periph *periph, 153 struct ccb_getdev *cgd); 154 static timeout_t adasendorderedtag; 155 static void adashutdown(void *arg, int howto); 156 157 #ifndef ADA_DEFAULT_TIMEOUT 158 #define ADA_DEFAULT_TIMEOUT 30 /* Timeout in seconds */ 159 #endif 160 161 #ifndef ADA_DEFAULT_RETRY 162 #define ADA_DEFAULT_RETRY 4 163 #endif 164 165 #ifndef ADA_DEFAULT_SEND_ORDERED 166 #define ADA_DEFAULT_SEND_ORDERED 1 167 #endif 168 169 170 static int ada_retry_count = ADA_DEFAULT_RETRY; 171 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT; 172 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED; 173 174 SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0, 175 "CAM Direct Access Disk driver"); 176 SYSCTL_INT(_kern_cam_ada, OID_AUTO, retry_count, CTLFLAG_RW, 177 &ada_retry_count, 0, "Normal I/O retry count"); 178 TUNABLE_INT("kern.cam.ada.retry_count", &ada_retry_count); 179 SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RW, 180 &ada_default_timeout, 0, "Normal I/O timeout (in seconds)"); 181 TUNABLE_INT("kern.cam.ada.default_timeout", &ada_default_timeout); 182 SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW, 183 &ada_send_ordered, 0, "Send Ordered Tags"); 184 TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered); 185 186 /* 187 * ADA_ORDEREDTAG_INTERVAL determines how often, relative 188 * to the default timeout, we check to see whether an ordered 189 * tagged transaction is appropriate to prevent simple tag 190 * starvation. Since we'd like to ensure that there is at least 191 * 1/2 of the timeout length left for a starved transaction to 192 * complete after we've sent an ordered tag, we must poll at least 193 * four times in every timeout period. This takes care of the worst 194 * case where a starved transaction starts during an interval that 195 * meets the requirement "don't send an ordered tag" test so it takes 196 * us two intervals to determine that a tag must be sent. 197 */ 198 #ifndef ADA_ORDEREDTAG_INTERVAL 199 #define ADA_ORDEREDTAG_INTERVAL 4 200 #endif 201 202 static struct periph_driver adadriver = 203 { 204 adainit, "ada", 205 TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0 206 }; 207 208 PERIPHDRIVER_DECLARE(ada, adadriver); 209 210 MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers"); 211 212 static int 213 adaopen(struct disk *dp) 214 { 215 struct cam_periph *periph; 216 struct ada_softc *softc; 217 int unit; 218 int error; 219 220 periph = (struct cam_periph *)dp->d_drv1; 221 if (periph == NULL) { 222 return (ENXIO); 223 } 224 225 if (cam_periph_acquire(periph) != CAM_REQ_CMP) { 226 return(ENXIO); 227 } 228 229 cam_periph_lock(periph); 230 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { 231 cam_periph_unlock(periph); 232 cam_periph_release(periph); 233 return (error); 234 } 235 236 unit = periph->unit_number; 237 softc = (struct ada_softc *)periph->softc; 238 softc->flags |= ADA_FLAG_OPEN; 239 240 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 241 ("adaopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit, 242 unit)); 243 244 if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) { 245 /* Invalidate our pack information. */ 246 softc->flags &= ~ADA_FLAG_PACK_INVALID; 247 } 248 249 cam_periph_unhold(periph); 250 cam_periph_unlock(periph); 251 return (0); 252 } 253 254 static int 255 adaclose(struct disk *dp) 256 { 257 struct cam_periph *periph; 258 struct ada_softc *softc; 259 union ccb *ccb; 260 int error; 261 262 periph = (struct cam_periph *)dp->d_drv1; 263 if (periph == NULL) 264 return (ENXIO); 265 266 cam_periph_lock(periph); 267 if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { 268 cam_periph_unlock(periph); 269 cam_periph_release(periph); 270 return (error); 271 } 272 273 softc = (struct ada_softc *)periph->softc; 274 /* We only sync the cache if the drive is capable of it. */ 275 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) { 276 277 ccb = cam_periph_getccb(periph, /*priority*/1); 278 ccb->ccb_h.ccb_state = ADA_CCB_DUMP; 279 cam_fill_ataio(&ccb->ataio, 280 1, 281 adadone, 282 CAM_DIR_NONE, 283 0, 284 NULL, 285 0, 286 ada_default_timeout*1000); 287 288 if (softc->flags & ADA_FLAG_CAN_48BIT) 289 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0); 290 else 291 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0); 292 xpt_polled_action(ccb); 293 294 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 295 xpt_print(periph->path, "Synchronize cache failed\n"); 296 297 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 298 cam_release_devq(ccb->ccb_h.path, 299 /*relsim_flags*/0, 300 /*reduction*/0, 301 /*timeout*/0, 302 /*getcount_only*/0); 303 xpt_release_ccb(ccb); 304 } 305 306 softc->flags &= ~ADA_FLAG_OPEN; 307 cam_periph_unhold(periph); 308 cam_periph_unlock(periph); 309 cam_periph_release(periph); 310 return (0); 311 } 312 313 /* 314 * Actually translate the requested transfer into one the physical driver 315 * can understand. The transfer is described by a buf and will include 316 * only one physical transfer. 317 */ 318 static void 319 adastrategy(struct bio *bp) 320 { 321 struct cam_periph *periph; 322 struct ada_softc *softc; 323 324 periph = (struct cam_periph *)bp->bio_disk->d_drv1; 325 if (periph == NULL) { 326 biofinish(bp, NULL, ENXIO); 327 return; 328 } 329 softc = (struct ada_softc *)periph->softc; 330 331 cam_periph_lock(periph); 332 333 #if 0 334 /* 335 * check it's not too big a transfer for our adapter 336 */ 337 scsi_minphys(bp,&sd_switch); 338 #endif 339 340 /* 341 * Mask interrupts so that the pack cannot be invalidated until 342 * after we are in the queue. Otherwise, we might not properly 343 * clean up one of the buffers. 344 */ 345 346 /* 347 * If the device has been made invalid, error out 348 */ 349 if ((softc->flags & ADA_FLAG_PACK_INVALID)) { 350 cam_periph_unlock(periph); 351 biofinish(bp, NULL, ENXIO); 352 return; 353 } 354 355 /* 356 * Place it in the queue of disk activities for this disk 357 */ 358 bioq_disksort(&softc->bio_queue, bp); 359 360 /* 361 * Schedule ourselves for performing the work. 362 */ 363 xpt_schedule(periph, /* XXX priority */1); 364 cam_periph_unlock(periph); 365 366 return; 367 } 368 369 static int 370 adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) 371 { 372 struct cam_periph *periph; 373 struct ada_softc *softc; 374 u_int secsize; 375 union ccb ccb; 376 struct disk *dp; 377 uint64_t lba; 378 uint16_t count; 379 380 dp = arg; 381 periph = dp->d_drv1; 382 if (periph == NULL) 383 return (ENXIO); 384 softc = (struct ada_softc *)periph->softc; 385 cam_periph_lock(periph); 386 secsize = softc->params.secsize; 387 lba = offset / secsize; 388 count = length / secsize; 389 390 if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) { 391 cam_periph_unlock(periph); 392 return (ENXIO); 393 } 394 395 if (length > 0) { 396 periph->flags |= CAM_PERIPH_POLLED; 397 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1); 398 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 399 cam_fill_ataio(&ccb.ataio, 400 0, 401 adadone, 402 CAM_DIR_OUT, 403 0, 404 (u_int8_t *) virtual, 405 length, 406 ada_default_timeout*1000); 407 if ((softc->flags & ADA_FLAG_CAN_48BIT) && 408 (lba + count >= ATA_MAX_28BIT_LBA || 409 count >= 256)) { 410 ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48, 411 0, lba, count); 412 } else { 413 ata_36bit_cmd(&ccb.ataio, ATA_WRITE_DMA, 414 0, lba, count); 415 } 416 xpt_polled_action(&ccb); 417 418 if ((ccb.ataio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 419 printf("Aborting dump due to I/O error.\n"); 420 cam_periph_unlock(periph); 421 return(EIO); 422 } 423 cam_periph_unlock(periph); 424 return(0); 425 } 426 427 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) { 428 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1); 429 430 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 431 cam_fill_ataio(&ccb.ataio, 432 1, 433 adadone, 434 CAM_DIR_NONE, 435 0, 436 NULL, 437 0, 438 ada_default_timeout*1000); 439 440 if (softc->flags & ADA_FLAG_CAN_48BIT) 441 ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0); 442 else 443 ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); 444 xpt_polled_action(&ccb); 445 446 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 447 xpt_print(periph->path, "Synchronize cache failed\n"); 448 449 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) 450 cam_release_devq(ccb.ccb_h.path, 451 /*relsim_flags*/0, 452 /*reduction*/0, 453 /*timeout*/0, 454 /*getcount_only*/0); 455 } 456 periph->flags &= ~CAM_PERIPH_POLLED; 457 cam_periph_unlock(periph); 458 return (0); 459 } 460 461 static void 462 adainit(void) 463 { 464 cam_status status; 465 466 /* 467 * Install a global async callback. This callback will 468 * receive async callbacks like "new device found". 469 */ 470 status = xpt_register_async(AC_FOUND_DEVICE, adaasync, NULL, NULL); 471 472 if (status != CAM_REQ_CMP) { 473 printf("ada: Failed to attach master async callback " 474 "due to status 0x%x!\n", status); 475 } else if (ada_send_ordered) { 476 477 /* Register our shutdown event handler */ 478 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, adashutdown, 479 NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) 480 printf("adainit: shutdown event registration failed!\n"); 481 } 482 } 483 484 static void 485 adaoninvalidate(struct cam_periph *periph) 486 { 487 struct ada_softc *softc; 488 489 softc = (struct ada_softc *)periph->softc; 490 491 /* 492 * De-register any async callbacks. 493 */ 494 xpt_register_async(0, adaasync, periph, periph->path); 495 496 softc->flags |= ADA_FLAG_PACK_INVALID; 497 498 /* 499 * Return all queued I/O with ENXIO. 500 * XXX Handle any transactions queued to the card 501 * with XPT_ABORT_CCB. 502 */ 503 bioq_flush(&softc->bio_queue, NULL, ENXIO); 504 505 disk_gone(softc->disk); 506 xpt_print(periph->path, "lost device\n"); 507 } 508 509 static void 510 adacleanup(struct cam_periph *periph) 511 { 512 struct ada_softc *softc; 513 514 softc = (struct ada_softc *)periph->softc; 515 516 xpt_print(periph->path, "removing device entry\n"); 517 cam_periph_unlock(periph); 518 519 /* 520 * If we can't free the sysctl tree, oh well... 521 */ 522 if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0 523 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) { 524 xpt_print(periph->path, "can't remove sysctl context\n"); 525 } 526 527 disk_destroy(softc->disk); 528 callout_drain(&softc->sendordered_c); 529 free(softc, M_DEVBUF); 530 cam_periph_lock(periph); 531 } 532 533 static void 534 adaasync(void *callback_arg, u_int32_t code, 535 struct cam_path *path, void *arg) 536 { 537 struct cam_periph *periph; 538 539 periph = (struct cam_periph *)callback_arg; 540 switch (code) { 541 case AC_FOUND_DEVICE: 542 { 543 struct ccb_getdev *cgd; 544 cam_status status; 545 546 cgd = (struct ccb_getdev *)arg; 547 if (cgd == NULL) 548 break; 549 550 if (cgd->protocol != PROTO_ATA) 551 break; 552 553 // if (SID_TYPE(&cgd->inq_data) != T_DIRECT 554 // && SID_TYPE(&cgd->inq_data) != T_RBC 555 // && SID_TYPE(&cgd->inq_data) != T_OPTICAL) 556 // break; 557 558 /* 559 * Allocate a peripheral instance for 560 * this device and start the probe 561 * process. 562 */ 563 status = cam_periph_alloc(adaregister, adaoninvalidate, 564 adacleanup, adastart, 565 "ada", CAM_PERIPH_BIO, 566 cgd->ccb_h.path, adaasync, 567 AC_FOUND_DEVICE, cgd); 568 569 if (status != CAM_REQ_CMP 570 && status != CAM_REQ_INPROG) 571 printf("adaasync: Unable to attach to new device " 572 "due to status 0x%x\n", status); 573 break; 574 } 575 case AC_SENT_BDR: 576 case AC_BUS_RESET: 577 { 578 struct ada_softc *softc; 579 struct ccb_hdr *ccbh; 580 581 softc = (struct ada_softc *)periph->softc; 582 /* 583 * Don't fail on the expected unit attention 584 * that will occur. 585 */ 586 softc->flags |= ADA_FLAG_RETRY_UA; 587 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) 588 ccbh->ccb_state |= ADA_CCB_RETRY_UA; 589 /* FALLTHROUGH*/ 590 } 591 default: 592 cam_periph_async(periph, code, path, arg); 593 break; 594 } 595 } 596 597 static void 598 adasysctlinit(void *context, int pending) 599 { 600 struct cam_periph *periph; 601 struct ada_softc *softc; 602 char tmpstr[80], tmpstr2[80]; 603 604 periph = (struct cam_periph *)context; 605 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 606 return; 607 608 softc = (struct ada_softc *)periph->softc; 609 snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d", periph->unit_number); 610 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); 611 612 sysctl_ctx_init(&softc->sysctl_ctx); 613 softc->flags |= ADA_FLAG_SCTX_INIT; 614 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 615 SYSCTL_STATIC_CHILDREN(_kern_cam_ada), OID_AUTO, tmpstr2, 616 CTLFLAG_RD, 0, tmpstr); 617 if (softc->sysctl_tree == NULL) { 618 printf("adasysctlinit: unable to allocate sysctl tree\n"); 619 cam_periph_release(periph); 620 return; 621 } 622 623 cam_periph_release(periph); 624 } 625 626 static cam_status 627 adaregister(struct cam_periph *periph, void *arg) 628 { 629 struct ada_softc *softc; 630 struct ccb_pathinq cpi; 631 struct ccb_getdev *cgd; 632 char announce_buf[80]; 633 struct disk_params *dp; 634 caddr_t match; 635 u_int maxio; 636 637 cgd = (struct ccb_getdev *)arg; 638 if (periph == NULL) { 639 printf("adaregister: periph was NULL!!\n"); 640 return(CAM_REQ_CMP_ERR); 641 } 642 643 if (cgd == NULL) { 644 printf("adaregister: no getdev CCB, can't register device\n"); 645 return(CAM_REQ_CMP_ERR); 646 } 647 648 softc = (struct ada_softc *)malloc(sizeof(*softc), M_DEVBUF, 649 M_NOWAIT|M_ZERO); 650 651 if (softc == NULL) { 652 printf("adaregister: Unable to probe new device. " 653 "Unable to allocate softc\n"); 654 return(CAM_REQ_CMP_ERR); 655 } 656 657 LIST_INIT(&softc->pending_ccbs); 658 softc->state = ADA_STATE_NORMAL; 659 bioq_init(&softc->bio_queue); 660 661 if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) 662 softc->flags |= ADA_FLAG_CAN_48BIT; 663 if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE) 664 softc->flags |= ADA_FLAG_CAN_FLUSHCACHE; 665 if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ && 666 cgd->ident_data.queue >= 31) 667 softc->flags |= ADA_FLAG_CAN_NCQ; 668 // if ((cgd->inq_data.flags & SID_CmdQue) != 0) 669 // softc->flags |= ADA_FLAG_TAGGED_QUEUING; 670 671 periph->softc = softc; 672 673 /* 674 * See if this device has any quirks. 675 */ 676 // match = cam_quirkmatch((caddr_t)&cgd->inq_data, 677 // (caddr_t)ada_quirk_table, 678 // sizeof(ada_quirk_table)/sizeof(*ada_quirk_table), 679 // sizeof(*ada_quirk_table), scsi_inquiry_match); 680 match = NULL; 681 682 if (match != NULL) 683 softc->quirks = ((struct ada_quirk_entry *)match)->quirks; 684 else 685 softc->quirks = ADA_Q_NONE; 686 687 /* Check if the SIM does not want queued commands */ 688 bzero(&cpi, sizeof(cpi)); 689 xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1); 690 cpi.ccb_h.func_code = XPT_PATH_INQ; 691 xpt_action((union ccb *)&cpi); 692 if (cpi.ccb_h.status != CAM_REQ_CMP || 693 (cpi.hba_inquiry & PI_TAG_ABLE) == 0) 694 softc->flags &= ~ADA_FLAG_CAN_NCQ; 695 696 TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph); 697 698 /* 699 * Register this media as a disk 700 */ 701 mtx_unlock(periph->sim->mtx); 702 softc->disk = disk_alloc(); 703 softc->disk->d_open = adaopen; 704 softc->disk->d_close = adaclose; 705 softc->disk->d_strategy = adastrategy; 706 softc->disk->d_dump = adadump; 707 softc->disk->d_name = "ada"; 708 softc->disk->d_drv1 = periph; 709 maxio = cpi.maxio; /* Honor max I/O size of SIM */ 710 if (maxio == 0) 711 maxio = DFLTPHYS; /* traditional default */ 712 else if (maxio > MAXPHYS) 713 maxio = MAXPHYS; /* for safety */ 714 if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) 715 maxio = min(maxio, 65535 * 512); 716 else /* 28bit ATA command limit */ 717 maxio = min(maxio, 255 * 512); 718 softc->disk->d_maxsize = maxio; 719 softc->disk->d_unit = periph->unit_number; 720 softc->disk->d_flags = 0; 721 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) 722 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; 723 724 adasetgeom(periph, cgd); 725 softc->disk->d_sectorsize = softc->params.secsize; 726 softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors; 727 /* XXX: these are not actually "firmware" values, so they may be wrong */ 728 softc->disk->d_fwsectors = softc->params.secs_per_track; 729 softc->disk->d_fwheads = softc->params.heads; 730 // softc->disk->d_devstat->block_size = softc->params.secsize; 731 // softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE; 732 733 disk_create(softc->disk, DISK_VERSION); 734 mtx_lock(periph->sim->mtx); 735 736 dp = &softc->params; 737 snprintf(announce_buf, sizeof(announce_buf), 738 "%juMB (%ju %u byte sectors: %dH %dS/T %dC)", 739 (uintmax_t)(((uintmax_t)dp->secsize * 740 dp->sectors) / (1024*1024)), 741 (uintmax_t)dp->sectors, 742 dp->secsize, dp->heads, 743 dp->secs_per_track, dp->cylinders); 744 xpt_announce_periph(periph, announce_buf); 745 if (softc->flags & ADA_FLAG_CAN_NCQ) { 746 printf("%s%d: Native Command Queueing enabled\n", 747 periph->periph_name, periph->unit_number); 748 } 749 750 /* 751 * Add async callbacks for bus reset and 752 * bus device reset calls. I don't bother 753 * checking if this fails as, in most cases, 754 * the system will function just fine without 755 * them and the only alternative would be to 756 * not attach the device on failure. 757 */ 758 xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE, 759 adaasync, periph, periph->path); 760 761 /* 762 * Take an exclusive refcount on the periph while adastart is called 763 * to finish the probe. The reference will be dropped in adadone at 764 * the end of probe. 765 */ 766 // (void)cam_periph_hold(periph, PRIBIO); 767 // xpt_schedule(periph, /*priority*/5); 768 769 /* 770 * Schedule a periodic event to occasionally send an 771 * ordered tag to a device. 772 */ 773 callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0); 774 callout_reset(&softc->sendordered_c, 775 (ADA_DEFAULT_TIMEOUT * hz) / ADA_ORDEREDTAG_INTERVAL, 776 adasendorderedtag, softc); 777 778 return(CAM_REQ_CMP); 779 } 780 781 static void 782 adastart(struct cam_periph *periph, union ccb *start_ccb) 783 { 784 struct ada_softc *softc; 785 786 softc = (struct ada_softc *)periph->softc; 787 788 switch (softc->state) { 789 case ADA_STATE_NORMAL: 790 { 791 /* Pull a buffer from the queue and get going on it */ 792 struct bio *bp; 793 794 /* 795 * See if there is a buf with work for us to do.. 796 */ 797 bp = bioq_first(&softc->bio_queue); 798 if (periph->immediate_priority <= periph->pinfo.priority) { 799 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 800 ("queuing for immediate ccb\n")); 801 start_ccb->ccb_h.ccb_state = ADA_CCB_WAITING; 802 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 803 periph_links.sle); 804 periph->immediate_priority = CAM_PRIORITY_NONE; 805 wakeup(&periph->ccb_list); 806 } else if (bp == NULL) { 807 xpt_release_ccb(start_ccb); 808 } else { 809 struct ccb_ataio *ataio = &start_ccb->ataio; 810 u_int8_t tag_code; 811 812 bioq_remove(&softc->bio_queue, bp); 813 814 if ((softc->flags & ADA_FLAG_NEED_OTAG) != 0) { 815 softc->flags &= ~ADA_FLAG_NEED_OTAG; 816 softc->ordered_tag_count++; 817 tag_code = 0;//MSG_ORDERED_Q_TAG; 818 } else { 819 tag_code = 0;//MSG_SIMPLE_Q_TAG; 820 } 821 switch (bp->bio_cmd) { 822 case BIO_READ: 823 case BIO_WRITE: 824 { 825 uint64_t lba = bp->bio_pblkno; 826 uint16_t count = bp->bio_bcount / softc->params.secsize; 827 828 cam_fill_ataio(ataio, 829 ada_retry_count, 830 adadone, 831 bp->bio_cmd == BIO_READ ? 832 CAM_DIR_IN : CAM_DIR_OUT, 833 tag_code, 834 bp->bio_data, 835 bp->bio_bcount, 836 ada_default_timeout*1000); 837 838 if (softc->flags & ADA_FLAG_CAN_NCQ) { 839 if (bp->bio_cmd == BIO_READ) { 840 ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED, 841 lba, count); 842 } else { 843 ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED, 844 lba, count); 845 } 846 } else if ((softc->flags & ADA_FLAG_CAN_48BIT) && 847 (lba + count >= ATA_MAX_28BIT_LBA || 848 count >= 256)) { 849 if (bp->bio_cmd == BIO_READ) { 850 ata_48bit_cmd(ataio, ATA_READ_DMA48, 851 0, lba, count); 852 } else { 853 ata_48bit_cmd(ataio, ATA_WRITE_DMA48, 854 0, lba, count); 855 } 856 } else { 857 if (bp->bio_cmd == BIO_READ) { 858 ata_36bit_cmd(ataio, ATA_READ_DMA, 859 0, lba, count); 860 } else { 861 ata_36bit_cmd(ataio, ATA_WRITE_DMA, 862 0, lba, count); 863 } 864 } 865 } 866 break; 867 case BIO_FLUSH: 868 cam_fill_ataio(ataio, 869 1, 870 adadone, 871 CAM_DIR_NONE, 872 tag_code, 873 NULL, 874 0, 875 ada_default_timeout*1000); 876 877 if (softc->flags & ADA_FLAG_CAN_48BIT) 878 ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0); 879 else 880 ata_48bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0); 881 break; 882 } 883 start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO; 884 885 /* 886 * Block out any asyncronous callbacks 887 * while we touch the pending ccb list. 888 */ 889 LIST_INSERT_HEAD(&softc->pending_ccbs, 890 &start_ccb->ccb_h, periph_links.le); 891 softc->outstanding_cmds++; 892 893 /* We expect a unit attention from this device */ 894 if ((softc->flags & ADA_FLAG_RETRY_UA) != 0) { 895 start_ccb->ccb_h.ccb_state |= ADA_CCB_RETRY_UA; 896 softc->flags &= ~ADA_FLAG_RETRY_UA; 897 } 898 899 start_ccb->ccb_h.ccb_bp = bp; 900 bp = bioq_first(&softc->bio_queue); 901 902 xpt_action(start_ccb); 903 } 904 905 if (bp != NULL) { 906 /* Have more work to do, so ensure we stay scheduled */ 907 xpt_schedule(periph, /* XXX priority */1); 908 } 909 break; 910 } 911 } 912 } 913 914 static void 915 adadone(struct cam_periph *periph, union ccb *done_ccb) 916 { 917 struct ada_softc *softc; 918 struct ccb_ataio *ataio; 919 920 softc = (struct ada_softc *)periph->softc; 921 ataio = &done_ccb->ataio; 922 switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) { 923 case ADA_CCB_BUFFER_IO: 924 { 925 struct bio *bp; 926 927 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 928 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 929 int error; 930 931 error = adaerror(done_ccb, CAM_RETRY_SELTO, 0); 932 if (error == ERESTART) { 933 /* 934 * A retry was scheuled, so 935 * just return. 936 */ 937 return; 938 } 939 if (error != 0) { 940 941 if (error == ENXIO) { 942 /* 943 * Catastrophic error. Mark our pack as 944 * invalid. 945 */ 946 /* 947 * XXX See if this is really a media 948 * XXX change first? 949 */ 950 xpt_print(periph->path, 951 "Invalidating pack\n"); 952 softc->flags |= ADA_FLAG_PACK_INVALID; 953 } 954 955 /* 956 * return all queued I/O with EIO, so that 957 * the client can retry these I/Os in the 958 * proper order should it attempt to recover. 959 */ 960 bioq_flush(&softc->bio_queue, NULL, EIO); 961 bp->bio_error = error; 962 bp->bio_resid = bp->bio_bcount; 963 bp->bio_flags |= BIO_ERROR; 964 } else { 965 bp->bio_resid = ataio->resid; 966 bp->bio_error = 0; 967 if (bp->bio_resid != 0) 968 bp->bio_flags |= BIO_ERROR; 969 } 970 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 971 cam_release_devq(done_ccb->ccb_h.path, 972 /*relsim_flags*/0, 973 /*reduction*/0, 974 /*timeout*/0, 975 /*getcount_only*/0); 976 } else { 977 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 978 panic("REQ_CMP with QFRZN"); 979 bp->bio_resid = ataio->resid; 980 if (ataio->resid > 0) 981 bp->bio_flags |= BIO_ERROR; 982 } 983 984 /* 985 * Block out any asyncronous callbacks 986 * while we touch the pending ccb list. 987 */ 988 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 989 softc->outstanding_cmds--; 990 if (softc->outstanding_cmds == 0) 991 softc->flags |= ADA_FLAG_WENT_IDLE; 992 993 biodone(bp); 994 break; 995 } 996 case ADA_CCB_WAITING: 997 { 998 /* Caller will release the CCB */ 999 wakeup(&done_ccb->ccb_h.cbfcnp); 1000 return; 1001 } 1002 case ADA_CCB_DUMP: 1003 /* No-op. We're polling */ 1004 return; 1005 default: 1006 break; 1007 } 1008 xpt_release_ccb(done_ccb); 1009 } 1010 1011 static int 1012 adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) 1013 { 1014 struct ada_softc *softc; 1015 struct cam_periph *periph; 1016 1017 periph = xpt_path_periph(ccb->ccb_h.path); 1018 softc = (struct ada_softc *)periph->softc; 1019 1020 return(cam_periph_error(ccb, cam_flags, sense_flags, 1021 &softc->saved_ccb)); 1022 } 1023 1024 static void 1025 adasetgeom(struct cam_periph *periph, struct ccb_getdev *cgd) 1026 { 1027 struct ada_softc *softc = (struct ada_softc *)periph->softc; 1028 struct disk_params *dp = &softc->params; 1029 u_int64_t lbasize48; 1030 u_int32_t lbasize; 1031 1032 dp->secsize = 512; 1033 if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) && 1034 cgd->ident_data.current_heads && cgd->ident_data.current_sectors) { 1035 dp->heads = cgd->ident_data.current_heads; 1036 dp->secs_per_track = cgd->ident_data.current_sectors; 1037 dp->cylinders = cgd->ident_data.cylinders; 1038 dp->sectors = (u_int32_t)cgd->ident_data.current_size_1 | 1039 ((u_int32_t)cgd->ident_data.current_size_2 << 16); 1040 } else { 1041 dp->heads = cgd->ident_data.heads; 1042 dp->secs_per_track = cgd->ident_data.sectors; 1043 dp->cylinders = cgd->ident_data.cylinders; 1044 dp->sectors = cgd->ident_data.cylinders * dp->heads * dp->secs_per_track; 1045 } 1046 lbasize = (u_int32_t)cgd->ident_data.lba_size_1 | 1047 ((u_int32_t)cgd->ident_data.lba_size_2 << 16); 1048 1049 /* does this device need oldstyle CHS addressing */ 1050 // if (!ad_version(cgd->ident_data.version_major) || !lbasize) 1051 // atadev->flags |= ATA_D_USE_CHS; 1052 1053 /* use the 28bit LBA size if valid or bigger than the CHS mapping */ 1054 if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize) 1055 dp->sectors = lbasize; 1056 1057 /* use the 48bit LBA size if valid */ 1058 lbasize48 = ((u_int64_t)cgd->ident_data.lba_size48_1) | 1059 ((u_int64_t)cgd->ident_data.lba_size48_2 << 16) | 1060 ((u_int64_t)cgd->ident_data.lba_size48_3 << 32) | 1061 ((u_int64_t)cgd->ident_data.lba_size48_4 << 48); 1062 if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) && 1063 lbasize48 > ATA_MAX_28BIT_LBA) 1064 dp->sectors = lbasize48; 1065 } 1066 1067 static void 1068 adasendorderedtag(void *arg) 1069 { 1070 struct ada_softc *softc = arg; 1071 1072 if (ada_send_ordered) { 1073 if ((softc->ordered_tag_count == 0) 1074 && ((softc->flags & ADA_FLAG_WENT_IDLE) == 0)) { 1075 softc->flags |= ADA_FLAG_NEED_OTAG; 1076 } 1077 if (softc->outstanding_cmds > 0) 1078 softc->flags &= ~ADA_FLAG_WENT_IDLE; 1079 1080 softc->ordered_tag_count = 0; 1081 } 1082 /* Queue us up again */ 1083 callout_reset(&softc->sendordered_c, 1084 (ADA_DEFAULT_TIMEOUT * hz) / ADA_ORDEREDTAG_INTERVAL, 1085 adasendorderedtag, softc); 1086 } 1087 1088 /* 1089 * Step through all ADA peripheral drivers, and if the device is still open, 1090 * sync the disk cache to physical media. 1091 */ 1092 static void 1093 adashutdown(void * arg, int howto) 1094 { 1095 struct cam_periph *periph; 1096 struct ada_softc *softc; 1097 1098 TAILQ_FOREACH(periph, &adadriver.units, unit_links) { 1099 union ccb ccb; 1100 1101 cam_periph_lock(periph); 1102 softc = (struct ada_softc *)periph->softc; 1103 /* 1104 * We only sync the cache if the drive is still open, and 1105 * if the drive is capable of it.. 1106 */ 1107 if (((softc->flags & ADA_FLAG_OPEN) == 0) || 1108 (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) { 1109 cam_periph_unlock(periph); 1110 continue; 1111 } 1112 1113 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1); 1114 1115 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 1116 cam_fill_ataio(&ccb.ataio, 1117 1, 1118 adadone, 1119 CAM_DIR_NONE, 1120 0, 1121 NULL, 1122 0, 1123 ada_default_timeout*1000); 1124 1125 if (softc->flags & ADA_FLAG_CAN_48BIT) 1126 ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0); 1127 else 1128 ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); 1129 xpt_polled_action(&ccb); 1130 1131 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 1132 xpt_print(periph->path, "Synchronize cache failed\n"); 1133 1134 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) 1135 cam_release_devq(ccb.ccb_h.path, 1136 /*relsim_flags*/0, 1137 /*reduction*/0, 1138 /*timeout*/0, 1139 /*getcount_only*/0); 1140 cam_periph_unlock(periph); 1141 } 1142 } 1143 1144 #endif /* _KERNEL */ 1145