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