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 "opt_ada.h" 31 #include "opt_ata.h" 32 33 #include <sys/param.h> 34 35 #ifdef _KERNEL 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/bio.h> 39 #include <sys/sysctl.h> 40 #include <sys/taskqueue.h> 41 #include <sys/lock.h> 42 #include <sys/mutex.h> 43 #include <sys/conf.h> 44 #include <sys/devicestat.h> 45 #include <sys/eventhandler.h> 46 #include <sys/malloc.h> 47 #include <sys/cons.h> 48 #include <sys/reboot.h> 49 #include <geom/geom_disk.h> 50 #endif /* _KERNEL */ 51 52 #ifndef _KERNEL 53 #include <stdio.h> 54 #include <string.h> 55 #endif /* _KERNEL */ 56 57 #include <cam/cam.h> 58 #include <cam/cam_ccb.h> 59 #include <cam/cam_periph.h> 60 #include <cam/cam_xpt_periph.h> 61 #include <cam/cam_sim.h> 62 63 #include <cam/ata/ata_all.h> 64 65 #include <machine/md_var.h> /* geometry translation */ 66 67 #ifdef _KERNEL 68 69 #define ATA_MAX_28BIT_LBA 268435455UL 70 71 typedef enum { 72 ADA_STATE_RAHEAD, 73 ADA_STATE_WCACHE, 74 ADA_STATE_NORMAL 75 } ada_state; 76 77 typedef enum { 78 ADA_FLAG_PACK_INVALID = 0x001, 79 ADA_FLAG_CAN_48BIT = 0x002, 80 ADA_FLAG_CAN_FLUSHCACHE = 0x004, 81 ADA_FLAG_CAN_NCQ = 0x008, 82 ADA_FLAG_CAN_DMA = 0x010, 83 ADA_FLAG_NEED_OTAG = 0x020, 84 ADA_FLAG_WENT_IDLE = 0x040, 85 ADA_FLAG_CAN_TRIM = 0x080, 86 ADA_FLAG_OPEN = 0x100, 87 ADA_FLAG_SCTX_INIT = 0x200, 88 ADA_FLAG_CAN_CFA = 0x400, 89 ADA_FLAG_CAN_POWERMGT = 0x800 90 } ada_flags; 91 92 typedef enum { 93 ADA_Q_NONE = 0x00, 94 ADA_Q_4K = 0x01, 95 } ada_quirks; 96 97 typedef enum { 98 ADA_CCB_RAHEAD = 0x01, 99 ADA_CCB_WCACHE = 0x02, 100 ADA_CCB_BUFFER_IO = 0x03, 101 ADA_CCB_WAITING = 0x04, 102 ADA_CCB_DUMP = 0x05, 103 ADA_CCB_TRIM = 0x06, 104 ADA_CCB_TYPE_MASK = 0x0F, 105 } ada_ccb_state; 106 107 /* Offsets into our private area for storing information */ 108 #define ccb_state ppriv_field0 109 #define ccb_bp ppriv_ptr1 110 111 struct disk_params { 112 u_int8_t heads; 113 u_int8_t secs_per_track; 114 u_int32_t cylinders; 115 u_int32_t secsize; /* Number of bytes/logical sector */ 116 u_int64_t sectors; /* Total number sectors */ 117 }; 118 119 #define TRIM_MAX_BLOCKS 8 120 #define TRIM_MAX_RANGES (TRIM_MAX_BLOCKS * 64) 121 #define TRIM_MAX_BIOS (TRIM_MAX_RANGES * 4) 122 struct trim_request { 123 uint8_t data[TRIM_MAX_RANGES * 8]; 124 struct bio *bps[TRIM_MAX_BIOS]; 125 }; 126 127 struct ada_softc { 128 struct bio_queue_head bio_queue; 129 struct bio_queue_head trim_queue; 130 ada_state state; 131 ada_flags flags; 132 ada_quirks quirks; 133 int ordered_tag_count; 134 int outstanding_cmds; 135 int trim_max_ranges; 136 int trim_running; 137 int read_ahead; 138 int write_cache; 139 #ifdef ADA_TEST_FAILURE 140 int force_read_error; 141 int force_write_error; 142 int periodic_read_error; 143 int periodic_read_count; 144 #endif 145 struct disk_params params; 146 struct disk *disk; 147 struct task sysctl_task; 148 struct sysctl_ctx_list sysctl_ctx; 149 struct sysctl_oid *sysctl_tree; 150 struct callout sendordered_c; 151 struct trim_request trim_req; 152 }; 153 154 struct ada_quirk_entry { 155 struct scsi_inquiry_pattern inq_pat; 156 ada_quirks quirks; 157 }; 158 159 static struct ada_quirk_entry ada_quirk_table[] = 160 { 161 { 162 /* Hitachi Advanced Format (4k) drives */ 163 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Hitachi H??????????E3*", "*" }, 164 /*quirks*/ADA_Q_4K 165 }, 166 { 167 /* Samsung Advanced Format (4k) drives */ 168 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD155UI*", "*" }, 169 /*quirks*/ADA_Q_4K 170 }, 171 { 172 /* Samsung Advanced Format (4k) drives */ 173 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD204UI*", "*" }, 174 /*quirks*/ADA_Q_4K 175 }, 176 { 177 /* Seagate Barracuda Green Advanced Format (4k) drives */ 178 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DL*", "*" }, 179 /*quirks*/ADA_Q_4K 180 }, 181 { 182 /* Seagate Barracuda Advanced Format (4k) drives */ 183 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???DM*", "*" }, 184 /*quirks*/ADA_Q_4K 185 }, 186 { 187 /* Seagate Barracuda Advanced Format (4k) drives */ 188 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DM*", "*" }, 189 /*quirks*/ADA_Q_4K 190 }, 191 { 192 /* Seagate Momentus Advanced Format (4k) drives */ 193 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500423AS*", "*" }, 194 /*quirks*/ADA_Q_4K 195 }, 196 { 197 /* Seagate Momentus Advanced Format (4k) drives */ 198 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500424AS*", "*" }, 199 /*quirks*/ADA_Q_4K 200 }, 201 { 202 /* Seagate Momentus Advanced Format (4k) drives */ 203 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640423AS*", "*" }, 204 /*quirks*/ADA_Q_4K 205 }, 206 { 207 /* Seagate Momentus Advanced Format (4k) drives */ 208 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640424AS*", "*" }, 209 /*quirks*/ADA_Q_4K 210 }, 211 { 212 /* Seagate Momentus Advanced Format (4k) drives */ 213 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750420AS*", "*" }, 214 /*quirks*/ADA_Q_4K 215 }, 216 { 217 /* Seagate Momentus Advanced Format (4k) drives */ 218 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750422AS*", "*" }, 219 /*quirks*/ADA_Q_4K 220 }, 221 { 222 /* Seagate Momentus Advanced Format (4k) drives */ 223 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750423AS*", "*" }, 224 /*quirks*/ADA_Q_4K 225 }, 226 { 227 /* Seagate Momentus Thin Advanced Format (4k) drives */ 228 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???LT*", "*" }, 229 /*quirks*/ADA_Q_4K 230 }, 231 { 232 /* WDC Caviar Green Advanced Format (4k) drives */ 233 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RS*", "*" }, 234 /*quirks*/ADA_Q_4K 235 }, 236 { 237 /* WDC Caviar Green Advanced Format (4k) drives */ 238 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RX*", "*" }, 239 /*quirks*/ADA_Q_4K 240 }, 241 { 242 /* WDC Caviar Green Advanced Format (4k) drives */ 243 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RS*", "*" }, 244 /*quirks*/ADA_Q_4K 245 }, 246 { 247 /* WDC Caviar Green Advanced Format (4k) drives */ 248 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RX*", "*" }, 249 /*quirks*/ADA_Q_4K 250 }, 251 { 252 /* WDC Scorpio Black Advanced Format (4k) drives */ 253 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PKT*", "*" }, 254 /*quirks*/ADA_Q_4K 255 }, 256 { 257 /* WDC Scorpio Black Advanced Format (4k) drives */ 258 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PKT*", "*" }, 259 /*quirks*/ADA_Q_4K 260 }, 261 { 262 /* WDC Scorpio Blue Advanced Format (4k) drives */ 263 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PVT*", "*" }, 264 /*quirks*/ADA_Q_4K 265 }, 266 { 267 /* WDC Scorpio Blue Advanced Format (4k) drives */ 268 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PVT*", "*" }, 269 /*quirks*/ADA_Q_4K 270 }, 271 { 272 /* Default */ 273 { 274 T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, 275 /*vendor*/"*", /*product*/"*", /*revision*/"*" 276 }, 277 /*quirks*/0 278 }, 279 }; 280 281 static disk_strategy_t adastrategy; 282 static dumper_t adadump; 283 static periph_init_t adainit; 284 static void adaasync(void *callback_arg, u_int32_t code, 285 struct cam_path *path, void *arg); 286 static void adasysctlinit(void *context, int pending); 287 static periph_ctor_t adaregister; 288 static periph_dtor_t adacleanup; 289 static periph_start_t adastart; 290 static periph_oninv_t adaoninvalidate; 291 static void adadone(struct cam_periph *periph, 292 union ccb *done_ccb); 293 static int adaerror(union ccb *ccb, u_int32_t cam_flags, 294 u_int32_t sense_flags); 295 static void adagetparams(struct cam_periph *periph, 296 struct ccb_getdev *cgd); 297 static timeout_t adasendorderedtag; 298 static void adashutdown(void *arg, int howto); 299 static void adasuspend(void *arg); 300 static void adaresume(void *arg); 301 302 #ifndef ADA_DEFAULT_LEGACY_ALIASES 303 #ifdef ATA_CAM 304 #define ADA_DEFAULT_LEGACY_ALIASES 1 305 #else 306 #define ADA_DEFAULT_LEGACY_ALIASES 0 307 #endif 308 #endif 309 310 #ifndef ADA_DEFAULT_TIMEOUT 311 #define ADA_DEFAULT_TIMEOUT 30 /* Timeout in seconds */ 312 #endif 313 314 #ifndef ADA_DEFAULT_RETRY 315 #define ADA_DEFAULT_RETRY 4 316 #endif 317 318 #ifndef ADA_DEFAULT_SEND_ORDERED 319 #define ADA_DEFAULT_SEND_ORDERED 1 320 #endif 321 322 #ifndef ADA_DEFAULT_SPINDOWN_SHUTDOWN 323 #define ADA_DEFAULT_SPINDOWN_SHUTDOWN 1 324 #endif 325 326 #ifndef ADA_DEFAULT_SPINDOWN_SUSPEND 327 #define ADA_DEFAULT_SPINDOWN_SUSPEND 1 328 #endif 329 330 #ifndef ADA_DEFAULT_READ_AHEAD 331 #define ADA_DEFAULT_READ_AHEAD 1 332 #endif 333 334 #ifndef ADA_DEFAULT_WRITE_CACHE 335 #define ADA_DEFAULT_WRITE_CACHE 1 336 #endif 337 338 #define ADA_RA (softc->read_ahead >= 0 ? \ 339 softc->read_ahead : ada_read_ahead) 340 #define ADA_WC (softc->write_cache >= 0 ? \ 341 softc->write_cache : ada_write_cache) 342 343 /* 344 * Most platforms map firmware geometry to actual, but some don't. If 345 * not overridden, default to nothing. 346 */ 347 #ifndef ata_disk_firmware_geom_adjust 348 #define ata_disk_firmware_geom_adjust(disk) 349 #endif 350 351 static int ada_legacy_aliases = ADA_DEFAULT_LEGACY_ALIASES; 352 static int ada_retry_count = ADA_DEFAULT_RETRY; 353 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT; 354 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED; 355 static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOWN_SHUTDOWN; 356 static int ada_spindown_suspend = ADA_DEFAULT_SPINDOWN_SUSPEND; 357 static int ada_read_ahead = ADA_DEFAULT_READ_AHEAD; 358 static int ada_write_cache = ADA_DEFAULT_WRITE_CACHE; 359 360 static SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0, 361 "CAM Direct Access Disk driver"); 362 SYSCTL_INT(_kern_cam_ada, OID_AUTO, legacy_aliases, CTLFLAG_RW, 363 &ada_legacy_aliases, 0, "Create legacy-like device aliases"); 364 TUNABLE_INT("kern.cam.ada.legacy_aliases", &ada_legacy_aliases); 365 SYSCTL_INT(_kern_cam_ada, OID_AUTO, retry_count, CTLFLAG_RW, 366 &ada_retry_count, 0, "Normal I/O retry count"); 367 TUNABLE_INT("kern.cam.ada.retry_count", &ada_retry_count); 368 SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RW, 369 &ada_default_timeout, 0, "Normal I/O timeout (in seconds)"); 370 TUNABLE_INT("kern.cam.ada.default_timeout", &ada_default_timeout); 371 SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW, 372 &ada_send_ordered, 0, "Send Ordered Tags"); 373 TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered); 374 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RW, 375 &ada_spindown_shutdown, 0, "Spin down upon shutdown"); 376 TUNABLE_INT("kern.cam.ada.spindown_shutdown", &ada_spindown_shutdown); 377 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_suspend, CTLFLAG_RW, 378 &ada_spindown_suspend, 0, "Spin down upon suspend"); 379 TUNABLE_INT("kern.cam.ada.spindown_suspend", &ada_spindown_suspend); 380 SYSCTL_INT(_kern_cam_ada, OID_AUTO, read_ahead, CTLFLAG_RW, 381 &ada_read_ahead, 0, "Enable disk read-ahead"); 382 TUNABLE_INT("kern.cam.ada.read_ahead", &ada_read_ahead); 383 SYSCTL_INT(_kern_cam_ada, OID_AUTO, write_cache, CTLFLAG_RW, 384 &ada_write_cache, 0, "Enable disk write cache"); 385 TUNABLE_INT("kern.cam.ada.write_cache", &ada_write_cache); 386 387 /* 388 * ADA_ORDEREDTAG_INTERVAL determines how often, relative 389 * to the default timeout, we check to see whether an ordered 390 * tagged transaction is appropriate to prevent simple tag 391 * starvation. Since we'd like to ensure that there is at least 392 * 1/2 of the timeout length left for a starved transaction to 393 * complete after we've sent an ordered tag, we must poll at least 394 * four times in every timeout period. This takes care of the worst 395 * case where a starved transaction starts during an interval that 396 * meets the requirement "don't send an ordered tag" test so it takes 397 * us two intervals to determine that a tag must be sent. 398 */ 399 #ifndef ADA_ORDEREDTAG_INTERVAL 400 #define ADA_ORDEREDTAG_INTERVAL 4 401 #endif 402 403 static struct periph_driver adadriver = 404 { 405 adainit, "ada", 406 TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0 407 }; 408 409 PERIPHDRIVER_DECLARE(ada, adadriver); 410 411 static MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers"); 412 413 static int 414 adaopen(struct disk *dp) 415 { 416 struct cam_periph *periph; 417 struct ada_softc *softc; 418 int error; 419 420 periph = (struct cam_periph *)dp->d_drv1; 421 if (periph == NULL) { 422 return (ENXIO); 423 } 424 425 if (cam_periph_acquire(periph) != CAM_REQ_CMP) { 426 return(ENXIO); 427 } 428 429 cam_periph_lock(periph); 430 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { 431 cam_periph_unlock(periph); 432 cam_periph_release(periph); 433 return (error); 434 } 435 436 softc = (struct ada_softc *)periph->softc; 437 softc->flags |= ADA_FLAG_OPEN; 438 439 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 440 ("adaopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit, 441 periph->unit_number)); 442 443 if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) { 444 /* Invalidate our pack information. */ 445 softc->flags &= ~ADA_FLAG_PACK_INVALID; 446 } 447 448 cam_periph_unhold(periph); 449 cam_periph_unlock(periph); 450 return (0); 451 } 452 453 static int 454 adaclose(struct disk *dp) 455 { 456 struct cam_periph *periph; 457 struct ada_softc *softc; 458 union ccb *ccb; 459 int error; 460 461 periph = (struct cam_periph *)dp->d_drv1; 462 if (periph == NULL) 463 return (ENXIO); 464 465 cam_periph_lock(periph); 466 if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { 467 cam_periph_unlock(periph); 468 cam_periph_release(periph); 469 return (error); 470 } 471 472 softc = (struct ada_softc *)periph->softc; 473 /* We only sync the cache if the drive is capable of it. */ 474 if ((softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 && 475 (softc->flags & ADA_FLAG_PACK_INVALID) == 0) { 476 477 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 478 cam_fill_ataio(&ccb->ataio, 479 1, 480 adadone, 481 CAM_DIR_NONE, 482 0, 483 NULL, 484 0, 485 ada_default_timeout*1000); 486 487 if (softc->flags & ADA_FLAG_CAN_48BIT) 488 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0); 489 else 490 ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0); 491 cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0, 492 /*sense_flags*/0, softc->disk->d_devstat); 493 494 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 495 xpt_print(periph->path, "Synchronize cache failed\n"); 496 xpt_release_ccb(ccb); 497 } 498 499 softc->flags &= ~ADA_FLAG_OPEN; 500 cam_periph_unhold(periph); 501 cam_periph_unlock(periph); 502 cam_periph_release(periph); 503 return (0); 504 } 505 506 static void 507 adaschedule(struct cam_periph *periph) 508 { 509 struct ada_softc *softc = (struct ada_softc *)periph->softc; 510 uint32_t prio; 511 512 /* Check if cam_periph_getccb() was called. */ 513 prio = periph->immediate_priority; 514 515 /* Check if we have more work to do. */ 516 if (bioq_first(&softc->bio_queue) || 517 (!softc->trim_running && bioq_first(&softc->trim_queue))) { 518 prio = CAM_PRIORITY_NORMAL; 519 } 520 521 /* Schedule CCB if any of above is true. */ 522 if (prio != CAM_PRIORITY_NONE) 523 xpt_schedule(periph, prio); 524 } 525 526 /* 527 * Actually translate the requested transfer into one the physical driver 528 * can understand. The transfer is described by a buf and will include 529 * only one physical transfer. 530 */ 531 static void 532 adastrategy(struct bio *bp) 533 { 534 struct cam_periph *periph; 535 struct ada_softc *softc; 536 537 periph = (struct cam_periph *)bp->bio_disk->d_drv1; 538 if (periph == NULL) { 539 biofinish(bp, NULL, ENXIO); 540 return; 541 } 542 softc = (struct ada_softc *)periph->softc; 543 544 cam_periph_lock(periph); 545 546 /* 547 * If the device has been made invalid, error out 548 */ 549 if ((softc->flags & ADA_FLAG_PACK_INVALID)) { 550 cam_periph_unlock(periph); 551 biofinish(bp, NULL, ENXIO); 552 return; 553 } 554 555 /* 556 * Place it in the queue of disk activities for this disk 557 */ 558 if (bp->bio_cmd == BIO_DELETE && 559 (softc->flags & ADA_FLAG_CAN_TRIM)) 560 bioq_disksort(&softc->trim_queue, bp); 561 else 562 bioq_disksort(&softc->bio_queue, bp); 563 564 /* 565 * Schedule ourselves for performing the work. 566 */ 567 adaschedule(periph); 568 cam_periph_unlock(periph); 569 570 return; 571 } 572 573 static int 574 adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) 575 { 576 struct cam_periph *periph; 577 struct ada_softc *softc; 578 u_int secsize; 579 union ccb ccb; 580 struct disk *dp; 581 uint64_t lba; 582 uint16_t count; 583 584 dp = arg; 585 periph = dp->d_drv1; 586 if (periph == NULL) 587 return (ENXIO); 588 softc = (struct ada_softc *)periph->softc; 589 cam_periph_lock(periph); 590 secsize = softc->params.secsize; 591 lba = offset / secsize; 592 count = length / secsize; 593 594 if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) { 595 cam_periph_unlock(periph); 596 return (ENXIO); 597 } 598 599 if (length > 0) { 600 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 601 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 602 cam_fill_ataio(&ccb.ataio, 603 0, 604 adadone, 605 CAM_DIR_OUT, 606 0, 607 (u_int8_t *) virtual, 608 length, 609 ada_default_timeout*1000); 610 if ((softc->flags & ADA_FLAG_CAN_48BIT) && 611 (lba + count >= ATA_MAX_28BIT_LBA || 612 count >= 256)) { 613 ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48, 614 0, lba, count); 615 } else { 616 ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA, 617 0, lba, count); 618 } 619 xpt_polled_action(&ccb); 620 621 if ((ccb.ataio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 622 printf("Aborting dump due to I/O error.\n"); 623 cam_periph_unlock(periph); 624 return(EIO); 625 } 626 cam_periph_unlock(periph); 627 return(0); 628 } 629 630 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) { 631 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 632 633 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 634 cam_fill_ataio(&ccb.ataio, 635 1, 636 adadone, 637 CAM_DIR_NONE, 638 0, 639 NULL, 640 0, 641 ada_default_timeout*1000); 642 643 if (softc->flags & ADA_FLAG_CAN_48BIT) 644 ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0); 645 else 646 ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); 647 xpt_polled_action(&ccb); 648 649 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 650 xpt_print(periph->path, "Synchronize cache failed\n"); 651 652 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) 653 cam_release_devq(ccb.ccb_h.path, 654 /*relsim_flags*/0, 655 /*reduction*/0, 656 /*timeout*/0, 657 /*getcount_only*/0); 658 } 659 cam_periph_unlock(periph); 660 return (0); 661 } 662 663 static void 664 adainit(void) 665 { 666 cam_status status; 667 668 /* 669 * Install a global async callback. This callback will 670 * receive async callbacks like "new device found". 671 */ 672 status = xpt_register_async(AC_FOUND_DEVICE, adaasync, NULL, NULL); 673 674 if (status != CAM_REQ_CMP) { 675 printf("ada: Failed to attach master async callback " 676 "due to status 0x%x!\n", status); 677 } else if (ada_send_ordered) { 678 679 /* Register our event handlers */ 680 if ((EVENTHANDLER_REGISTER(power_suspend, adasuspend, 681 NULL, EVENTHANDLER_PRI_LAST)) == NULL) 682 printf("adainit: power event registration failed!\n"); 683 if ((EVENTHANDLER_REGISTER(power_resume, adaresume, 684 NULL, EVENTHANDLER_PRI_LAST)) == NULL) 685 printf("adainit: power event registration failed!\n"); 686 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, adashutdown, 687 NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) 688 printf("adainit: shutdown event registration failed!\n"); 689 } 690 } 691 692 static void 693 adaoninvalidate(struct cam_periph *periph) 694 { 695 struct ada_softc *softc; 696 697 softc = (struct ada_softc *)periph->softc; 698 699 /* 700 * De-register any async callbacks. 701 */ 702 xpt_register_async(0, adaasync, periph, periph->path); 703 704 softc->flags |= ADA_FLAG_PACK_INVALID; 705 706 /* 707 * Return all queued I/O with ENXIO. 708 * XXX Handle any transactions queued to the card 709 * with XPT_ABORT_CCB. 710 */ 711 bioq_flush(&softc->bio_queue, NULL, ENXIO); 712 bioq_flush(&softc->trim_queue, NULL, ENXIO); 713 714 disk_gone(softc->disk); 715 xpt_print(periph->path, "lost device\n"); 716 } 717 718 static void 719 adacleanup(struct cam_periph *periph) 720 { 721 struct ada_softc *softc; 722 723 softc = (struct ada_softc *)periph->softc; 724 725 xpt_print(periph->path, "removing device entry\n"); 726 cam_periph_unlock(periph); 727 728 /* 729 * If we can't free the sysctl tree, oh well... 730 */ 731 if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0 732 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) { 733 xpt_print(periph->path, "can't remove sysctl context\n"); 734 } 735 736 disk_destroy(softc->disk); 737 callout_drain(&softc->sendordered_c); 738 free(softc, M_DEVBUF); 739 cam_periph_lock(periph); 740 } 741 742 static void 743 adaasync(void *callback_arg, u_int32_t code, 744 struct cam_path *path, void *arg) 745 { 746 struct cam_periph *periph; 747 struct ada_softc *softc; 748 749 periph = (struct cam_periph *)callback_arg; 750 switch (code) { 751 case AC_FOUND_DEVICE: 752 { 753 struct ccb_getdev *cgd; 754 cam_status status; 755 756 cgd = (struct ccb_getdev *)arg; 757 if (cgd == NULL) 758 break; 759 760 if (cgd->protocol != PROTO_ATA) 761 break; 762 763 /* 764 * Allocate a peripheral instance for 765 * this device and start the probe 766 * process. 767 */ 768 status = cam_periph_alloc(adaregister, adaoninvalidate, 769 adacleanup, adastart, 770 "ada", CAM_PERIPH_BIO, 771 cgd->ccb_h.path, adaasync, 772 AC_FOUND_DEVICE, cgd); 773 774 if (status != CAM_REQ_CMP 775 && status != CAM_REQ_INPROG) 776 printf("adaasync: Unable to attach to new device " 777 "due to status 0x%x\n", status); 778 break; 779 } 780 case AC_SENT_BDR: 781 case AC_BUS_RESET: 782 { 783 struct ccb_getdev cgd; 784 785 softc = (struct ada_softc *)periph->softc; 786 cam_periph_async(periph, code, path, arg); 787 if (softc->state != ADA_STATE_NORMAL) 788 break; 789 xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 790 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 791 xpt_action((union ccb *)&cgd); 792 if (ADA_RA >= 0 && 793 cgd.ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD) 794 softc->state = ADA_STATE_RAHEAD; 795 else if (ADA_WC >= 0 && 796 cgd.ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) 797 softc->state = ADA_STATE_WCACHE; 798 else 799 break; 800 cam_periph_acquire(periph); 801 cam_freeze_devq_arg(periph->path, 802 RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1); 803 xpt_schedule(periph, CAM_PRIORITY_DEV); 804 } 805 default: 806 cam_periph_async(periph, code, path, arg); 807 break; 808 } 809 } 810 811 static void 812 adasysctlinit(void *context, int pending) 813 { 814 struct cam_periph *periph; 815 struct ada_softc *softc; 816 char tmpstr[80], tmpstr2[80]; 817 818 periph = (struct cam_periph *)context; 819 820 /* periph was held for us when this task was enqueued */ 821 if (periph->flags & CAM_PERIPH_INVALID) { 822 cam_periph_release(periph); 823 return; 824 } 825 826 softc = (struct ada_softc *)periph->softc; 827 snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d", periph->unit_number); 828 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); 829 830 sysctl_ctx_init(&softc->sysctl_ctx); 831 softc->flags |= ADA_FLAG_SCTX_INIT; 832 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 833 SYSCTL_STATIC_CHILDREN(_kern_cam_ada), OID_AUTO, tmpstr2, 834 CTLFLAG_RD, 0, tmpstr); 835 if (softc->sysctl_tree == NULL) { 836 printf("adasysctlinit: unable to allocate sysctl tree\n"); 837 cam_periph_release(periph); 838 return; 839 } 840 841 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 842 OID_AUTO, "read_ahead", CTLFLAG_RW | CTLFLAG_MPSAFE, 843 &softc->read_ahead, 0, "Enable disk read ahead."); 844 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 845 OID_AUTO, "write_cache", CTLFLAG_RW | CTLFLAG_MPSAFE, 846 &softc->write_cache, 0, "Enable disk write cache."); 847 #ifdef ADA_TEST_FAILURE 848 /* 849 * Add a 'door bell' sysctl which allows one to set it from userland 850 * and cause something bad to happen. For the moment, we only allow 851 * whacking the next read or write. 852 */ 853 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 854 OID_AUTO, "force_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE, 855 &softc->force_read_error, 0, 856 "Force a read error for the next N reads."); 857 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 858 OID_AUTO, "force_write_error", CTLFLAG_RW | CTLFLAG_MPSAFE, 859 &softc->force_write_error, 0, 860 "Force a write error for the next N writes."); 861 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 862 OID_AUTO, "periodic_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE, 863 &softc->periodic_read_error, 0, 864 "Force a read error every N reads (don't set too low)."); 865 #endif 866 cam_periph_release(periph); 867 } 868 869 static int 870 adagetattr(struct bio *bp) 871 { 872 int ret = -1; 873 struct cam_periph *periph; 874 875 if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL) 876 return ENXIO; 877 periph = (struct cam_periph *)bp->bio_disk->d_drv1; 878 if (periph->path == NULL) 879 return ENXIO; 880 881 ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute, 882 periph->path); 883 if (ret == 0) 884 bp->bio_completed = bp->bio_length; 885 return ret; 886 } 887 888 static cam_status 889 adaregister(struct cam_periph *periph, void *arg) 890 { 891 struct ada_softc *softc; 892 struct ccb_pathinq cpi; 893 struct ccb_getdev *cgd; 894 char announce_buf[80], buf1[32]; 895 struct disk_params *dp; 896 caddr_t match; 897 u_int maxio; 898 int legacy_id, quirks; 899 900 cgd = (struct ccb_getdev *)arg; 901 if (periph == NULL) { 902 printf("adaregister: periph was NULL!!\n"); 903 return(CAM_REQ_CMP_ERR); 904 } 905 906 if (cgd == NULL) { 907 printf("adaregister: no getdev CCB, can't register device\n"); 908 return(CAM_REQ_CMP_ERR); 909 } 910 911 softc = (struct ada_softc *)malloc(sizeof(*softc), M_DEVBUF, 912 M_NOWAIT|M_ZERO); 913 914 if (softc == NULL) { 915 printf("adaregister: Unable to probe new device. " 916 "Unable to allocate softc\n"); 917 return(CAM_REQ_CMP_ERR); 918 } 919 920 bioq_init(&softc->bio_queue); 921 bioq_init(&softc->trim_queue); 922 923 if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA && 924 (cgd->inq_flags & SID_DMA)) 925 softc->flags |= ADA_FLAG_CAN_DMA; 926 if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) 927 softc->flags |= ADA_FLAG_CAN_48BIT; 928 if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE) 929 softc->flags |= ADA_FLAG_CAN_FLUSHCACHE; 930 if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT) 931 softc->flags |= ADA_FLAG_CAN_POWERMGT; 932 if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ && 933 (cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue)) 934 softc->flags |= ADA_FLAG_CAN_NCQ; 935 if (cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) { 936 softc->flags |= ADA_FLAG_CAN_TRIM; 937 softc->trim_max_ranges = TRIM_MAX_RANGES; 938 if (cgd->ident_data.max_dsm_blocks != 0) { 939 softc->trim_max_ranges = 940 min(cgd->ident_data.max_dsm_blocks * 64, 941 softc->trim_max_ranges); 942 } 943 } 944 if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA) 945 softc->flags |= ADA_FLAG_CAN_CFA; 946 947 periph->softc = softc; 948 949 /* 950 * See if this device has any quirks. 951 */ 952 match = cam_quirkmatch((caddr_t)&cgd->ident_data, 953 (caddr_t)ada_quirk_table, 954 sizeof(ada_quirk_table)/sizeof(*ada_quirk_table), 955 sizeof(*ada_quirk_table), ata_identify_match); 956 if (match != NULL) 957 softc->quirks = ((struct ada_quirk_entry *)match)->quirks; 958 else 959 softc->quirks = ADA_Q_NONE; 960 961 bzero(&cpi, sizeof(cpi)); 962 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); 963 cpi.ccb_h.func_code = XPT_PATH_INQ; 964 xpt_action((union ccb *)&cpi); 965 966 TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph); 967 968 /* 969 * Register this media as a disk 970 */ 971 (void)cam_periph_hold(periph, PRIBIO); 972 mtx_unlock(periph->sim->mtx); 973 snprintf(announce_buf, sizeof(announce_buf), 974 "kern.cam.ada.%d.quirks", periph->unit_number); 975 quirks = softc->quirks; 976 TUNABLE_INT_FETCH(announce_buf, &quirks); 977 softc->quirks = quirks; 978 softc->read_ahead = -1; 979 snprintf(announce_buf, sizeof(announce_buf), 980 "kern.cam.ada.%d.read_ahead", periph->unit_number); 981 TUNABLE_INT_FETCH(announce_buf, &softc->read_ahead); 982 softc->write_cache = -1; 983 snprintf(announce_buf, sizeof(announce_buf), 984 "kern.cam.ada.%d.write_cache", periph->unit_number); 985 TUNABLE_INT_FETCH(announce_buf, &softc->write_cache); 986 adagetparams(periph, cgd); 987 softc->disk = disk_alloc(); 988 softc->disk->d_devstat = devstat_new_entry(periph->periph_name, 989 periph->unit_number, softc->params.secsize, 990 DEVSTAT_ALL_SUPPORTED, 991 DEVSTAT_TYPE_DIRECT | 992 XPORT_DEVSTAT_TYPE(cpi.transport), 993 DEVSTAT_PRIORITY_DISK); 994 softc->disk->d_open = adaopen; 995 softc->disk->d_close = adaclose; 996 softc->disk->d_strategy = adastrategy; 997 softc->disk->d_getattr = adagetattr; 998 softc->disk->d_dump = adadump; 999 softc->disk->d_name = "ada"; 1000 softc->disk->d_drv1 = periph; 1001 maxio = cpi.maxio; /* Honor max I/O size of SIM */ 1002 if (maxio == 0) 1003 maxio = DFLTPHYS; /* traditional default */ 1004 else if (maxio > MAXPHYS) 1005 maxio = MAXPHYS; /* for safety */ 1006 if (softc->flags & ADA_FLAG_CAN_48BIT) 1007 maxio = min(maxio, 65536 * softc->params.secsize); 1008 else /* 28bit ATA command limit */ 1009 maxio = min(maxio, 256 * softc->params.secsize); 1010 softc->disk->d_maxsize = maxio; 1011 softc->disk->d_unit = periph->unit_number; 1012 softc->disk->d_flags = 0; 1013 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) 1014 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; 1015 if ((softc->flags & ADA_FLAG_CAN_TRIM) || 1016 ((softc->flags & ADA_FLAG_CAN_CFA) && 1017 !(softc->flags & ADA_FLAG_CAN_48BIT))) 1018 softc->disk->d_flags |= DISKFLAG_CANDELETE; 1019 strlcpy(softc->disk->d_descr, cgd->ident_data.model, 1020 MIN(sizeof(softc->disk->d_descr), sizeof(cgd->ident_data.model))); 1021 softc->disk->d_hba_vendor = cpi.hba_vendor; 1022 softc->disk->d_hba_device = cpi.hba_device; 1023 softc->disk->d_hba_subvendor = cpi.hba_subvendor; 1024 softc->disk->d_hba_subdevice = cpi.hba_subdevice; 1025 1026 softc->disk->d_sectorsize = softc->params.secsize; 1027 softc->disk->d_mediasize = (off_t)softc->params.sectors * 1028 softc->params.secsize; 1029 if (ata_physical_sector_size(&cgd->ident_data) != 1030 softc->params.secsize) { 1031 softc->disk->d_stripesize = 1032 ata_physical_sector_size(&cgd->ident_data); 1033 softc->disk->d_stripeoffset = (softc->disk->d_stripesize - 1034 ata_logical_sector_offset(&cgd->ident_data)) % 1035 softc->disk->d_stripesize; 1036 } else if (softc->quirks & ADA_Q_4K) { 1037 softc->disk->d_stripesize = 4096; 1038 softc->disk->d_stripeoffset = 0; 1039 } 1040 softc->disk->d_fwsectors = softc->params.secs_per_track; 1041 softc->disk->d_fwheads = softc->params.heads; 1042 ata_disk_firmware_geom_adjust(softc->disk); 1043 1044 if (ada_legacy_aliases) { 1045 #ifdef ATA_STATIC_ID 1046 legacy_id = xpt_path_legacy_ata_id(periph->path); 1047 #else 1048 legacy_id = softc->disk->d_unit; 1049 #endif 1050 if (legacy_id >= 0) { 1051 snprintf(announce_buf, sizeof(announce_buf), 1052 "kern.devalias.%s%d", 1053 softc->disk->d_name, softc->disk->d_unit); 1054 snprintf(buf1, sizeof(buf1), 1055 "ad%d", legacy_id); 1056 setenv(announce_buf, buf1); 1057 } 1058 } else 1059 legacy_id = -1; 1060 disk_create(softc->disk, DISK_VERSION); 1061 mtx_lock(periph->sim->mtx); 1062 cam_periph_unhold(periph); 1063 1064 dp = &softc->params; 1065 snprintf(announce_buf, sizeof(announce_buf), 1066 "%juMB (%ju %u byte sectors: %dH %dS/T %dC)", 1067 (uintmax_t)(((uintmax_t)dp->secsize * 1068 dp->sectors) / (1024*1024)), 1069 (uintmax_t)dp->sectors, 1070 dp->secsize, dp->heads, 1071 dp->secs_per_track, dp->cylinders); 1072 xpt_announce_periph(periph, announce_buf); 1073 if (legacy_id >= 0) 1074 printf("%s%d: Previously was known as ad%d\n", 1075 periph->periph_name, periph->unit_number, legacy_id); 1076 1077 /* 1078 * Create our sysctl variables, now that we know 1079 * we have successfully attached. 1080 */ 1081 cam_periph_acquire(periph); 1082 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task); 1083 1084 /* 1085 * Add async callbacks for bus reset and 1086 * bus device reset calls. I don't bother 1087 * checking if this fails as, in most cases, 1088 * the system will function just fine without 1089 * them and the only alternative would be to 1090 * not attach the device on failure. 1091 */ 1092 xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE, 1093 adaasync, periph, periph->path); 1094 1095 /* 1096 * Schedule a periodic event to occasionally send an 1097 * ordered tag to a device. 1098 */ 1099 callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0); 1100 callout_reset(&softc->sendordered_c, 1101 (ADA_DEFAULT_TIMEOUT * hz) / ADA_ORDEREDTAG_INTERVAL, 1102 adasendorderedtag, softc); 1103 1104 if (ADA_RA >= 0 && 1105 cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD) { 1106 softc->state = ADA_STATE_RAHEAD; 1107 cam_periph_acquire(periph); 1108 cam_freeze_devq_arg(periph->path, 1109 RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1); 1110 xpt_schedule(periph, CAM_PRIORITY_DEV); 1111 } else if (ADA_WC >= 0 && 1112 cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) { 1113 softc->state = ADA_STATE_WCACHE; 1114 cam_periph_acquire(periph); 1115 cam_freeze_devq_arg(periph->path, 1116 RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1); 1117 xpt_schedule(periph, CAM_PRIORITY_DEV); 1118 } else 1119 softc->state = ADA_STATE_NORMAL; 1120 1121 return(CAM_REQ_CMP); 1122 } 1123 1124 static void 1125 adastart(struct cam_periph *periph, union ccb *start_ccb) 1126 { 1127 struct ada_softc *softc = (struct ada_softc *)periph->softc; 1128 struct ccb_ataio *ataio = &start_ccb->ataio; 1129 1130 switch (softc->state) { 1131 case ADA_STATE_NORMAL: 1132 { 1133 struct bio *bp; 1134 u_int8_t tag_code; 1135 1136 /* Execute immediate CCB if waiting. */ 1137 if (periph->immediate_priority <= periph->pinfo.priority) { 1138 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 1139 ("queuing for immediate ccb\n")); 1140 start_ccb->ccb_h.ccb_state = ADA_CCB_WAITING; 1141 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 1142 periph_links.sle); 1143 periph->immediate_priority = CAM_PRIORITY_NONE; 1144 wakeup(&periph->ccb_list); 1145 /* Have more work to do, so ensure we stay scheduled */ 1146 adaschedule(periph); 1147 break; 1148 } 1149 /* Run TRIM if not running yet. */ 1150 if (!softc->trim_running && 1151 (bp = bioq_first(&softc->trim_queue)) != 0) { 1152 struct trim_request *req = &softc->trim_req; 1153 struct bio *bp1; 1154 uint64_t lastlba = (uint64_t)-1; 1155 int bps = 0, c, lastcount = 0, off, ranges = 0; 1156 1157 softc->trim_running = 1; 1158 bzero(req, sizeof(*req)); 1159 bp1 = bp; 1160 do { 1161 uint64_t lba = bp1->bio_pblkno; 1162 int count = bp1->bio_bcount / 1163 softc->params.secsize; 1164 1165 bioq_remove(&softc->trim_queue, bp1); 1166 1167 /* Try to extend the previous range. */ 1168 if (lba == lastlba) { 1169 c = min(count, 0xffff - lastcount); 1170 lastcount += c; 1171 off = (ranges - 1) * 8; 1172 req->data[off + 6] = lastcount & 0xff; 1173 req->data[off + 7] = 1174 (lastcount >> 8) & 0xff; 1175 count -= c; 1176 lba += c; 1177 } 1178 1179 while (count > 0) { 1180 c = min(count, 0xffff); 1181 off = ranges * 8; 1182 req->data[off + 0] = lba & 0xff; 1183 req->data[off + 1] = (lba >> 8) & 0xff; 1184 req->data[off + 2] = (lba >> 16) & 0xff; 1185 req->data[off + 3] = (lba >> 24) & 0xff; 1186 req->data[off + 4] = (lba >> 32) & 0xff; 1187 req->data[off + 5] = (lba >> 40) & 0xff; 1188 req->data[off + 6] = c & 0xff; 1189 req->data[off + 7] = (c >> 8) & 0xff; 1190 lba += c; 1191 count -= c; 1192 lastcount = c; 1193 ranges++; 1194 } 1195 lastlba = lba; 1196 req->bps[bps++] = bp1; 1197 bp1 = bioq_first(&softc->trim_queue); 1198 if (bps >= TRIM_MAX_BIOS || 1199 bp1 == NULL || 1200 bp1->bio_bcount / softc->params.secsize > 1201 (softc->trim_max_ranges - ranges) * 0xffff) 1202 break; 1203 } while (1); 1204 cam_fill_ataio(ataio, 1205 ada_retry_count, 1206 adadone, 1207 CAM_DIR_OUT, 1208 0, 1209 req->data, 1210 ((ranges + 63) / 64) * 512, 1211 ada_default_timeout * 1000); 1212 ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT, 1213 ATA_DSM_TRIM, 0, (ranges + 63) / 64); 1214 start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM; 1215 goto out; 1216 } 1217 /* Run regular command. */ 1218 bp = bioq_first(&softc->bio_queue); 1219 if (bp == NULL) { 1220 xpt_release_ccb(start_ccb); 1221 break; 1222 } 1223 bioq_remove(&softc->bio_queue, bp); 1224 1225 if ((bp->bio_flags & BIO_ORDERED) != 0 1226 || (softc->flags & ADA_FLAG_NEED_OTAG) != 0) { 1227 softc->flags &= ~ADA_FLAG_NEED_OTAG; 1228 softc->ordered_tag_count++; 1229 tag_code = 0; 1230 } else { 1231 tag_code = 1; 1232 } 1233 switch (bp->bio_cmd) { 1234 case BIO_READ: 1235 case BIO_WRITE: 1236 { 1237 uint64_t lba = bp->bio_pblkno; 1238 uint16_t count = bp->bio_bcount / softc->params.secsize; 1239 #ifdef ADA_TEST_FAILURE 1240 int fail = 0; 1241 1242 /* 1243 * Support the failure ioctls. If the command is a 1244 * read, and there are pending forced read errors, or 1245 * if a write and pending write errors, then fail this 1246 * operation with EIO. This is useful for testing 1247 * purposes. Also, support having every Nth read fail. 1248 * 1249 * This is a rather blunt tool. 1250 */ 1251 if (bp->bio_cmd == BIO_READ) { 1252 if (softc->force_read_error) { 1253 softc->force_read_error--; 1254 fail = 1; 1255 } 1256 if (softc->periodic_read_error > 0) { 1257 if (++softc->periodic_read_count >= 1258 softc->periodic_read_error) { 1259 softc->periodic_read_count = 0; 1260 fail = 1; 1261 } 1262 } 1263 } else { 1264 if (softc->force_write_error) { 1265 softc->force_write_error--; 1266 fail = 1; 1267 } 1268 } 1269 if (fail) { 1270 bp->bio_error = EIO; 1271 bp->bio_flags |= BIO_ERROR; 1272 biodone(bp); 1273 xpt_release_ccb(start_ccb); 1274 adaschedule(periph); 1275 return; 1276 } 1277 #endif 1278 cam_fill_ataio(ataio, 1279 ada_retry_count, 1280 adadone, 1281 bp->bio_cmd == BIO_READ ? 1282 CAM_DIR_IN : CAM_DIR_OUT, 1283 tag_code, 1284 bp->bio_data, 1285 bp->bio_bcount, 1286 ada_default_timeout*1000); 1287 1288 if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) { 1289 if (bp->bio_cmd == BIO_READ) { 1290 ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED, 1291 lba, count); 1292 } else { 1293 ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED, 1294 lba, count); 1295 } 1296 } else if ((softc->flags & ADA_FLAG_CAN_48BIT) && 1297 (lba + count >= ATA_MAX_28BIT_LBA || 1298 count > 256)) { 1299 if (softc->flags & ADA_FLAG_CAN_DMA) { 1300 if (bp->bio_cmd == BIO_READ) { 1301 ata_48bit_cmd(ataio, ATA_READ_DMA48, 1302 0, lba, count); 1303 } else { 1304 ata_48bit_cmd(ataio, ATA_WRITE_DMA48, 1305 0, lba, count); 1306 } 1307 } else { 1308 if (bp->bio_cmd == BIO_READ) { 1309 ata_48bit_cmd(ataio, ATA_READ_MUL48, 1310 0, lba, count); 1311 } else { 1312 ata_48bit_cmd(ataio, ATA_WRITE_MUL48, 1313 0, lba, count); 1314 } 1315 } 1316 } else { 1317 if (count == 256) 1318 count = 0; 1319 if (softc->flags & ADA_FLAG_CAN_DMA) { 1320 if (bp->bio_cmd == BIO_READ) { 1321 ata_28bit_cmd(ataio, ATA_READ_DMA, 1322 0, lba, count); 1323 } else { 1324 ata_28bit_cmd(ataio, ATA_WRITE_DMA, 1325 0, lba, count); 1326 } 1327 } else { 1328 if (bp->bio_cmd == BIO_READ) { 1329 ata_28bit_cmd(ataio, ATA_READ_MUL, 1330 0, lba, count); 1331 } else { 1332 ata_28bit_cmd(ataio, ATA_WRITE_MUL, 1333 0, lba, count); 1334 } 1335 } 1336 } 1337 break; 1338 } 1339 case BIO_DELETE: 1340 { 1341 uint64_t lba = bp->bio_pblkno; 1342 uint16_t count = bp->bio_bcount / softc->params.secsize; 1343 1344 cam_fill_ataio(ataio, 1345 ada_retry_count, 1346 adadone, 1347 CAM_DIR_NONE, 1348 0, 1349 NULL, 1350 0, 1351 ada_default_timeout*1000); 1352 1353 if (count >= 256) 1354 count = 0; 1355 ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count); 1356 break; 1357 } 1358 case BIO_FLUSH: 1359 cam_fill_ataio(ataio, 1360 1, 1361 adadone, 1362 CAM_DIR_NONE, 1363 0, 1364 NULL, 1365 0, 1366 ada_default_timeout*1000); 1367 1368 if (softc->flags & ADA_FLAG_CAN_48BIT) 1369 ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0); 1370 else 1371 ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0); 1372 break; 1373 } 1374 start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO; 1375 out: 1376 start_ccb->ccb_h.ccb_bp = bp; 1377 softc->outstanding_cmds++; 1378 xpt_action(start_ccb); 1379 1380 /* May have more work to do, so ensure we stay scheduled */ 1381 adaschedule(periph); 1382 break; 1383 } 1384 case ADA_STATE_RAHEAD: 1385 case ADA_STATE_WCACHE: 1386 { 1387 if (softc->flags & ADA_FLAG_PACK_INVALID) { 1388 softc->state = ADA_STATE_NORMAL; 1389 xpt_release_ccb(start_ccb); 1390 cam_release_devq(periph->path, 1391 RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE); 1392 adaschedule(periph); 1393 cam_periph_release_locked(periph); 1394 return; 1395 } 1396 1397 cam_fill_ataio(ataio, 1398 1, 1399 adadone, 1400 CAM_DIR_NONE, 1401 0, 1402 NULL, 1403 0, 1404 ada_default_timeout*1000); 1405 1406 if (softc->state == ADA_STATE_RAHEAD) { 1407 ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_RA ? 1408 ATA_SF_ENAB_RCACHE : ATA_SF_DIS_RCACHE, 0, 0); 1409 start_ccb->ccb_h.ccb_state = ADA_CCB_RAHEAD; 1410 } else { 1411 ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_WC ? 1412 ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0); 1413 start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE; 1414 } 1415 xpt_action(start_ccb); 1416 break; 1417 } 1418 } 1419 } 1420 1421 static void 1422 adadone(struct cam_periph *periph, union ccb *done_ccb) 1423 { 1424 struct ada_softc *softc; 1425 struct ccb_ataio *ataio; 1426 struct ccb_getdev *cgd; 1427 1428 softc = (struct ada_softc *)periph->softc; 1429 ataio = &done_ccb->ataio; 1430 switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) { 1431 case ADA_CCB_BUFFER_IO: 1432 case ADA_CCB_TRIM: 1433 { 1434 struct bio *bp; 1435 1436 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 1437 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1438 int error; 1439 1440 error = adaerror(done_ccb, 0, 0); 1441 if (error == ERESTART) { 1442 /* A retry was scheduled, so just return. */ 1443 return; 1444 } 1445 if (error != 0) { 1446 if (error == ENXIO && 1447 (softc->flags & ADA_FLAG_PACK_INVALID) == 0) { 1448 /* 1449 * Catastrophic error. Mark our pack as 1450 * invalid. 1451 */ 1452 /* 1453 * XXX See if this is really a media 1454 * XXX change first? 1455 */ 1456 xpt_print(periph->path, 1457 "Invalidating pack\n"); 1458 softc->flags |= ADA_FLAG_PACK_INVALID; 1459 } 1460 bp->bio_error = error; 1461 bp->bio_resid = bp->bio_bcount; 1462 bp->bio_flags |= BIO_ERROR; 1463 } else { 1464 bp->bio_resid = ataio->resid; 1465 bp->bio_error = 0; 1466 if (bp->bio_resid != 0) 1467 bp->bio_flags |= BIO_ERROR; 1468 } 1469 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 1470 cam_release_devq(done_ccb->ccb_h.path, 1471 /*relsim_flags*/0, 1472 /*reduction*/0, 1473 /*timeout*/0, 1474 /*getcount_only*/0); 1475 } else { 1476 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 1477 panic("REQ_CMP with QFRZN"); 1478 bp->bio_resid = ataio->resid; 1479 if (ataio->resid > 0) 1480 bp->bio_flags |= BIO_ERROR; 1481 } 1482 softc->outstanding_cmds--; 1483 if (softc->outstanding_cmds == 0) 1484 softc->flags |= ADA_FLAG_WENT_IDLE; 1485 if ((ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) == 1486 ADA_CCB_TRIM) { 1487 struct trim_request *req = 1488 (struct trim_request *)ataio->data_ptr; 1489 int i; 1490 1491 for (i = 1; i < TRIM_MAX_BIOS && req->bps[i]; i++) { 1492 struct bio *bp1 = req->bps[i]; 1493 1494 bp1->bio_resid = bp->bio_resid; 1495 bp1->bio_error = bp->bio_error; 1496 if (bp->bio_flags & BIO_ERROR) 1497 bp1->bio_flags |= BIO_ERROR; 1498 biodone(bp1); 1499 } 1500 softc->trim_running = 0; 1501 biodone(bp); 1502 adaschedule(periph); 1503 } else 1504 biodone(bp); 1505 break; 1506 } 1507 case ADA_CCB_RAHEAD: 1508 { 1509 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1510 if (adaerror(done_ccb, 0, 0) == ERESTART) { 1511 return; 1512 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { 1513 cam_release_devq(done_ccb->ccb_h.path, 1514 /*relsim_flags*/0, 1515 /*reduction*/0, 1516 /*timeout*/0, 1517 /*getcount_only*/0); 1518 } 1519 } 1520 1521 /* 1522 * Since our peripheral may be invalidated by an error 1523 * above or an external event, we must release our CCB 1524 * before releasing the reference on the peripheral. 1525 * The peripheral will only go away once the last reference 1526 * is removed, and we need it around for the CCB release 1527 * operation. 1528 */ 1529 cgd = (struct ccb_getdev *)done_ccb; 1530 xpt_setup_ccb(&cgd->ccb_h, periph->path, CAM_PRIORITY_NORMAL); 1531 cgd->ccb_h.func_code = XPT_GDEV_TYPE; 1532 xpt_action((union ccb *)cgd); 1533 if (ADA_WC >= 0 && 1534 cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) { 1535 softc->state = ADA_STATE_WCACHE; 1536 xpt_release_ccb(done_ccb); 1537 xpt_schedule(periph, CAM_PRIORITY_DEV); 1538 return; 1539 } 1540 softc->state = ADA_STATE_NORMAL; 1541 xpt_release_ccb(done_ccb); 1542 cam_release_devq(periph->path, 1543 RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE); 1544 adaschedule(periph); 1545 cam_periph_release_locked(periph); 1546 return; 1547 } 1548 case ADA_CCB_WCACHE: 1549 { 1550 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1551 if (adaerror(done_ccb, 0, 0) == ERESTART) { 1552 return; 1553 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { 1554 cam_release_devq(done_ccb->ccb_h.path, 1555 /*relsim_flags*/0, 1556 /*reduction*/0, 1557 /*timeout*/0, 1558 /*getcount_only*/0); 1559 } 1560 } 1561 1562 softc->state = ADA_STATE_NORMAL; 1563 /* 1564 * Since our peripheral may be invalidated by an error 1565 * above or an external event, we must release our CCB 1566 * before releasing the reference on the peripheral. 1567 * The peripheral will only go away once the last reference 1568 * is removed, and we need it around for the CCB release 1569 * operation. 1570 */ 1571 xpt_release_ccb(done_ccb); 1572 cam_release_devq(periph->path, 1573 RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE); 1574 adaschedule(periph); 1575 cam_periph_release_locked(periph); 1576 return; 1577 } 1578 case ADA_CCB_WAITING: 1579 { 1580 /* Caller will release the CCB */ 1581 wakeup(&done_ccb->ccb_h.cbfcnp); 1582 return; 1583 } 1584 case ADA_CCB_DUMP: 1585 /* No-op. We're polling */ 1586 return; 1587 default: 1588 break; 1589 } 1590 xpt_release_ccb(done_ccb); 1591 } 1592 1593 static int 1594 adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) 1595 { 1596 1597 return(cam_periph_error(ccb, cam_flags, sense_flags, NULL)); 1598 } 1599 1600 static void 1601 adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd) 1602 { 1603 struct ada_softc *softc = (struct ada_softc *)periph->softc; 1604 struct disk_params *dp = &softc->params; 1605 u_int64_t lbasize48; 1606 u_int32_t lbasize; 1607 1608 dp->secsize = ata_logical_sector_size(&cgd->ident_data); 1609 if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) && 1610 cgd->ident_data.current_heads && cgd->ident_data.current_sectors) { 1611 dp->heads = cgd->ident_data.current_heads; 1612 dp->secs_per_track = cgd->ident_data.current_sectors; 1613 dp->cylinders = cgd->ident_data.cylinders; 1614 dp->sectors = (u_int32_t)cgd->ident_data.current_size_1 | 1615 ((u_int32_t)cgd->ident_data.current_size_2 << 16); 1616 } else { 1617 dp->heads = cgd->ident_data.heads; 1618 dp->secs_per_track = cgd->ident_data.sectors; 1619 dp->cylinders = cgd->ident_data.cylinders; 1620 dp->sectors = cgd->ident_data.cylinders * dp->heads * dp->secs_per_track; 1621 } 1622 lbasize = (u_int32_t)cgd->ident_data.lba_size_1 | 1623 ((u_int32_t)cgd->ident_data.lba_size_2 << 16); 1624 1625 /* use the 28bit LBA size if valid or bigger than the CHS mapping */ 1626 if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize) 1627 dp->sectors = lbasize; 1628 1629 /* use the 48bit LBA size if valid */ 1630 lbasize48 = ((u_int64_t)cgd->ident_data.lba_size48_1) | 1631 ((u_int64_t)cgd->ident_data.lba_size48_2 << 16) | 1632 ((u_int64_t)cgd->ident_data.lba_size48_3 << 32) | 1633 ((u_int64_t)cgd->ident_data.lba_size48_4 << 48); 1634 if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) && 1635 lbasize48 > ATA_MAX_28BIT_LBA) 1636 dp->sectors = lbasize48; 1637 } 1638 1639 static void 1640 adasendorderedtag(void *arg) 1641 { 1642 struct ada_softc *softc = arg; 1643 1644 if (ada_send_ordered) { 1645 if ((softc->ordered_tag_count == 0) 1646 && ((softc->flags & ADA_FLAG_WENT_IDLE) == 0)) { 1647 softc->flags |= ADA_FLAG_NEED_OTAG; 1648 } 1649 if (softc->outstanding_cmds > 0) 1650 softc->flags &= ~ADA_FLAG_WENT_IDLE; 1651 1652 softc->ordered_tag_count = 0; 1653 } 1654 /* Queue us up again */ 1655 callout_reset(&softc->sendordered_c, 1656 (ADA_DEFAULT_TIMEOUT * hz) / ADA_ORDEREDTAG_INTERVAL, 1657 adasendorderedtag, softc); 1658 } 1659 1660 /* 1661 * Step through all ADA peripheral drivers, and if the device is still open, 1662 * sync the disk cache to physical media. 1663 */ 1664 static void 1665 adaflush(void) 1666 { 1667 struct cam_periph *periph; 1668 struct ada_softc *softc; 1669 1670 TAILQ_FOREACH(periph, &adadriver.units, unit_links) { 1671 union ccb ccb; 1672 1673 /* If we paniced with lock held - not recurse here. */ 1674 if (cam_periph_owned(periph)) 1675 continue; 1676 cam_periph_lock(periph); 1677 softc = (struct ada_softc *)periph->softc; 1678 /* 1679 * We only sync the cache if the drive is still open, and 1680 * if the drive is capable of it.. 1681 */ 1682 if (((softc->flags & ADA_FLAG_OPEN) == 0) || 1683 (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) { 1684 cam_periph_unlock(periph); 1685 continue; 1686 } 1687 1688 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 1689 1690 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 1691 cam_fill_ataio(&ccb.ataio, 1692 1, 1693 adadone, 1694 CAM_DIR_NONE, 1695 0, 1696 NULL, 1697 0, 1698 ada_default_timeout*1000); 1699 1700 if (softc->flags & ADA_FLAG_CAN_48BIT) 1701 ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0); 1702 else 1703 ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0); 1704 xpt_polled_action(&ccb); 1705 1706 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 1707 xpt_print(periph->path, "Synchronize cache failed\n"); 1708 1709 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) 1710 cam_release_devq(ccb.ccb_h.path, 1711 /*relsim_flags*/0, 1712 /*reduction*/0, 1713 /*timeout*/0, 1714 /*getcount_only*/0); 1715 cam_periph_unlock(periph); 1716 } 1717 } 1718 1719 static void 1720 adaspindown(uint8_t cmd, int flags) 1721 { 1722 struct cam_periph *periph; 1723 struct ada_softc *softc; 1724 1725 TAILQ_FOREACH(periph, &adadriver.units, unit_links) { 1726 union ccb ccb; 1727 1728 /* If we paniced with lock held - not recurse here. */ 1729 if (cam_periph_owned(periph)) 1730 continue; 1731 cam_periph_lock(periph); 1732 softc = (struct ada_softc *)periph->softc; 1733 /* 1734 * We only spin-down the drive if it is capable of it.. 1735 */ 1736 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) { 1737 cam_periph_unlock(periph); 1738 continue; 1739 } 1740 1741 if (bootverbose) 1742 xpt_print(periph->path, "spin-down\n"); 1743 1744 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 1745 1746 ccb.ccb_h.ccb_state = ADA_CCB_DUMP; 1747 cam_fill_ataio(&ccb.ataio, 1748 1, 1749 adadone, 1750 CAM_DIR_NONE | flags, 1751 0, 1752 NULL, 1753 0, 1754 ada_default_timeout*1000); 1755 1756 ata_28bit_cmd(&ccb.ataio, cmd, 0, 0, 0); 1757 xpt_polled_action(&ccb); 1758 1759 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 1760 xpt_print(periph->path, "Spin-down disk failed\n"); 1761 1762 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) 1763 cam_release_devq(ccb.ccb_h.path, 1764 /*relsim_flags*/0, 1765 /*reduction*/0, 1766 /*timeout*/0, 1767 /*getcount_only*/0); 1768 cam_periph_unlock(periph); 1769 } 1770 } 1771 1772 static void 1773 adashutdown(void *arg, int howto) 1774 { 1775 1776 adaflush(); 1777 if (ada_spindown_shutdown != 0 && 1778 (howto & (RB_HALT | RB_POWEROFF)) != 0) 1779 adaspindown(ATA_STANDBY_IMMEDIATE, 0); 1780 } 1781 1782 static void 1783 adasuspend(void *arg) 1784 { 1785 1786 adaflush(); 1787 if (ada_spindown_suspend != 0) 1788 adaspindown(ATA_SLEEP, CAM_DEV_QFREEZE); 1789 } 1790 1791 static void 1792 adaresume(void *arg) 1793 { 1794 struct cam_periph *periph; 1795 struct ada_softc *softc; 1796 1797 if (ada_spindown_suspend == 0) 1798 return; 1799 1800 TAILQ_FOREACH(periph, &adadriver.units, unit_links) { 1801 cam_periph_lock(periph); 1802 softc = (struct ada_softc *)periph->softc; 1803 /* 1804 * We only spin-down the drive if it is capable of it.. 1805 */ 1806 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) { 1807 cam_periph_unlock(periph); 1808 continue; 1809 } 1810 1811 if (bootverbose) 1812 xpt_print(periph->path, "resume\n"); 1813 1814 /* 1815 * Drop freeze taken due to CAM_DEV_QFREEZE flag set on 1816 * sleep request. 1817 */ 1818 cam_release_devq(periph->path, 1819 /*relsim_flags*/0, 1820 /*openings*/0, 1821 /*timeout*/0, 1822 /*getcount_only*/0); 1823 1824 cam_periph_unlock(periph); 1825 } 1826 } 1827 1828 #endif /* _KERNEL */ 1829