1 /*- 2 * Copyright (c) 1997 Justin T. Gibbs. 3 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Kenneth D. Merry. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions, and the following disclaimer, 11 * without modification, immediately at the beginning of the file. 12 * 2. The name of the author may not be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /*- 29 * Portions of this driver taken from the original FreeBSD cd driver. 30 * Written by Julian Elischer (julian@tfs.com) 31 * for TRW Financial Systems for use under the MACH(2.5) operating system. 32 * 33 * TRW Financial Systems, in accordance with their agreement with Carnegie 34 * Mellon University, makes this software available to CMU to distribute 35 * or use in any manner that they see fit as long as this message is kept with 36 * the software. For this reason TFS also grants any other persons or 37 * organisations permission to use or modify this software. 38 * 39 * TFS supplies this software to be publicly redistributed 40 * on the understanding that TFS is not responsible for the correct 41 * functioning of this software in any circumstances. 42 * 43 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 44 * 45 * from: cd.c,v 1.83 1997/05/04 15:24:22 joerg Exp $ 46 */ 47 48 #include <sys/cdefs.h> 49 __FBSDID("$FreeBSD$"); 50 51 #include "opt_cd.h" 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/kernel.h> 56 #include <sys/bio.h> 57 #include <sys/conf.h> 58 #include <sys/disk.h> 59 #include <sys/malloc.h> 60 #include <sys/cdio.h> 61 #include <sys/cdrio.h> 62 #include <sys/dvdio.h> 63 #include <sys/devicestat.h> 64 #include <sys/sysctl.h> 65 #include <sys/taskqueue.h> 66 #include <geom/geom_disk.h> 67 68 #include <cam/cam.h> 69 #include <cam/cam_ccb.h> 70 #include <cam/cam_periph.h> 71 #include <cam/cam_xpt_periph.h> 72 #include <cam/cam_queue.h> 73 #include <cam/cam_sim.h> 74 75 #include <cam/scsi/scsi_message.h> 76 #include <cam/scsi/scsi_da.h> 77 #include <cam/scsi/scsi_cd.h> 78 79 #define LEADOUT 0xaa /* leadout toc entry */ 80 81 struct cd_params { 82 u_int32_t blksize; 83 u_long disksize; 84 }; 85 86 typedef enum { 87 CD_Q_NONE = 0x00, 88 CD_Q_NO_TOUCH = 0x01, 89 CD_Q_BCD_TRACKS = 0x02, 90 CD_Q_10_BYTE_ONLY = 0x10, 91 CD_Q_RETRY_BUSY = 0x40 92 } cd_quirks; 93 94 #define CD_Q_BIT_STRING \ 95 "\020" \ 96 "\001NO_TOUCH" \ 97 "\002BCD_TRACKS" \ 98 "\00510_BYTE_ONLY" \ 99 "\007RETRY_BUSY" 100 101 typedef enum { 102 CD_FLAG_INVALID = 0x0001, 103 CD_FLAG_NEW_DISC = 0x0002, 104 CD_FLAG_DISC_LOCKED = 0x0004, 105 CD_FLAG_DISC_REMOVABLE = 0x0008, 106 CD_FLAG_SAW_MEDIA = 0x0010, 107 CD_FLAG_ACTIVE = 0x0080, 108 CD_FLAG_SCHED_ON_COMP = 0x0100, 109 CD_FLAG_RETRY_UA = 0x0200, 110 CD_FLAG_VALID_MEDIA = 0x0400, 111 CD_FLAG_VALID_TOC = 0x0800, 112 CD_FLAG_SCTX_INIT = 0x1000 113 } cd_flags; 114 115 typedef enum { 116 CD_CCB_PROBE = 0x01, 117 CD_CCB_BUFFER_IO = 0x02, 118 CD_CCB_TUR = 0x04, 119 CD_CCB_TYPE_MASK = 0x0F, 120 CD_CCB_RETRY_UA = 0x10 121 } cd_ccb_state; 122 123 #define ccb_state ppriv_field0 124 #define ccb_bp ppriv_ptr1 125 126 struct cd_tocdata { 127 struct ioc_toc_header header; 128 struct cd_toc_entry entries[100]; 129 }; 130 131 struct cd_toc_single { 132 struct ioc_toc_header header; 133 struct cd_toc_entry entry; 134 }; 135 136 typedef enum { 137 CD_STATE_PROBE, 138 CD_STATE_NORMAL 139 } cd_state; 140 141 struct cd_softc { 142 cam_pinfo pinfo; 143 cd_state state; 144 volatile cd_flags flags; 145 struct bio_queue_head bio_queue; 146 LIST_HEAD(, ccb_hdr) pending_ccbs; 147 struct cd_params params; 148 union ccb saved_ccb; 149 cd_quirks quirks; 150 struct cam_periph *periph; 151 int minimum_command_size; 152 int outstanding_cmds; 153 int tur; 154 struct task sysctl_task; 155 struct sysctl_ctx_list sysctl_ctx; 156 struct sysctl_oid *sysctl_tree; 157 STAILQ_HEAD(, cd_mode_params) mode_queue; 158 struct cd_tocdata toc; 159 struct disk *disk; 160 struct callout mediapoll_c; 161 }; 162 163 struct cd_page_sizes { 164 int page; 165 int page_size; 166 }; 167 168 static struct cd_page_sizes cd_page_size_table[] = 169 { 170 { AUDIO_PAGE, sizeof(struct cd_audio_page)} 171 }; 172 173 struct cd_quirk_entry { 174 struct scsi_inquiry_pattern inq_pat; 175 cd_quirks quirks; 176 }; 177 178 /* 179 * NOTE ON 10_BYTE_ONLY quirks: Any 10_BYTE_ONLY quirks MUST be because 180 * your device hangs when it gets a 10 byte command. Adding a quirk just 181 * to get rid of the informative diagnostic message is not acceptable. All 182 * 10_BYTE_ONLY quirks must be documented in full in a PR (which should be 183 * referenced in a comment along with the quirk) , and must be approved by 184 * ken@FreeBSD.org. Any quirks added that don't adhere to this policy may 185 * be removed until the submitter can explain why they are needed. 186 * 10_BYTE_ONLY quirks will be removed (as they will no longer be necessary) 187 * when the CAM_NEW_TRAN_CODE work is done. 188 */ 189 static struct cd_quirk_entry cd_quirk_table[] = 190 { 191 { 192 { T_CDROM, SIP_MEDIA_REMOVABLE, "CHINON", "CD-ROM CDS-535","*"}, 193 /* quirks */ CD_Q_BCD_TRACKS 194 }, 195 { 196 /* 197 * VMware returns BUSY status when storage has transient 198 * connectivity problems, so better wait. 199 */ 200 {T_CDROM, SIP_MEDIA_REMOVABLE, "NECVMWar", "VMware IDE CDR10", "*"}, 201 /*quirks*/ CD_Q_RETRY_BUSY 202 } 203 }; 204 205 static disk_open_t cdopen; 206 static disk_close_t cdclose; 207 static disk_ioctl_t cdioctl; 208 static disk_strategy_t cdstrategy; 209 210 static periph_init_t cdinit; 211 static periph_ctor_t cdregister; 212 static periph_dtor_t cdcleanup; 213 static periph_start_t cdstart; 214 static periph_oninv_t cdoninvalidate; 215 static void cdasync(void *callback_arg, u_int32_t code, 216 struct cam_path *path, void *arg); 217 static int cdcmdsizesysctl(SYSCTL_HANDLER_ARGS); 218 static int cdrunccb(union ccb *ccb, 219 int (*error_routine)(union ccb *ccb, 220 u_int32_t cam_flags, 221 u_int32_t sense_flags), 222 u_int32_t cam_flags, u_int32_t sense_flags); 223 static void cddone(struct cam_periph *periph, 224 union ccb *start_ccb); 225 static union cd_pages *cdgetpage(struct cd_mode_params *mode_params); 226 static int cdgetpagesize(int page_num); 227 static void cdprevent(struct cam_periph *periph, int action); 228 static int cdcheckmedia(struct cam_periph *periph); 229 static int cdsize(struct cam_periph *periph, u_int32_t *size); 230 static int cd6byteworkaround(union ccb *ccb); 231 static int cderror(union ccb *ccb, u_int32_t cam_flags, 232 u_int32_t sense_flags); 233 static int cdreadtoc(struct cam_periph *periph, u_int32_t mode, 234 u_int32_t start, u_int8_t *data, 235 u_int32_t len, u_int32_t sense_flags); 236 static int cdgetmode(struct cam_periph *periph, 237 struct cd_mode_params *data, u_int32_t page); 238 static int cdsetmode(struct cam_periph *periph, 239 struct cd_mode_params *data); 240 static int cdplay(struct cam_periph *periph, u_int32_t blk, 241 u_int32_t len); 242 static int cdreadsubchannel(struct cam_periph *periph, 243 u_int32_t mode, u_int32_t format, 244 int track, 245 struct cd_sub_channel_info *data, 246 u_int32_t len); 247 static int cdplaymsf(struct cam_periph *periph, u_int32_t startm, 248 u_int32_t starts, u_int32_t startf, 249 u_int32_t endm, u_int32_t ends, 250 u_int32_t endf); 251 static int cdplaytracks(struct cam_periph *periph, 252 u_int32_t strack, u_int32_t sindex, 253 u_int32_t etrack, u_int32_t eindex); 254 static int cdpause(struct cam_periph *periph, u_int32_t go); 255 static int cdstopunit(struct cam_periph *periph, u_int32_t eject); 256 static int cdstartunit(struct cam_periph *periph, int load); 257 static int cdsetspeed(struct cam_periph *periph, 258 u_int32_t rdspeed, u_int32_t wrspeed); 259 static int cdreportkey(struct cam_periph *periph, 260 struct dvd_authinfo *authinfo); 261 static int cdsendkey(struct cam_periph *periph, 262 struct dvd_authinfo *authinfo); 263 static int cdreaddvdstructure(struct cam_periph *periph, 264 struct dvd_struct *dvdstruct); 265 static timeout_t cdmediapoll; 266 267 static struct periph_driver cddriver = 268 { 269 cdinit, "cd", 270 TAILQ_HEAD_INITIALIZER(cddriver.units), /* generation */ 0 271 }; 272 273 PERIPHDRIVER_DECLARE(cd, cddriver); 274 275 #ifndef CD_DEFAULT_POLL_PERIOD 276 #define CD_DEFAULT_POLL_PERIOD 3 277 #endif 278 #ifndef CD_DEFAULT_RETRY 279 #define CD_DEFAULT_RETRY 4 280 #endif 281 #ifndef CD_DEFAULT_TIMEOUT 282 #define CD_DEFAULT_TIMEOUT 30000 283 #endif 284 285 static int cd_poll_period = CD_DEFAULT_POLL_PERIOD; 286 static int cd_retry_count = CD_DEFAULT_RETRY; 287 static int cd_timeout = CD_DEFAULT_TIMEOUT; 288 289 static SYSCTL_NODE(_kern_cam, OID_AUTO, cd, CTLFLAG_RD, 0, "CAM CDROM driver"); 290 SYSCTL_INT(_kern_cam_cd, OID_AUTO, poll_period, CTLFLAG_RWTUN, 291 &cd_poll_period, 0, "Media polling period in seconds"); 292 SYSCTL_INT(_kern_cam_cd, OID_AUTO, retry_count, CTLFLAG_RWTUN, 293 &cd_retry_count, 0, "Normal I/O retry count"); 294 SYSCTL_INT(_kern_cam_cd, OID_AUTO, timeout, CTLFLAG_RWTUN, 295 &cd_timeout, 0, "Timeout, in us, for read operations"); 296 297 static MALLOC_DEFINE(M_SCSICD, "scsi_cd", "scsi_cd buffers"); 298 299 static void 300 cdinit(void) 301 { 302 cam_status status; 303 304 /* 305 * Install a global async callback. This callback will 306 * receive async callbacks like "new device found". 307 */ 308 status = xpt_register_async(AC_FOUND_DEVICE, cdasync, NULL, NULL); 309 310 if (status != CAM_REQ_CMP) { 311 printf("cd: Failed to attach master async callback " 312 "due to status 0x%x!\n", status); 313 } 314 } 315 316 /* 317 * Callback from GEOM, called when it has finished cleaning up its 318 * resources. 319 */ 320 static void 321 cddiskgonecb(struct disk *dp) 322 { 323 struct cam_periph *periph; 324 325 periph = (struct cam_periph *)dp->d_drv1; 326 cam_periph_release(periph); 327 } 328 329 static void 330 cdoninvalidate(struct cam_periph *periph) 331 { 332 struct cd_softc *softc; 333 334 softc = (struct cd_softc *)periph->softc; 335 336 /* 337 * De-register any async callbacks. 338 */ 339 xpt_register_async(0, cdasync, periph, periph->path); 340 341 softc->flags |= CD_FLAG_INVALID; 342 343 /* 344 * Return all queued I/O with ENXIO. 345 * XXX Handle any transactions queued to the card 346 * with XPT_ABORT_CCB. 347 */ 348 bioq_flush(&softc->bio_queue, NULL, ENXIO); 349 350 disk_gone(softc->disk); 351 } 352 353 static void 354 cdcleanup(struct cam_periph *periph) 355 { 356 struct cd_softc *softc; 357 358 softc = (struct cd_softc *)periph->softc; 359 360 cam_periph_unlock(periph); 361 if ((softc->flags & CD_FLAG_SCTX_INIT) != 0 362 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) { 363 xpt_print(periph->path, "can't remove sysctl context\n"); 364 } 365 366 callout_drain(&softc->mediapoll_c); 367 disk_destroy(softc->disk); 368 free(softc, M_DEVBUF); 369 cam_periph_lock(periph); 370 } 371 372 static void 373 cdasync(void *callback_arg, u_int32_t code, 374 struct cam_path *path, void *arg) 375 { 376 struct cam_periph *periph; 377 struct cd_softc *softc; 378 379 periph = (struct cam_periph *)callback_arg; 380 switch (code) { 381 case AC_FOUND_DEVICE: 382 { 383 struct ccb_getdev *cgd; 384 cam_status status; 385 386 cgd = (struct ccb_getdev *)arg; 387 if (cgd == NULL) 388 break; 389 390 if (cgd->protocol != PROTO_SCSI) 391 break; 392 if (SID_QUAL(&cgd->inq_data) != SID_QUAL_LU_CONNECTED) 393 break; 394 if (SID_TYPE(&cgd->inq_data) != T_CDROM 395 && SID_TYPE(&cgd->inq_data) != T_WORM) 396 break; 397 398 /* 399 * Allocate a peripheral instance for 400 * this device and start the probe 401 * process. 402 */ 403 status = cam_periph_alloc(cdregister, cdoninvalidate, 404 cdcleanup, cdstart, 405 "cd", CAM_PERIPH_BIO, 406 path, cdasync, 407 AC_FOUND_DEVICE, cgd); 408 409 if (status != CAM_REQ_CMP 410 && status != CAM_REQ_INPROG) 411 printf("cdasync: Unable to attach new device " 412 "due to status 0x%x\n", status); 413 414 break; 415 } 416 case AC_UNIT_ATTENTION: 417 { 418 union ccb *ccb; 419 int error_code, sense_key, asc, ascq; 420 421 softc = (struct cd_softc *)periph->softc; 422 ccb = (union ccb *)arg; 423 424 /* 425 * Handle all media change UNIT ATTENTIONs except 426 * our own, as they will be handled by cderror(). 427 */ 428 if (xpt_path_periph(ccb->ccb_h.path) != periph && 429 scsi_extract_sense_ccb(ccb, 430 &error_code, &sense_key, &asc, &ascq)) { 431 if (asc == 0x28 && ascq == 0x00) 432 disk_media_changed(softc->disk, M_NOWAIT); 433 } 434 cam_periph_async(periph, code, path, arg); 435 break; 436 } 437 case AC_SCSI_AEN: 438 softc = (struct cd_softc *)periph->softc; 439 if (softc->state == CD_STATE_NORMAL && !softc->tur) { 440 if (cam_periph_acquire(periph) == CAM_REQ_CMP) { 441 softc->tur = 1; 442 xpt_schedule(periph, CAM_PRIORITY_NORMAL); 443 } 444 } 445 /* FALLTHROUGH */ 446 case AC_SENT_BDR: 447 case AC_BUS_RESET: 448 { 449 struct ccb_hdr *ccbh; 450 451 softc = (struct cd_softc *)periph->softc; 452 /* 453 * Don't fail on the expected unit attention 454 * that will occur. 455 */ 456 softc->flags |= CD_FLAG_RETRY_UA; 457 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) 458 ccbh->ccb_state |= CD_CCB_RETRY_UA; 459 /* FALLTHROUGH */ 460 } 461 default: 462 cam_periph_async(periph, code, path, arg); 463 break; 464 } 465 } 466 467 static void 468 cdsysctlinit(void *context, int pending) 469 { 470 struct cam_periph *periph; 471 struct cd_softc *softc; 472 char tmpstr[80], tmpstr2[80]; 473 474 periph = (struct cam_periph *)context; 475 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 476 return; 477 478 softc = (struct cd_softc *)periph->softc; 479 snprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number); 480 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); 481 482 sysctl_ctx_init(&softc->sysctl_ctx); 483 softc->flags |= CD_FLAG_SCTX_INIT; 484 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 485 SYSCTL_STATIC_CHILDREN(_kern_cam_cd), OID_AUTO, 486 tmpstr2, CTLFLAG_RD, 0, tmpstr); 487 488 if (softc->sysctl_tree == NULL) { 489 printf("cdsysctlinit: unable to allocate sysctl tree\n"); 490 cam_periph_release(periph); 491 return; 492 } 493 494 /* 495 * Now register the sysctl handler, so the user can the value on 496 * the fly. 497 */ 498 SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), 499 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, 500 &softc->minimum_command_size, 0, cdcmdsizesysctl, "I", 501 "Minimum CDB size"); 502 503 cam_periph_release(periph); 504 } 505 506 /* 507 * We have a handler function for this so we can check the values when the 508 * user sets them, instead of every time we look at them. 509 */ 510 static int 511 cdcmdsizesysctl(SYSCTL_HANDLER_ARGS) 512 { 513 int error, value; 514 515 value = *(int *)arg1; 516 517 error = sysctl_handle_int(oidp, &value, 0, req); 518 519 if ((error != 0) 520 || (req->newptr == NULL)) 521 return (error); 522 523 /* 524 * The only real values we can have here are 6 or 10. I don't 525 * really forsee having 12 be an option at any time in the future. 526 * So if the user sets something less than or equal to 6, we'll set 527 * it to 6. If he sets something greater than 6, we'll set it to 10. 528 * 529 * I suppose we could just return an error here for the wrong values, 530 * but I don't think it's necessary to do so, as long as we can 531 * determine the user's intent without too much trouble. 532 */ 533 if (value < 6) 534 value = 6; 535 else if (value > 6) 536 value = 10; 537 538 *(int *)arg1 = value; 539 540 return (0); 541 } 542 543 static cam_status 544 cdregister(struct cam_periph *periph, void *arg) 545 { 546 struct cd_softc *softc; 547 struct ccb_pathinq cpi; 548 struct ccb_getdev *cgd; 549 char tmpstr[80]; 550 caddr_t match; 551 552 cgd = (struct ccb_getdev *)arg; 553 if (cgd == NULL) { 554 printf("cdregister: no getdev CCB, can't register device\n"); 555 return(CAM_REQ_CMP_ERR); 556 } 557 558 softc = (struct cd_softc *)malloc(sizeof(*softc),M_DEVBUF, 559 M_NOWAIT | M_ZERO); 560 if (softc == NULL) { 561 printf("cdregister: Unable to probe new device. " 562 "Unable to allocate softc\n"); 563 return(CAM_REQ_CMP_ERR); 564 } 565 566 LIST_INIT(&softc->pending_ccbs); 567 STAILQ_INIT(&softc->mode_queue); 568 softc->state = CD_STATE_PROBE; 569 bioq_init(&softc->bio_queue); 570 if (SID_IS_REMOVABLE(&cgd->inq_data)) 571 softc->flags |= CD_FLAG_DISC_REMOVABLE; 572 573 periph->softc = softc; 574 softc->periph = periph; 575 576 /* 577 * See if this device has any quirks. 578 */ 579 match = cam_quirkmatch((caddr_t)&cgd->inq_data, 580 (caddr_t)cd_quirk_table, 581 sizeof(cd_quirk_table)/sizeof(*cd_quirk_table), 582 sizeof(*cd_quirk_table), scsi_inquiry_match); 583 584 if (match != NULL) 585 softc->quirks = ((struct cd_quirk_entry *)match)->quirks; 586 else 587 softc->quirks = CD_Q_NONE; 588 589 /* Check if the SIM does not want 6 byte commands */ 590 bzero(&cpi, sizeof(cpi)); 591 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 592 cpi.ccb_h.func_code = XPT_PATH_INQ; 593 xpt_action((union ccb *)&cpi); 594 if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) 595 softc->quirks |= CD_Q_10_BYTE_ONLY; 596 597 TASK_INIT(&softc->sysctl_task, 0, cdsysctlinit, periph); 598 599 /* The default is 6 byte commands, unless quirked otherwise */ 600 if (softc->quirks & CD_Q_10_BYTE_ONLY) 601 softc->minimum_command_size = 10; 602 else 603 softc->minimum_command_size = 6; 604 605 /* 606 * Refcount and block open attempts until we are setup 607 * Can't block 608 */ 609 (void)cam_periph_hold(periph, PRIBIO); 610 cam_periph_unlock(periph); 611 /* 612 * Load the user's default, if any. 613 */ 614 snprintf(tmpstr, sizeof(tmpstr), "kern.cam.cd.%d.minimum_cmd_size", 615 periph->unit_number); 616 TUNABLE_INT_FETCH(tmpstr, &softc->minimum_command_size); 617 618 /* 6 and 10 are the only permissible values here. */ 619 if (softc->minimum_command_size < 6) 620 softc->minimum_command_size = 6; 621 else if (softc->minimum_command_size > 6) 622 softc->minimum_command_size = 10; 623 624 /* 625 * We need to register the statistics structure for this device, 626 * but we don't have the blocksize yet for it. So, we register 627 * the structure and indicate that we don't have the blocksize 628 * yet. Unlike other SCSI peripheral drivers, we explicitly set 629 * the device type here to be CDROM, rather than just ORing in 630 * the device type. This is because this driver can attach to either 631 * CDROM or WORM devices, and we want this peripheral driver to 632 * show up in the devstat list as a CD peripheral driver, not a 633 * WORM peripheral driver. WORM drives will also have the WORM 634 * driver attached to them. 635 */ 636 softc->disk = disk_alloc(); 637 softc->disk->d_devstat = devstat_new_entry("cd", 638 periph->unit_number, 0, 639 DEVSTAT_BS_UNAVAILABLE, 640 DEVSTAT_TYPE_CDROM | 641 XPORT_DEVSTAT_TYPE(cpi.transport), 642 DEVSTAT_PRIORITY_CD); 643 softc->disk->d_open = cdopen; 644 softc->disk->d_close = cdclose; 645 softc->disk->d_strategy = cdstrategy; 646 softc->disk->d_gone = cddiskgonecb; 647 softc->disk->d_ioctl = cdioctl; 648 softc->disk->d_name = "cd"; 649 cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor, 650 sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr)); 651 strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr)); 652 cam_strvis(&softc->disk->d_descr[strlen(softc->disk->d_descr)], 653 cgd->inq_data.product, sizeof(cgd->inq_data.product), 654 sizeof(softc->disk->d_descr) - strlen(softc->disk->d_descr)); 655 softc->disk->d_unit = periph->unit_number; 656 softc->disk->d_drv1 = periph; 657 if (cpi.maxio == 0) 658 softc->disk->d_maxsize = DFLTPHYS; /* traditional default */ 659 else if (cpi.maxio > MAXPHYS) 660 softc->disk->d_maxsize = MAXPHYS; /* for safety */ 661 else 662 softc->disk->d_maxsize = cpi.maxio; 663 softc->disk->d_flags = 0; 664 softc->disk->d_hba_vendor = cpi.hba_vendor; 665 softc->disk->d_hba_device = cpi.hba_device; 666 softc->disk->d_hba_subvendor = cpi.hba_subvendor; 667 softc->disk->d_hba_subdevice = cpi.hba_subdevice; 668 669 /* 670 * Acquire a reference to the periph before we register with GEOM. 671 * We'll release this reference once GEOM calls us back (via 672 * dadiskgonecb()) telling us that our provider has been freed. 673 */ 674 if (cam_periph_acquire(periph) != CAM_REQ_CMP) { 675 xpt_print(periph->path, "%s: lost periph during " 676 "registration!\n", __func__); 677 cam_periph_lock(periph); 678 return (CAM_REQ_CMP_ERR); 679 } 680 681 disk_create(softc->disk, DISK_VERSION); 682 cam_periph_lock(periph); 683 684 /* 685 * Add an async callback so that we get 686 * notified if this device goes away. 687 */ 688 xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE | 689 AC_SCSI_AEN | AC_UNIT_ATTENTION, cdasync, periph, periph->path); 690 691 /* 692 * Schedule a periodic media polling events. 693 */ 694 callout_init_mtx(&softc->mediapoll_c, cam_periph_mtx(periph), 0); 695 if ((softc->flags & CD_FLAG_DISC_REMOVABLE) && 696 (cgd->inq_flags & SID_AEN) == 0 && 697 cd_poll_period != 0) 698 callout_reset(&softc->mediapoll_c, cd_poll_period * hz, 699 cdmediapoll, periph); 700 701 xpt_schedule(periph, CAM_PRIORITY_DEV); 702 return(CAM_REQ_CMP); 703 } 704 705 static int 706 cdopen(struct disk *dp) 707 { 708 struct cam_periph *periph; 709 struct cd_softc *softc; 710 int error; 711 712 periph = (struct cam_periph *)dp->d_drv1; 713 softc = (struct cd_softc *)periph->softc; 714 715 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 716 return(ENXIO); 717 718 cam_periph_lock(periph); 719 720 if (softc->flags & CD_FLAG_INVALID) { 721 cam_periph_release_locked(periph); 722 cam_periph_unlock(periph); 723 return(ENXIO); 724 } 725 726 if ((error = cam_periph_hold(periph, PRIBIO | PCATCH)) != 0) { 727 cam_periph_release_locked(periph); 728 cam_periph_unlock(periph); 729 return (error); 730 } 731 732 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, 733 ("cdopen\n")); 734 735 /* 736 * Check for media, and set the appropriate flags. We don't bail 737 * if we don't have media, but then we don't allow anything but the 738 * CDIOCEJECT/CDIOCCLOSE ioctls if there is no media. 739 */ 740 cdcheckmedia(periph); 741 742 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("leaving cdopen\n")); 743 cam_periph_unhold(periph); 744 745 cam_periph_unlock(periph); 746 747 return (0); 748 } 749 750 static int 751 cdclose(struct disk *dp) 752 { 753 struct cam_periph *periph; 754 struct cd_softc *softc; 755 756 periph = (struct cam_periph *)dp->d_drv1; 757 softc = (struct cd_softc *)periph->softc; 758 759 cam_periph_lock(periph); 760 if (cam_periph_hold(periph, PRIBIO) != 0) { 761 cam_periph_unlock(periph); 762 cam_periph_release(periph); 763 return (0); 764 } 765 766 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, 767 ("cdclose\n")); 768 769 if ((softc->flags & CD_FLAG_DISC_REMOVABLE) != 0) 770 cdprevent(periph, PR_ALLOW); 771 772 /* 773 * Since we're closing this CD, mark the blocksize as unavailable. 774 * It will be marked as available when the CD is opened again. 775 */ 776 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE; 777 778 /* 779 * We'll check the media and toc again at the next open(). 780 */ 781 softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC); 782 783 cam_periph_unhold(periph); 784 cam_periph_release_locked(periph); 785 cam_periph_unlock(periph); 786 787 return (0); 788 } 789 790 static int 791 cdrunccb(union ccb *ccb, int (*error_routine)(union ccb *ccb, 792 u_int32_t cam_flags, 793 u_int32_t sense_flags), 794 u_int32_t cam_flags, u_int32_t sense_flags) 795 { 796 struct cd_softc *softc; 797 struct cam_periph *periph; 798 int error; 799 800 periph = xpt_path_periph(ccb->ccb_h.path); 801 softc = (struct cd_softc *)periph->softc; 802 803 error = cam_periph_runccb(ccb, error_routine, cam_flags, sense_flags, 804 softc->disk->d_devstat); 805 806 return(error); 807 } 808 809 /* 810 * Actually translate the requested transfer into one the physical driver 811 * can understand. The transfer is described by a buf and will include 812 * only one physical transfer. 813 */ 814 static void 815 cdstrategy(struct bio *bp) 816 { 817 struct cam_periph *periph; 818 struct cd_softc *softc; 819 820 periph = (struct cam_periph *)bp->bio_disk->d_drv1; 821 cam_periph_lock(periph); 822 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 823 ("cdstrategy(%p)\n", bp)); 824 825 softc = (struct cd_softc *)periph->softc; 826 827 /* 828 * If the device has been made invalid, error out 829 */ 830 if ((softc->flags & CD_FLAG_INVALID)) { 831 cam_periph_unlock(periph); 832 biofinish(bp, NULL, ENXIO); 833 return; 834 } 835 836 /* 837 * If we don't have valid media, look for it before trying to 838 * schedule the I/O. 839 */ 840 if ((softc->flags & CD_FLAG_VALID_MEDIA) == 0) { 841 int error; 842 843 error = cdcheckmedia(periph); 844 if (error != 0) { 845 cam_periph_unlock(periph); 846 biofinish(bp, NULL, error); 847 return; 848 } 849 } 850 851 /* 852 * Place it in the queue of disk activities for this disk 853 */ 854 bioq_disksort(&softc->bio_queue, bp); 855 856 xpt_schedule(periph, CAM_PRIORITY_NORMAL); 857 858 cam_periph_unlock(periph); 859 return; 860 } 861 862 static void 863 cdstart(struct cam_periph *periph, union ccb *start_ccb) 864 { 865 struct cd_softc *softc; 866 struct bio *bp; 867 struct ccb_scsiio *csio; 868 struct scsi_read_capacity_data *rcap; 869 870 softc = (struct cd_softc *)periph->softc; 871 872 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdstart\n")); 873 874 switch (softc->state) { 875 case CD_STATE_NORMAL: 876 { 877 bp = bioq_first(&softc->bio_queue); 878 if (bp == NULL) { 879 if (softc->tur) { 880 softc->tur = 0; 881 csio = &start_ccb->csio; 882 scsi_test_unit_ready(csio, 883 /*retries*/ cd_retry_count, 884 cddone, 885 MSG_SIMPLE_Q_TAG, 886 SSD_FULL_SIZE, 887 cd_timeout); 888 start_ccb->ccb_h.ccb_bp = NULL; 889 start_ccb->ccb_h.ccb_state = CD_CCB_TUR; 890 xpt_action(start_ccb); 891 } else 892 xpt_release_ccb(start_ccb); 893 } else { 894 if (softc->tur) { 895 softc->tur = 0; 896 cam_periph_release_locked(periph); 897 } 898 bioq_remove(&softc->bio_queue, bp); 899 900 scsi_read_write(&start_ccb->csio, 901 /*retries*/ cd_retry_count, 902 /* cbfcnp */ cddone, 903 MSG_SIMPLE_Q_TAG, 904 /* read */bp->bio_cmd == BIO_READ ? 905 SCSI_RW_READ : SCSI_RW_WRITE, 906 /* byte2 */ 0, 907 /* minimum_cmd_size */ 10, 908 /* lba */ bp->bio_offset / 909 softc->params.blksize, 910 bp->bio_bcount / softc->params.blksize, 911 /* data_ptr */ bp->bio_data, 912 /* dxfer_len */ bp->bio_bcount, 913 /* sense_len */ cd_retry_count ? 914 SSD_FULL_SIZE : SF_NO_PRINT, 915 /* timeout */ cd_timeout); 916 /* Use READ CD command for audio tracks. */ 917 if (softc->params.blksize == 2352) { 918 start_ccb->csio.cdb_io.cdb_bytes[0] = READ_CD; 919 start_ccb->csio.cdb_io.cdb_bytes[9] = 0xf8; 920 start_ccb->csio.cdb_io.cdb_bytes[10] = 0; 921 start_ccb->csio.cdb_io.cdb_bytes[11] = 0; 922 start_ccb->csio.cdb_len = 12; 923 } 924 start_ccb->ccb_h.ccb_state = CD_CCB_BUFFER_IO; 925 926 927 LIST_INSERT_HEAD(&softc->pending_ccbs, 928 &start_ccb->ccb_h, periph_links.le); 929 softc->outstanding_cmds++; 930 931 /* We expect a unit attention from this device */ 932 if ((softc->flags & CD_FLAG_RETRY_UA) != 0) { 933 start_ccb->ccb_h.ccb_state |= CD_CCB_RETRY_UA; 934 softc->flags &= ~CD_FLAG_RETRY_UA; 935 } 936 937 start_ccb->ccb_h.ccb_bp = bp; 938 bp = bioq_first(&softc->bio_queue); 939 940 xpt_action(start_ccb); 941 } 942 if (bp != NULL || softc->tur) { 943 /* Have more work to do, so ensure we stay scheduled */ 944 xpt_schedule(periph, CAM_PRIORITY_NORMAL); 945 } 946 break; 947 } 948 case CD_STATE_PROBE: 949 { 950 951 rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcap), 952 M_SCSICD, M_NOWAIT | M_ZERO); 953 if (rcap == NULL) { 954 xpt_print(periph->path, 955 "cdstart: Couldn't malloc read_capacity data\n"); 956 /* cd_free_periph??? */ 957 break; 958 } 959 csio = &start_ccb->csio; 960 scsi_read_capacity(csio, 961 /*retries*/ cd_retry_count, 962 cddone, 963 MSG_SIMPLE_Q_TAG, 964 rcap, 965 SSD_FULL_SIZE, 966 /*timeout*/20000); 967 start_ccb->ccb_h.ccb_bp = NULL; 968 start_ccb->ccb_h.ccb_state = CD_CCB_PROBE; 969 xpt_action(start_ccb); 970 break; 971 } 972 } 973 } 974 975 static void 976 cddone(struct cam_periph *periph, union ccb *done_ccb) 977 { 978 struct cd_softc *softc; 979 struct ccb_scsiio *csio; 980 981 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cddone\n")); 982 983 softc = (struct cd_softc *)periph->softc; 984 csio = &done_ccb->csio; 985 986 switch (csio->ccb_h.ccb_state & CD_CCB_TYPE_MASK) { 987 case CD_CCB_BUFFER_IO: 988 { 989 struct bio *bp; 990 int error; 991 992 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 993 error = 0; 994 995 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 996 int sf; 997 998 if ((done_ccb->ccb_h.ccb_state & CD_CCB_RETRY_UA) != 0) 999 sf = SF_RETRY_UA; 1000 else 1001 sf = 0; 1002 1003 error = cderror(done_ccb, CAM_RETRY_SELTO, sf); 1004 if (error == ERESTART) { 1005 /* 1006 * A retry was scheuled, so 1007 * just return. 1008 */ 1009 return; 1010 } 1011 } 1012 1013 if (error != 0) { 1014 xpt_print(periph->path, 1015 "cddone: got error %#x back\n", error); 1016 bioq_flush(&softc->bio_queue, NULL, EIO); 1017 bp->bio_resid = bp->bio_bcount; 1018 bp->bio_error = error; 1019 bp->bio_flags |= BIO_ERROR; 1020 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 1021 cam_release_devq(done_ccb->ccb_h.path, 1022 /*relsim_flags*/0, 1023 /*reduction*/0, 1024 /*timeout*/0, 1025 /*getcount_only*/0); 1026 1027 } else { 1028 bp->bio_resid = csio->resid; 1029 bp->bio_error = 0; 1030 if (bp->bio_resid != 0) { 1031 /* 1032 * Short transfer ??? 1033 * XXX: not sure this is correct for partial 1034 * transfers at EOM 1035 */ 1036 bp->bio_flags |= BIO_ERROR; 1037 } 1038 } 1039 1040 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 1041 softc->outstanding_cmds--; 1042 1043 biofinish(bp, NULL, 0); 1044 break; 1045 } 1046 case CD_CCB_PROBE: 1047 { 1048 struct scsi_read_capacity_data *rdcap; 1049 char announce_buf[120]; /* 1050 * Currently (9/30/97) the 1051 * longest possible announce 1052 * buffer is 108 bytes, for the 1053 * first error case below. 1054 * That is 39 bytes for the 1055 * basic string, 16 bytes for the 1056 * biggest sense key (hardware 1057 * error), 52 bytes for the 1058 * text of the largest sense 1059 * qualifier valid for a CDROM, 1060 * (0x72, 0x03 or 0x04, 1061 * 0x03), and one byte for the 1062 * null terminating character. 1063 * To allow for longer strings, 1064 * the announce buffer is 120 1065 * bytes. 1066 */ 1067 struct cd_params *cdp; 1068 int error; 1069 1070 cdp = &softc->params; 1071 1072 rdcap = (struct scsi_read_capacity_data *)csio->data_ptr; 1073 1074 cdp->disksize = scsi_4btoul (rdcap->addr) + 1; 1075 cdp->blksize = scsi_4btoul (rdcap->length); 1076 1077 /* 1078 * Retry any UNIT ATTENTION type errors. They 1079 * are expected at boot. 1080 */ 1081 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP || 1082 (error = cderror(done_ccb, CAM_RETRY_SELTO, 1083 SF_RETRY_UA | SF_NO_PRINT)) == 0) { 1084 1085 snprintf(announce_buf, sizeof(announce_buf), 1086 "cd present [%lu x %lu byte records]", 1087 cdp->disksize, (u_long)cdp->blksize); 1088 1089 } else { 1090 if (error == ERESTART) { 1091 /* 1092 * A retry was scheuled, so 1093 * just return. 1094 */ 1095 return; 1096 } else { 1097 int asc, ascq; 1098 int sense_key, error_code; 1099 int have_sense; 1100 cam_status status; 1101 struct ccb_getdev cgd; 1102 1103 /* Don't wedge this device's queue */ 1104 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 1105 cam_release_devq(done_ccb->ccb_h.path, 1106 /*relsim_flags*/0, 1107 /*reduction*/0, 1108 /*timeout*/0, 1109 /*getcount_only*/0); 1110 1111 status = done_ccb->ccb_h.status; 1112 1113 xpt_setup_ccb(&cgd.ccb_h, 1114 done_ccb->ccb_h.path, 1115 CAM_PRIORITY_NORMAL); 1116 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 1117 xpt_action((union ccb *)&cgd); 1118 1119 if (scsi_extract_sense_ccb(done_ccb, 1120 &error_code, &sense_key, &asc, &ascq)) 1121 have_sense = TRUE; 1122 else 1123 have_sense = FALSE; 1124 1125 /* 1126 * Attach to anything that claims to be a 1127 * CDROM or WORM device, as long as it 1128 * doesn't return a "Logical unit not 1129 * supported" (0x25) error. 1130 */ 1131 if ((have_sense) && (asc != 0x25) 1132 && (error_code == SSD_CURRENT_ERROR)) { 1133 const char *sense_key_desc; 1134 const char *asc_desc; 1135 1136 scsi_sense_desc(sense_key, asc, ascq, 1137 &cgd.inq_data, 1138 &sense_key_desc, 1139 &asc_desc); 1140 snprintf(announce_buf, 1141 sizeof(announce_buf), 1142 "Attempt to query device " 1143 "size failed: %s, %s", 1144 sense_key_desc, 1145 asc_desc); 1146 } else if ((have_sense == 0) 1147 && ((status & CAM_STATUS_MASK) == 1148 CAM_SCSI_STATUS_ERROR) 1149 && (csio->scsi_status == 1150 SCSI_STATUS_BUSY)) { 1151 snprintf(announce_buf, 1152 sizeof(announce_buf), 1153 "Attempt to query device " 1154 "size failed: SCSI Status: %s", 1155 scsi_status_string(csio)); 1156 } else if (SID_TYPE(&cgd.inq_data) == T_CDROM) { 1157 /* 1158 * We only print out an error for 1159 * CDROM type devices. For WORM 1160 * devices, we don't print out an 1161 * error since a few WORM devices 1162 * don't support CDROM commands. 1163 * If we have sense information, go 1164 * ahead and print it out. 1165 * Otherwise, just say that we 1166 * couldn't attach. 1167 */ 1168 1169 /* 1170 * Just print out the error, not 1171 * the full probe message, when we 1172 * don't attach. 1173 */ 1174 if (have_sense) 1175 scsi_sense_print( 1176 &done_ccb->csio); 1177 else { 1178 xpt_print(periph->path, 1179 "got CAM status %#x\n", 1180 done_ccb->ccb_h.status); 1181 } 1182 xpt_print(periph->path, "fatal error, " 1183 "failed to attach to device\n"); 1184 /* 1185 * Invalidate this peripheral. 1186 */ 1187 cam_periph_invalidate(periph); 1188 1189 announce_buf[0] = '\0'; 1190 } else { 1191 1192 /* 1193 * Invalidate this peripheral. 1194 */ 1195 cam_periph_invalidate(periph); 1196 announce_buf[0] = '\0'; 1197 } 1198 } 1199 } 1200 free(rdcap, M_SCSICD); 1201 if (announce_buf[0] != '\0') { 1202 xpt_announce_periph(periph, announce_buf); 1203 xpt_announce_quirks(periph, softc->quirks, 1204 CD_Q_BIT_STRING); 1205 /* 1206 * Create our sysctl variables, now that we know 1207 * we have successfully attached. 1208 */ 1209 taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task); 1210 } 1211 softc->state = CD_STATE_NORMAL; 1212 /* 1213 * Since our peripheral may be invalidated by an error 1214 * above or an external event, we must release our CCB 1215 * before releasing the probe lock on the peripheral. 1216 * The peripheral will only go away once the last lock 1217 * is removed, and we need it around for the CCB release 1218 * operation. 1219 */ 1220 xpt_release_ccb(done_ccb); 1221 cam_periph_unhold(periph); 1222 return; 1223 } 1224 case CD_CCB_TUR: 1225 { 1226 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1227 1228 if (cderror(done_ccb, CAM_RETRY_SELTO, 1229 SF_RETRY_UA | SF_NO_RECOVERY | SF_NO_PRINT) == 1230 ERESTART) 1231 return; 1232 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 1233 cam_release_devq(done_ccb->ccb_h.path, 1234 /*relsim_flags*/0, 1235 /*reduction*/0, 1236 /*timeout*/0, 1237 /*getcount_only*/0); 1238 } 1239 xpt_release_ccb(done_ccb); 1240 cam_periph_release_locked(periph); 1241 return; 1242 } 1243 default: 1244 break; 1245 } 1246 xpt_release_ccb(done_ccb); 1247 } 1248 1249 static union cd_pages * 1250 cdgetpage(struct cd_mode_params *mode_params) 1251 { 1252 union cd_pages *page; 1253 1254 if (mode_params->cdb_size == 10) 1255 page = (union cd_pages *)find_mode_page_10( 1256 (struct scsi_mode_header_10 *)mode_params->mode_buf); 1257 else 1258 page = (union cd_pages *)find_mode_page_6( 1259 (struct scsi_mode_header_6 *)mode_params->mode_buf); 1260 1261 return (page); 1262 } 1263 1264 static int 1265 cdgetpagesize(int page_num) 1266 { 1267 int i; 1268 1269 for (i = 0; i < (sizeof(cd_page_size_table)/ 1270 sizeof(cd_page_size_table[0])); i++) { 1271 if (cd_page_size_table[i].page == page_num) 1272 return (cd_page_size_table[i].page_size); 1273 } 1274 1275 return (-1); 1276 } 1277 1278 static int 1279 cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) 1280 { 1281 1282 struct cam_periph *periph; 1283 struct cd_softc *softc; 1284 int nocopyout, error = 0; 1285 1286 periph = (struct cam_periph *)dp->d_drv1; 1287 cam_periph_lock(periph); 1288 1289 softc = (struct cd_softc *)periph->softc; 1290 1291 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 1292 ("cdioctl(%#lx)\n", cmd)); 1293 1294 if ((error = cam_periph_hold(periph, PRIBIO | PCATCH)) != 0) { 1295 cam_periph_unlock(periph); 1296 cam_periph_release(periph); 1297 return (error); 1298 } 1299 1300 /* 1301 * If we don't have media loaded, check for it. If still don't 1302 * have media loaded, we can only do a load or eject. 1303 * 1304 * We only care whether media is loaded if this is a cd-specific ioctl 1305 * (thus the IOCGROUP check below). Note that this will break if 1306 * anyone adds any ioctls into the switch statement below that don't 1307 * have their ioctl group set to 'c'. 1308 */ 1309 if (((softc->flags & CD_FLAG_VALID_MEDIA) == 0) 1310 && ((cmd != CDIOCCLOSE) 1311 && (cmd != CDIOCEJECT)) 1312 && (IOCGROUP(cmd) == 'c')) { 1313 error = cdcheckmedia(periph); 1314 if (error != 0) { 1315 cam_periph_unhold(periph); 1316 cam_periph_unlock(periph); 1317 return (error); 1318 } 1319 } 1320 /* 1321 * Drop the lock here so later mallocs can use WAITOK. The periph 1322 * is essentially locked still with the cam_periph_hold call above. 1323 */ 1324 cam_periph_unlock(periph); 1325 1326 nocopyout = 0; 1327 switch (cmd) { 1328 1329 case CDIOCPLAYTRACKS: 1330 { 1331 struct ioc_play_track *args 1332 = (struct ioc_play_track *) addr; 1333 struct cd_mode_params params; 1334 union cd_pages *page; 1335 1336 params.alloc_len = sizeof(union cd_mode_data_6_10); 1337 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1338 M_WAITOK | M_ZERO); 1339 1340 cam_periph_lock(periph); 1341 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1342 ("trying to do CDIOCPLAYTRACKS\n")); 1343 1344 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1345 if (error) { 1346 free(params.mode_buf, M_SCSICD); 1347 cam_periph_unlock(periph); 1348 break; 1349 } 1350 page = cdgetpage(¶ms); 1351 1352 page->audio.flags &= ~CD_PA_SOTC; 1353 page->audio.flags |= CD_PA_IMMED; 1354 error = cdsetmode(periph, ¶ms); 1355 free(params.mode_buf, M_SCSICD); 1356 if (error) { 1357 cam_periph_unlock(periph); 1358 break; 1359 } 1360 1361 /* 1362 * This was originally implemented with the PLAY 1363 * AUDIO TRACK INDEX command, but that command was 1364 * deprecated after SCSI-2. Most (all?) SCSI CDROM 1365 * drives support it but ATAPI and ATAPI-derivative 1366 * drives don't seem to support it. So we keep a 1367 * cache of the table of contents and translate 1368 * track numbers to MSF format. 1369 */ 1370 if (softc->flags & CD_FLAG_VALID_TOC) { 1371 union msf_lba *sentry, *eentry; 1372 int st, et; 1373 1374 if (args->end_track < 1375 softc->toc.header.ending_track + 1) 1376 args->end_track++; 1377 if (args->end_track > 1378 softc->toc.header.ending_track + 1) 1379 args->end_track = 1380 softc->toc.header.ending_track + 1; 1381 st = args->start_track - 1382 softc->toc.header.starting_track; 1383 et = args->end_track - 1384 softc->toc.header.starting_track; 1385 if ((st < 0) 1386 || (et < 0) 1387 || (st > (softc->toc.header.ending_track - 1388 softc->toc.header.starting_track))) { 1389 error = EINVAL; 1390 cam_periph_unlock(periph); 1391 break; 1392 } 1393 sentry = &softc->toc.entries[st].addr; 1394 eentry = &softc->toc.entries[et].addr; 1395 error = cdplaymsf(periph, 1396 sentry->msf.minute, 1397 sentry->msf.second, 1398 sentry->msf.frame, 1399 eentry->msf.minute, 1400 eentry->msf.second, 1401 eentry->msf.frame); 1402 } else { 1403 /* 1404 * If we don't have a valid TOC, try the 1405 * play track index command. It is part of 1406 * the SCSI-2 spec, but was removed in the 1407 * MMC specs. ATAPI and ATAPI-derived 1408 * drives don't support it. 1409 */ 1410 if (softc->quirks & CD_Q_BCD_TRACKS) { 1411 args->start_track = 1412 bin2bcd(args->start_track); 1413 args->end_track = 1414 bin2bcd(args->end_track); 1415 } 1416 error = cdplaytracks(periph, 1417 args->start_track, 1418 args->start_index, 1419 args->end_track, 1420 args->end_index); 1421 } 1422 cam_periph_unlock(periph); 1423 } 1424 break; 1425 case CDIOCPLAYMSF: 1426 { 1427 struct ioc_play_msf *args 1428 = (struct ioc_play_msf *) addr; 1429 struct cd_mode_params params; 1430 union cd_pages *page; 1431 1432 params.alloc_len = sizeof(union cd_mode_data_6_10); 1433 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1434 M_WAITOK | M_ZERO); 1435 1436 cam_periph_lock(periph); 1437 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1438 ("trying to do CDIOCPLAYMSF\n")); 1439 1440 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1441 if (error) { 1442 free(params.mode_buf, M_SCSICD); 1443 cam_periph_unlock(periph); 1444 break; 1445 } 1446 page = cdgetpage(¶ms); 1447 1448 page->audio.flags &= ~CD_PA_SOTC; 1449 page->audio.flags |= CD_PA_IMMED; 1450 error = cdsetmode(periph, ¶ms); 1451 free(params.mode_buf, M_SCSICD); 1452 if (error) { 1453 cam_periph_unlock(periph); 1454 break; 1455 } 1456 error = cdplaymsf(periph, 1457 args->start_m, 1458 args->start_s, 1459 args->start_f, 1460 args->end_m, 1461 args->end_s, 1462 args->end_f); 1463 cam_periph_unlock(periph); 1464 } 1465 break; 1466 case CDIOCPLAYBLOCKS: 1467 { 1468 struct ioc_play_blocks *args 1469 = (struct ioc_play_blocks *) addr; 1470 struct cd_mode_params params; 1471 union cd_pages *page; 1472 1473 params.alloc_len = sizeof(union cd_mode_data_6_10); 1474 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1475 M_WAITOK | M_ZERO); 1476 1477 cam_periph_lock(periph); 1478 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1479 ("trying to do CDIOCPLAYBLOCKS\n")); 1480 1481 1482 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1483 if (error) { 1484 free(params.mode_buf, M_SCSICD); 1485 cam_periph_unlock(periph); 1486 break; 1487 } 1488 page = cdgetpage(¶ms); 1489 1490 page->audio.flags &= ~CD_PA_SOTC; 1491 page->audio.flags |= CD_PA_IMMED; 1492 error = cdsetmode(periph, ¶ms); 1493 free(params.mode_buf, M_SCSICD); 1494 if (error) { 1495 cam_periph_unlock(periph); 1496 break; 1497 } 1498 error = cdplay(periph, args->blk, args->len); 1499 cam_periph_unlock(periph); 1500 } 1501 break; 1502 case CDIOCREADSUBCHANNEL_SYSSPACE: 1503 nocopyout = 1; 1504 /* Fallthrough */ 1505 case CDIOCREADSUBCHANNEL: 1506 { 1507 struct ioc_read_subchannel *args 1508 = (struct ioc_read_subchannel *) addr; 1509 struct cd_sub_channel_info *data; 1510 u_int32_t len = args->data_len; 1511 1512 data = malloc(sizeof(struct cd_sub_channel_info), 1513 M_SCSICD, M_WAITOK | M_ZERO); 1514 1515 cam_periph_lock(periph); 1516 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1517 ("trying to do CDIOCREADSUBCHANNEL\n")); 1518 1519 if ((len > sizeof(struct cd_sub_channel_info)) || 1520 (len < sizeof(struct cd_sub_channel_header))) { 1521 printf( 1522 "scsi_cd: cdioctl: " 1523 "cdioreadsubchannel: error, len=%d\n", 1524 len); 1525 error = EINVAL; 1526 free(data, M_SCSICD); 1527 cam_periph_unlock(periph); 1528 break; 1529 } 1530 1531 if (softc->quirks & CD_Q_BCD_TRACKS) 1532 args->track = bin2bcd(args->track); 1533 1534 error = cdreadsubchannel(periph, args->address_format, 1535 args->data_format, args->track, data, len); 1536 1537 if (error) { 1538 free(data, M_SCSICD); 1539 cam_periph_unlock(periph); 1540 break; 1541 } 1542 if (softc->quirks & CD_Q_BCD_TRACKS) 1543 data->what.track_info.track_number = 1544 bcd2bin(data->what.track_info.track_number); 1545 len = min(len, ((data->header.data_len[0] << 8) + 1546 data->header.data_len[1] + 1547 sizeof(struct cd_sub_channel_header))); 1548 cam_periph_unlock(periph); 1549 if (nocopyout == 0) { 1550 if (copyout(data, args->data, len) != 0) { 1551 error = EFAULT; 1552 } 1553 } else { 1554 bcopy(data, args->data, len); 1555 } 1556 free(data, M_SCSICD); 1557 } 1558 break; 1559 1560 case CDIOREADTOCHEADER: 1561 { 1562 struct ioc_toc_header *th; 1563 1564 th = malloc(sizeof(struct ioc_toc_header), M_SCSICD, 1565 M_WAITOK | M_ZERO); 1566 1567 cam_periph_lock(periph); 1568 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1569 ("trying to do CDIOREADTOCHEADER\n")); 1570 1571 error = cdreadtoc(periph, 0, 0, (u_int8_t *)th, 1572 sizeof (*th), /*sense_flags*/SF_NO_PRINT); 1573 if (error) { 1574 free(th, M_SCSICD); 1575 cam_periph_unlock(periph); 1576 break; 1577 } 1578 if (softc->quirks & CD_Q_BCD_TRACKS) { 1579 /* we are going to have to convert the BCD 1580 * encoding on the cd to what is expected 1581 */ 1582 th->starting_track = 1583 bcd2bin(th->starting_track); 1584 th->ending_track = bcd2bin(th->ending_track); 1585 } 1586 th->len = ntohs(th->len); 1587 bcopy(th, addr, sizeof(*th)); 1588 free(th, M_SCSICD); 1589 cam_periph_unlock(periph); 1590 } 1591 break; 1592 case CDIOREADTOCENTRYS: 1593 { 1594 struct cd_tocdata *data; 1595 struct cd_toc_single *lead; 1596 struct ioc_read_toc_entry *te = 1597 (struct ioc_read_toc_entry *) addr; 1598 struct ioc_toc_header *th; 1599 u_int32_t len, readlen, idx, num; 1600 u_int32_t starting_track = te->starting_track; 1601 1602 data = malloc(sizeof(*data), M_SCSICD, M_WAITOK | M_ZERO); 1603 lead = malloc(sizeof(*lead), M_SCSICD, M_WAITOK | M_ZERO); 1604 1605 cam_periph_lock(periph); 1606 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1607 ("trying to do CDIOREADTOCENTRYS\n")); 1608 1609 if (te->data_len < sizeof(struct cd_toc_entry) 1610 || (te->data_len % sizeof(struct cd_toc_entry)) != 0 1611 || (te->address_format != CD_MSF_FORMAT 1612 && te->address_format != CD_LBA_FORMAT)) { 1613 error = EINVAL; 1614 printf("scsi_cd: error in readtocentries, " 1615 "returning EINVAL\n"); 1616 free(data, M_SCSICD); 1617 free(lead, M_SCSICD); 1618 cam_periph_unlock(periph); 1619 break; 1620 } 1621 1622 th = &data->header; 1623 error = cdreadtoc(periph, 0, 0, (u_int8_t *)th, 1624 sizeof (*th), /*sense_flags*/0); 1625 if (error) { 1626 free(data, M_SCSICD); 1627 free(lead, M_SCSICD); 1628 cam_periph_unlock(periph); 1629 break; 1630 } 1631 1632 if (softc->quirks & CD_Q_BCD_TRACKS) { 1633 /* we are going to have to convert the BCD 1634 * encoding on the cd to what is expected 1635 */ 1636 th->starting_track = 1637 bcd2bin(th->starting_track); 1638 th->ending_track = bcd2bin(th->ending_track); 1639 } 1640 1641 if (starting_track == 0) 1642 starting_track = th->starting_track; 1643 else if (starting_track == LEADOUT) 1644 starting_track = th->ending_track + 1; 1645 else if (starting_track < th->starting_track || 1646 starting_track > th->ending_track + 1) { 1647 printf("scsi_cd: error in readtocentries, " 1648 "returning EINVAL\n"); 1649 free(data, M_SCSICD); 1650 free(lead, M_SCSICD); 1651 cam_periph_unlock(periph); 1652 error = EINVAL; 1653 break; 1654 } 1655 1656 /* calculate reading length without leadout entry */ 1657 readlen = (th->ending_track - starting_track + 1) * 1658 sizeof(struct cd_toc_entry); 1659 1660 /* and with leadout entry */ 1661 len = readlen + sizeof(struct cd_toc_entry); 1662 if (te->data_len < len) { 1663 len = te->data_len; 1664 if (readlen > len) 1665 readlen = len; 1666 } 1667 if (len > sizeof(data->entries)) { 1668 printf("scsi_cd: error in readtocentries, " 1669 "returning EINVAL\n"); 1670 error = EINVAL; 1671 free(data, M_SCSICD); 1672 free(lead, M_SCSICD); 1673 cam_periph_unlock(periph); 1674 break; 1675 } 1676 num = len / sizeof(struct cd_toc_entry); 1677 1678 if (readlen > 0) { 1679 error = cdreadtoc(periph, te->address_format, 1680 starting_track, 1681 (u_int8_t *)data, 1682 readlen + sizeof (*th), 1683 /*sense_flags*/0); 1684 if (error) { 1685 free(data, M_SCSICD); 1686 free(lead, M_SCSICD); 1687 cam_periph_unlock(periph); 1688 break; 1689 } 1690 } 1691 1692 /* make leadout entry if needed */ 1693 idx = starting_track + num - 1; 1694 if (softc->quirks & CD_Q_BCD_TRACKS) 1695 th->ending_track = bcd2bin(th->ending_track); 1696 if (idx == th->ending_track + 1) { 1697 error = cdreadtoc(periph, te->address_format, 1698 LEADOUT, (u_int8_t *)lead, 1699 sizeof(*lead), 1700 /*sense_flags*/0); 1701 if (error) { 1702 free(data, M_SCSICD); 1703 free(lead, M_SCSICD); 1704 cam_periph_unlock(periph); 1705 break; 1706 } 1707 data->entries[idx - starting_track] = 1708 lead->entry; 1709 } 1710 if (softc->quirks & CD_Q_BCD_TRACKS) { 1711 for (idx = 0; idx < num - 1; idx++) { 1712 data->entries[idx].track = 1713 bcd2bin(data->entries[idx].track); 1714 } 1715 } 1716 1717 cam_periph_unlock(periph); 1718 error = copyout(data->entries, te->data, len); 1719 free(data, M_SCSICD); 1720 free(lead, M_SCSICD); 1721 } 1722 break; 1723 case CDIOREADTOCENTRY: 1724 { 1725 struct cd_toc_single *data; 1726 struct ioc_read_toc_single_entry *te = 1727 (struct ioc_read_toc_single_entry *) addr; 1728 struct ioc_toc_header *th; 1729 u_int32_t track; 1730 1731 data = malloc(sizeof(*data), M_SCSICD, M_WAITOK | M_ZERO); 1732 1733 cam_periph_lock(periph); 1734 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1735 ("trying to do CDIOREADTOCENTRY\n")); 1736 1737 if (te->address_format != CD_MSF_FORMAT 1738 && te->address_format != CD_LBA_FORMAT) { 1739 printf("error in readtocentry, " 1740 " returning EINVAL\n"); 1741 free(data, M_SCSICD); 1742 error = EINVAL; 1743 cam_periph_unlock(periph); 1744 break; 1745 } 1746 1747 th = &data->header; 1748 error = cdreadtoc(periph, 0, 0, (u_int8_t *)th, 1749 sizeof (*th), /*sense_flags*/0); 1750 if (error) { 1751 free(data, M_SCSICD); 1752 cam_periph_unlock(periph); 1753 break; 1754 } 1755 1756 if (softc->quirks & CD_Q_BCD_TRACKS) { 1757 /* we are going to have to convert the BCD 1758 * encoding on the cd to what is expected 1759 */ 1760 th->starting_track = 1761 bcd2bin(th->starting_track); 1762 th->ending_track = bcd2bin(th->ending_track); 1763 } 1764 track = te->track; 1765 if (track == 0) 1766 track = th->starting_track; 1767 else if (track == LEADOUT) 1768 /* OK */; 1769 else if (track < th->starting_track || 1770 track > th->ending_track + 1) { 1771 printf("error in readtocentry, " 1772 " returning EINVAL\n"); 1773 free(data, M_SCSICD); 1774 error = EINVAL; 1775 cam_periph_unlock(periph); 1776 break; 1777 } 1778 1779 error = cdreadtoc(periph, te->address_format, track, 1780 (u_int8_t *)data, sizeof(*data), 1781 /*sense_flags*/0); 1782 if (error) { 1783 free(data, M_SCSICD); 1784 cam_periph_unlock(periph); 1785 break; 1786 } 1787 1788 if (softc->quirks & CD_Q_BCD_TRACKS) 1789 data->entry.track = bcd2bin(data->entry.track); 1790 bcopy(&data->entry, &te->entry, 1791 sizeof(struct cd_toc_entry)); 1792 free(data, M_SCSICD); 1793 cam_periph_unlock(periph); 1794 } 1795 break; 1796 case CDIOCSETPATCH: 1797 { 1798 struct ioc_patch *arg = (struct ioc_patch *)addr; 1799 struct cd_mode_params params; 1800 union cd_pages *page; 1801 1802 params.alloc_len = sizeof(union cd_mode_data_6_10); 1803 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1804 M_WAITOK | M_ZERO); 1805 1806 cam_periph_lock(periph); 1807 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1808 ("trying to do CDIOCSETPATCH\n")); 1809 1810 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1811 if (error) { 1812 free(params.mode_buf, M_SCSICD); 1813 cam_periph_unlock(periph); 1814 break; 1815 } 1816 page = cdgetpage(¶ms); 1817 1818 page->audio.port[LEFT_PORT].channels = 1819 arg->patch[0]; 1820 page->audio.port[RIGHT_PORT].channels = 1821 arg->patch[1]; 1822 page->audio.port[2].channels = arg->patch[2]; 1823 page->audio.port[3].channels = arg->patch[3]; 1824 error = cdsetmode(periph, ¶ms); 1825 free(params.mode_buf, M_SCSICD); 1826 cam_periph_unlock(periph); 1827 } 1828 break; 1829 case CDIOCGETVOL: 1830 { 1831 struct ioc_vol *arg = (struct ioc_vol *) addr; 1832 struct cd_mode_params params; 1833 union cd_pages *page; 1834 1835 params.alloc_len = sizeof(union cd_mode_data_6_10); 1836 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1837 M_WAITOK | M_ZERO); 1838 1839 cam_periph_lock(periph); 1840 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1841 ("trying to do CDIOCGETVOL\n")); 1842 1843 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1844 if (error) { 1845 free(params.mode_buf, M_SCSICD); 1846 cam_periph_unlock(periph); 1847 break; 1848 } 1849 page = cdgetpage(¶ms); 1850 1851 arg->vol[LEFT_PORT] = 1852 page->audio.port[LEFT_PORT].volume; 1853 arg->vol[RIGHT_PORT] = 1854 page->audio.port[RIGHT_PORT].volume; 1855 arg->vol[2] = page->audio.port[2].volume; 1856 arg->vol[3] = page->audio.port[3].volume; 1857 free(params.mode_buf, M_SCSICD); 1858 cam_periph_unlock(periph); 1859 } 1860 break; 1861 case CDIOCSETVOL: 1862 { 1863 struct ioc_vol *arg = (struct ioc_vol *) addr; 1864 struct cd_mode_params params; 1865 union cd_pages *page; 1866 1867 params.alloc_len = sizeof(union cd_mode_data_6_10); 1868 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1869 M_WAITOK | M_ZERO); 1870 1871 cam_periph_lock(periph); 1872 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1873 ("trying to do CDIOCSETVOL\n")); 1874 1875 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1876 if (error) { 1877 free(params.mode_buf, M_SCSICD); 1878 cam_periph_unlock(periph); 1879 break; 1880 } 1881 page = cdgetpage(¶ms); 1882 1883 page->audio.port[LEFT_PORT].channels = CHANNEL_0; 1884 page->audio.port[LEFT_PORT].volume = 1885 arg->vol[LEFT_PORT]; 1886 page->audio.port[RIGHT_PORT].channels = CHANNEL_1; 1887 page->audio.port[RIGHT_PORT].volume = 1888 arg->vol[RIGHT_PORT]; 1889 page->audio.port[2].volume = arg->vol[2]; 1890 page->audio.port[3].volume = arg->vol[3]; 1891 error = cdsetmode(periph, ¶ms); 1892 cam_periph_unlock(periph); 1893 free(params.mode_buf, M_SCSICD); 1894 } 1895 break; 1896 case CDIOCSETMONO: 1897 { 1898 struct cd_mode_params params; 1899 union cd_pages *page; 1900 1901 params.alloc_len = sizeof(union cd_mode_data_6_10); 1902 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1903 M_WAITOK | M_ZERO); 1904 1905 cam_periph_lock(periph); 1906 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1907 ("trying to do CDIOCSETMONO\n")); 1908 1909 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1910 if (error) { 1911 free(params.mode_buf, M_SCSICD); 1912 cam_periph_unlock(periph); 1913 break; 1914 } 1915 page = cdgetpage(¶ms); 1916 1917 page->audio.port[LEFT_PORT].channels = 1918 LEFT_CHANNEL | RIGHT_CHANNEL; 1919 page->audio.port[RIGHT_PORT].channels = 1920 LEFT_CHANNEL | RIGHT_CHANNEL; 1921 page->audio.port[2].channels = 0; 1922 page->audio.port[3].channels = 0; 1923 error = cdsetmode(periph, ¶ms); 1924 cam_periph_unlock(periph); 1925 free(params.mode_buf, M_SCSICD); 1926 } 1927 break; 1928 case CDIOCSETSTEREO: 1929 { 1930 struct cd_mode_params params; 1931 union cd_pages *page; 1932 1933 params.alloc_len = sizeof(union cd_mode_data_6_10); 1934 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1935 M_WAITOK | M_ZERO); 1936 1937 cam_periph_lock(periph); 1938 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1939 ("trying to do CDIOCSETSTEREO\n")); 1940 1941 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1942 if (error) { 1943 free(params.mode_buf, M_SCSICD); 1944 cam_periph_unlock(periph); 1945 break; 1946 } 1947 page = cdgetpage(¶ms); 1948 1949 page->audio.port[LEFT_PORT].channels = 1950 LEFT_CHANNEL; 1951 page->audio.port[RIGHT_PORT].channels = 1952 RIGHT_CHANNEL; 1953 page->audio.port[2].channels = 0; 1954 page->audio.port[3].channels = 0; 1955 error = cdsetmode(periph, ¶ms); 1956 free(params.mode_buf, M_SCSICD); 1957 cam_periph_unlock(periph); 1958 } 1959 break; 1960 case CDIOCSETMUTE: 1961 { 1962 struct cd_mode_params params; 1963 union cd_pages *page; 1964 1965 params.alloc_len = sizeof(union cd_mode_data_6_10); 1966 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1967 M_WAITOK | M_ZERO); 1968 1969 cam_periph_lock(periph); 1970 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1971 ("trying to do CDIOCSETMUTE\n")); 1972 1973 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 1974 if (error) { 1975 free(params.mode_buf, M_SCSICD); 1976 cam_periph_unlock(periph); 1977 break; 1978 } 1979 page = cdgetpage(¶ms); 1980 1981 page->audio.port[LEFT_PORT].channels = 0; 1982 page->audio.port[RIGHT_PORT].channels = 0; 1983 page->audio.port[2].channels = 0; 1984 page->audio.port[3].channels = 0; 1985 error = cdsetmode(periph, ¶ms); 1986 free(params.mode_buf, M_SCSICD); 1987 cam_periph_unlock(periph); 1988 } 1989 break; 1990 case CDIOCSETLEFT: 1991 { 1992 struct cd_mode_params params; 1993 union cd_pages *page; 1994 1995 params.alloc_len = sizeof(union cd_mode_data_6_10); 1996 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 1997 M_WAITOK | M_ZERO); 1998 1999 cam_periph_lock(periph); 2000 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 2001 ("trying to do CDIOCSETLEFT\n")); 2002 2003 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 2004 if (error) { 2005 free(params.mode_buf, M_SCSICD); 2006 cam_periph_unlock(periph); 2007 break; 2008 } 2009 page = cdgetpage(¶ms); 2010 2011 page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL; 2012 page->audio.port[RIGHT_PORT].channels = LEFT_CHANNEL; 2013 page->audio.port[2].channels = 0; 2014 page->audio.port[3].channels = 0; 2015 error = cdsetmode(periph, ¶ms); 2016 free(params.mode_buf, M_SCSICD); 2017 cam_periph_unlock(periph); 2018 } 2019 break; 2020 case CDIOCSETRIGHT: 2021 { 2022 struct cd_mode_params params; 2023 union cd_pages *page; 2024 2025 params.alloc_len = sizeof(union cd_mode_data_6_10); 2026 params.mode_buf = malloc(params.alloc_len, M_SCSICD, 2027 M_WAITOK | M_ZERO); 2028 2029 cam_periph_lock(periph); 2030 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 2031 ("trying to do CDIOCSETRIGHT\n")); 2032 2033 error = cdgetmode(periph, ¶ms, AUDIO_PAGE); 2034 if (error) { 2035 free(params.mode_buf, M_SCSICD); 2036 cam_periph_unlock(periph); 2037 break; 2038 } 2039 page = cdgetpage(¶ms); 2040 2041 page->audio.port[LEFT_PORT].channels = RIGHT_CHANNEL; 2042 page->audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; 2043 page->audio.port[2].channels = 0; 2044 page->audio.port[3].channels = 0; 2045 error = cdsetmode(periph, ¶ms); 2046 free(params.mode_buf, M_SCSICD); 2047 cam_periph_unlock(periph); 2048 } 2049 break; 2050 case CDIOCRESUME: 2051 cam_periph_lock(periph); 2052 error = cdpause(periph, 1); 2053 cam_periph_unlock(periph); 2054 break; 2055 case CDIOCPAUSE: 2056 cam_periph_lock(periph); 2057 error = cdpause(periph, 0); 2058 cam_periph_unlock(periph); 2059 break; 2060 case CDIOCSTART: 2061 cam_periph_lock(periph); 2062 error = cdstartunit(periph, 0); 2063 cam_periph_unlock(periph); 2064 break; 2065 case CDIOCCLOSE: 2066 cam_periph_lock(periph); 2067 error = cdstartunit(periph, 1); 2068 cam_periph_unlock(periph); 2069 break; 2070 case CDIOCSTOP: 2071 cam_periph_lock(periph); 2072 error = cdstopunit(periph, 0); 2073 cam_periph_unlock(periph); 2074 break; 2075 case CDIOCEJECT: 2076 cam_periph_lock(periph); 2077 error = cdstopunit(periph, 1); 2078 cam_periph_unlock(periph); 2079 break; 2080 case CDIOCALLOW: 2081 cam_periph_lock(periph); 2082 cdprevent(periph, PR_ALLOW); 2083 cam_periph_unlock(periph); 2084 break; 2085 case CDIOCPREVENT: 2086 cam_periph_lock(periph); 2087 cdprevent(periph, PR_PREVENT); 2088 cam_periph_unlock(periph); 2089 break; 2090 case CDIOCSETDEBUG: 2091 /* sc_link->flags |= (SDEV_DB1 | SDEV_DB2); */ 2092 error = ENOTTY; 2093 break; 2094 case CDIOCCLRDEBUG: 2095 /* sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2); */ 2096 error = ENOTTY; 2097 break; 2098 case CDIOCRESET: 2099 /* return (cd_reset(periph)); */ 2100 error = ENOTTY; 2101 break; 2102 case CDRIOCREADSPEED: 2103 cam_periph_lock(periph); 2104 error = cdsetspeed(periph, *(u_int32_t *)addr, CDR_MAX_SPEED); 2105 cam_periph_unlock(periph); 2106 break; 2107 case CDRIOCWRITESPEED: 2108 cam_periph_lock(periph); 2109 error = cdsetspeed(periph, CDR_MAX_SPEED, *(u_int32_t *)addr); 2110 cam_periph_unlock(periph); 2111 break; 2112 case CDRIOCGETBLOCKSIZE: 2113 *(int *)addr = softc->params.blksize; 2114 break; 2115 case CDRIOCSETBLOCKSIZE: 2116 if (*(int *)addr <= 0) { 2117 error = EINVAL; 2118 break; 2119 } 2120 softc->disk->d_sectorsize = softc->params.blksize = *(int *)addr; 2121 break; 2122 case DVDIOCSENDKEY: 2123 case DVDIOCREPORTKEY: { 2124 struct dvd_authinfo *authinfo; 2125 2126 authinfo = (struct dvd_authinfo *)addr; 2127 2128 if (cmd == DVDIOCREPORTKEY) 2129 error = cdreportkey(periph, authinfo); 2130 else 2131 error = cdsendkey(periph, authinfo); 2132 break; 2133 } 2134 case DVDIOCREADSTRUCTURE: { 2135 struct dvd_struct *dvdstruct; 2136 2137 dvdstruct = (struct dvd_struct *)addr; 2138 2139 error = cdreaddvdstructure(periph, dvdstruct); 2140 2141 break; 2142 } 2143 default: 2144 cam_periph_lock(periph); 2145 error = cam_periph_ioctl(periph, cmd, addr, cderror); 2146 cam_periph_unlock(periph); 2147 break; 2148 } 2149 2150 cam_periph_lock(periph); 2151 cam_periph_unhold(periph); 2152 2153 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("leaving cdioctl\n")); 2154 if (error && bootverbose) { 2155 printf("scsi_cd.c::ioctl cmd=%08lx error=%d\n", cmd, error); 2156 } 2157 cam_periph_unlock(periph); 2158 2159 return (error); 2160 } 2161 2162 static void 2163 cdprevent(struct cam_periph *periph, int action) 2164 { 2165 union ccb *ccb; 2166 struct cd_softc *softc; 2167 int error; 2168 2169 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdprevent\n")); 2170 2171 softc = (struct cd_softc *)periph->softc; 2172 2173 if (((action == PR_ALLOW) 2174 && (softc->flags & CD_FLAG_DISC_LOCKED) == 0) 2175 || ((action == PR_PREVENT) 2176 && (softc->flags & CD_FLAG_DISC_LOCKED) != 0)) { 2177 return; 2178 } 2179 2180 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2181 2182 scsi_prevent(&ccb->csio, 2183 /*retries*/ cd_retry_count, 2184 cddone, 2185 MSG_SIMPLE_Q_TAG, 2186 action, 2187 SSD_FULL_SIZE, 2188 /* timeout */60000); 2189 2190 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2191 /*sense_flags*/SF_RETRY_UA|SF_NO_PRINT); 2192 2193 xpt_release_ccb(ccb); 2194 2195 if (error == 0) { 2196 if (action == PR_ALLOW) 2197 softc->flags &= ~CD_FLAG_DISC_LOCKED; 2198 else 2199 softc->flags |= CD_FLAG_DISC_LOCKED; 2200 } 2201 } 2202 2203 /* 2204 * XXX: the disk media and sector size is only really able to change 2205 * XXX: while the device is closed. 2206 */ 2207 static int 2208 cdcheckmedia(struct cam_periph *periph) 2209 { 2210 struct cd_softc *softc; 2211 struct ioc_toc_header *toch; 2212 struct cd_toc_single leadout; 2213 u_int32_t size, toclen; 2214 int error, num_entries, cdindex; 2215 2216 softc = (struct cd_softc *)periph->softc; 2217 2218 cdprevent(periph, PR_PREVENT); 2219 softc->disk->d_sectorsize = 2048; 2220 softc->disk->d_mediasize = 0; 2221 2222 /* 2223 * Get the disc size and block size. If we can't get it, we don't 2224 * have media, most likely. 2225 */ 2226 if ((error = cdsize(periph, &size)) != 0) { 2227 softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC); 2228 cdprevent(periph, PR_ALLOW); 2229 return (error); 2230 } else { 2231 softc->flags |= CD_FLAG_SAW_MEDIA | CD_FLAG_VALID_MEDIA; 2232 softc->disk->d_sectorsize = softc->params.blksize; 2233 softc->disk->d_mediasize = 2234 (off_t)softc->params.blksize * softc->params.disksize; 2235 } 2236 2237 /* 2238 * Now we check the table of contents. This (currently) is only 2239 * used for the CDIOCPLAYTRACKS ioctl. It may be used later to do 2240 * things like present a separate entry in /dev for each track, 2241 * like that acd(4) driver does. 2242 */ 2243 bzero(&softc->toc, sizeof(softc->toc)); 2244 toch = &softc->toc.header; 2245 /* 2246 * We will get errors here for media that doesn't have a table of 2247 * contents. According to the MMC-3 spec: "When a Read TOC/PMA/ATIP 2248 * command is presented for a DDCD/CD-R/RW media, where the first TOC 2249 * has not been recorded (no complete session) and the Format codes 2250 * 0000b, 0001b, or 0010b are specified, this command shall be rejected 2251 * with an INVALID FIELD IN CDB. Devices that are not capable of 2252 * reading an incomplete session on DDC/CD-R/RW media shall report 2253 * CANNOT READ MEDIUM - INCOMPATIBLE FORMAT." 2254 * 2255 * So this isn't fatal if we can't read the table of contents, it 2256 * just means that the user won't be able to issue the play tracks 2257 * ioctl, and likely lots of other stuff won't work either. They 2258 * need to burn the CD before we can do a whole lot with it. So 2259 * we don't print anything here if we get an error back. 2260 */ 2261 error = cdreadtoc(periph, 0, 0, (u_int8_t *)toch, sizeof(*toch), 2262 SF_NO_PRINT); 2263 /* 2264 * Errors in reading the table of contents aren't fatal, we just 2265 * won't have a valid table of contents cached. 2266 */ 2267 if (error != 0) { 2268 error = 0; 2269 bzero(&softc->toc, sizeof(softc->toc)); 2270 goto bailout; 2271 } 2272 2273 if (softc->quirks & CD_Q_BCD_TRACKS) { 2274 toch->starting_track = bcd2bin(toch->starting_track); 2275 toch->ending_track = bcd2bin(toch->ending_track); 2276 } 2277 2278 /* Number of TOC entries, plus leadout */ 2279 num_entries = (toch->ending_track - toch->starting_track) + 2; 2280 2281 if (num_entries <= 0) 2282 goto bailout; 2283 2284 toclen = num_entries * sizeof(struct cd_toc_entry); 2285 2286 error = cdreadtoc(periph, CD_MSF_FORMAT, toch->starting_track, 2287 (u_int8_t *)&softc->toc, toclen + sizeof(*toch), 2288 SF_NO_PRINT); 2289 if (error != 0) { 2290 error = 0; 2291 bzero(&softc->toc, sizeof(softc->toc)); 2292 goto bailout; 2293 } 2294 2295 if (softc->quirks & CD_Q_BCD_TRACKS) { 2296 toch->starting_track = bcd2bin(toch->starting_track); 2297 toch->ending_track = bcd2bin(toch->ending_track); 2298 } 2299 /* 2300 * XXX KDM is this necessary? Probably only if the drive doesn't 2301 * return leadout information with the table of contents. 2302 */ 2303 cdindex = toch->starting_track + num_entries -1; 2304 if (cdindex == toch->ending_track + 1) { 2305 2306 error = cdreadtoc(periph, CD_MSF_FORMAT, LEADOUT, 2307 (u_int8_t *)&leadout, sizeof(leadout), 2308 SF_NO_PRINT); 2309 if (error != 0) { 2310 error = 0; 2311 goto bailout; 2312 } 2313 softc->toc.entries[cdindex - toch->starting_track] = 2314 leadout.entry; 2315 } 2316 if (softc->quirks & CD_Q_BCD_TRACKS) { 2317 for (cdindex = 0; cdindex < num_entries - 1; cdindex++) { 2318 softc->toc.entries[cdindex].track = 2319 bcd2bin(softc->toc.entries[cdindex].track); 2320 } 2321 } 2322 2323 softc->flags |= CD_FLAG_VALID_TOC; 2324 2325 /* If the first track is audio, correct sector size. */ 2326 if ((softc->toc.entries[0].control & 4) == 0) { 2327 softc->disk->d_sectorsize = softc->params.blksize = 2352; 2328 softc->disk->d_mediasize = 2329 (off_t)softc->params.blksize * softc->params.disksize; 2330 } 2331 2332 bailout: 2333 2334 /* 2335 * We unconditionally (re)set the blocksize each time the 2336 * CD device is opened. This is because the CD can change, 2337 * and therefore the blocksize might change. 2338 * XXX problems here if some slice or partition is still 2339 * open with the old size? 2340 */ 2341 if ((softc->disk->d_devstat->flags & DEVSTAT_BS_UNAVAILABLE) != 0) 2342 softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE; 2343 softc->disk->d_devstat->block_size = softc->params.blksize; 2344 2345 return (error); 2346 } 2347 2348 static int 2349 cdsize(struct cam_periph *periph, u_int32_t *size) 2350 { 2351 struct cd_softc *softc; 2352 union ccb *ccb; 2353 struct scsi_read_capacity_data *rcap_buf; 2354 int error; 2355 2356 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdsize\n")); 2357 2358 softc = (struct cd_softc *)periph->softc; 2359 2360 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2361 2362 /* XXX Should be M_WAITOK */ 2363 rcap_buf = malloc(sizeof(struct scsi_read_capacity_data), 2364 M_SCSICD, M_NOWAIT | M_ZERO); 2365 if (rcap_buf == NULL) 2366 return (ENOMEM); 2367 2368 scsi_read_capacity(&ccb->csio, 2369 /*retries*/ cd_retry_count, 2370 cddone, 2371 MSG_SIMPLE_Q_TAG, 2372 rcap_buf, 2373 SSD_FULL_SIZE, 2374 /* timeout */20000); 2375 2376 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2377 /*sense_flags*/SF_RETRY_UA|SF_NO_PRINT); 2378 2379 xpt_release_ccb(ccb); 2380 2381 softc->params.disksize = scsi_4btoul(rcap_buf->addr) + 1; 2382 softc->params.blksize = scsi_4btoul(rcap_buf->length); 2383 /* Make sure we got at least some block size. */ 2384 if (error == 0 && softc->params.blksize == 0) 2385 error = EIO; 2386 /* 2387 * SCSI-3 mandates that the reported blocksize shall be 2048. 2388 * Older drives sometimes report funny values, trim it down to 2389 * 2048, or other parts of the kernel will get confused. 2390 * 2391 * XXX we leave drives alone that might report 512 bytes, as 2392 * well as drives reporting more weird sizes like perhaps 4K. 2393 */ 2394 if (softc->params.blksize > 2048 && softc->params.blksize <= 2352) 2395 softc->params.blksize = 2048; 2396 2397 free(rcap_buf, M_SCSICD); 2398 *size = softc->params.disksize; 2399 2400 return (error); 2401 2402 } 2403 2404 static int 2405 cd6byteworkaround(union ccb *ccb) 2406 { 2407 u_int8_t *cdb; 2408 struct cam_periph *periph; 2409 struct cd_softc *softc; 2410 struct cd_mode_params *params; 2411 int frozen, found; 2412 2413 periph = xpt_path_periph(ccb->ccb_h.path); 2414 softc = (struct cd_softc *)periph->softc; 2415 2416 cdb = ccb->csio.cdb_io.cdb_bytes; 2417 2418 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) 2419 || ((cdb[0] != MODE_SENSE_6) 2420 && (cdb[0] != MODE_SELECT_6))) 2421 return (0); 2422 2423 /* 2424 * Because there is no convenient place to stash the overall 2425 * cd_mode_params structure pointer, we have to grab it like this. 2426 * This means that ALL MODE_SENSE and MODE_SELECT requests in the 2427 * cd(4) driver MUST go through cdgetmode() and cdsetmode()! 2428 * 2429 * XXX It would be nice if, at some point, we could increase the 2430 * number of available peripheral private pointers. Both pointers 2431 * are currently used in most every peripheral driver. 2432 */ 2433 found = 0; 2434 2435 STAILQ_FOREACH(params, &softc->mode_queue, links) { 2436 if (params->mode_buf == ccb->csio.data_ptr) { 2437 found = 1; 2438 break; 2439 } 2440 } 2441 2442 /* 2443 * This shouldn't happen. All mode sense and mode select 2444 * operations in the cd(4) driver MUST go through cdgetmode() and 2445 * cdsetmode()! 2446 */ 2447 if (found == 0) { 2448 xpt_print(periph->path, 2449 "mode buffer not found in mode queue!\n"); 2450 return (0); 2451 } 2452 2453 params->cdb_size = 10; 2454 softc->minimum_command_size = 10; 2455 xpt_print(ccb->ccb_h.path, 2456 "%s(6) failed, increasing minimum CDB size to 10 bytes\n", 2457 (cdb[0] == MODE_SENSE_6) ? "MODE_SENSE" : "MODE_SELECT"); 2458 2459 if (cdb[0] == MODE_SENSE_6) { 2460 struct scsi_mode_sense_10 ms10; 2461 struct scsi_mode_sense_6 *ms6; 2462 int len; 2463 2464 ms6 = (struct scsi_mode_sense_6 *)cdb; 2465 2466 bzero(&ms10, sizeof(ms10)); 2467 ms10.opcode = MODE_SENSE_10; 2468 ms10.byte2 = ms6->byte2; 2469 ms10.page = ms6->page; 2470 2471 /* 2472 * 10 byte mode header, block descriptor, 2473 * sizeof(union cd_pages) 2474 */ 2475 len = sizeof(struct cd_mode_data_10); 2476 ccb->csio.dxfer_len = len; 2477 2478 scsi_ulto2b(len, ms10.length); 2479 ms10.control = ms6->control; 2480 bcopy(&ms10, cdb, 10); 2481 ccb->csio.cdb_len = 10; 2482 } else { 2483 struct scsi_mode_select_10 ms10; 2484 struct scsi_mode_select_6 *ms6; 2485 struct scsi_mode_header_6 *header6; 2486 struct scsi_mode_header_10 *header10; 2487 struct scsi_mode_page_header *page_header; 2488 int blk_desc_len, page_num, page_size, len; 2489 2490 ms6 = (struct scsi_mode_select_6 *)cdb; 2491 2492 bzero(&ms10, sizeof(ms10)); 2493 ms10.opcode = MODE_SELECT_10; 2494 ms10.byte2 = ms6->byte2; 2495 2496 header6 = (struct scsi_mode_header_6 *)params->mode_buf; 2497 header10 = (struct scsi_mode_header_10 *)params->mode_buf; 2498 2499 page_header = find_mode_page_6(header6); 2500 page_num = page_header->page_code; 2501 2502 blk_desc_len = header6->blk_desc_len; 2503 2504 page_size = cdgetpagesize(page_num); 2505 2506 if (page_size != (page_header->page_length + 2507 sizeof(*page_header))) 2508 page_size = page_header->page_length + 2509 sizeof(*page_header); 2510 2511 len = sizeof(*header10) + blk_desc_len + page_size; 2512 2513 len = min(params->alloc_len, len); 2514 2515 /* 2516 * Since the 6 byte parameter header is shorter than the 10 2517 * byte parameter header, we need to copy the actual mode 2518 * page data, and the block descriptor, if any, so things wind 2519 * up in the right place. The regions will overlap, but 2520 * bcopy() does the right thing. 2521 */ 2522 bcopy(params->mode_buf + sizeof(*header6), 2523 params->mode_buf + sizeof(*header10), 2524 len - sizeof(*header10)); 2525 2526 /* Make sure these fields are set correctly. */ 2527 scsi_ulto2b(0, header10->data_length); 2528 header10->medium_type = 0; 2529 scsi_ulto2b(blk_desc_len, header10->blk_desc_len); 2530 2531 ccb->csio.dxfer_len = len; 2532 2533 scsi_ulto2b(len, ms10.length); 2534 ms10.control = ms6->control; 2535 bcopy(&ms10, cdb, 10); 2536 ccb->csio.cdb_len = 10; 2537 } 2538 2539 frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0; 2540 ccb->ccb_h.status = CAM_REQUEUE_REQ; 2541 xpt_action(ccb); 2542 if (frozen) { 2543 cam_release_devq(ccb->ccb_h.path, 2544 /*relsim_flags*/0, 2545 /*openings*/0, 2546 /*timeout*/0, 2547 /*getcount_only*/0); 2548 } 2549 2550 return (ERESTART); 2551 } 2552 2553 static int 2554 cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) 2555 { 2556 struct cd_softc *softc; 2557 struct cam_periph *periph; 2558 int error, error_code, sense_key, asc, ascq; 2559 2560 periph = xpt_path_periph(ccb->ccb_h.path); 2561 softc = (struct cd_softc *)periph->softc; 2562 2563 error = 0; 2564 2565 /* 2566 * We use a status of CAM_REQ_INVALID as shorthand -- if a 6 byte 2567 * CDB comes back with this particular error, try transforming it 2568 * into the 10 byte version. 2569 */ 2570 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) { 2571 error = cd6byteworkaround(ccb); 2572 } else if (scsi_extract_sense_ccb(ccb, 2573 &error_code, &sense_key, &asc, &ascq)) { 2574 if (sense_key == SSD_KEY_ILLEGAL_REQUEST) 2575 error = cd6byteworkaround(ccb); 2576 else if (sense_key == SSD_KEY_UNIT_ATTENTION && 2577 asc == 0x28 && ascq == 0x00) 2578 disk_media_changed(softc->disk, M_NOWAIT); 2579 else if (sense_key == SSD_KEY_NOT_READY && 2580 asc == 0x3a && (softc->flags & CD_FLAG_SAW_MEDIA)) { 2581 softc->flags &= ~CD_FLAG_SAW_MEDIA; 2582 disk_media_gone(softc->disk, M_NOWAIT); 2583 } 2584 } 2585 2586 if (error == ERESTART) 2587 return (error); 2588 2589 /* 2590 * XXX 2591 * Until we have a better way of doing pack validation, 2592 * don't treat UAs as errors. 2593 */ 2594 sense_flags |= SF_RETRY_UA; 2595 2596 if (softc->quirks & CD_Q_RETRY_BUSY) 2597 sense_flags |= SF_RETRY_BUSY; 2598 return (cam_periph_error(ccb, cam_flags, sense_flags, 2599 &softc->saved_ccb)); 2600 } 2601 2602 static void 2603 cdmediapoll(void *arg) 2604 { 2605 struct cam_periph *periph = arg; 2606 struct cd_softc *softc = periph->softc; 2607 2608 if (softc->state == CD_STATE_NORMAL && !softc->tur && 2609 softc->outstanding_cmds == 0) { 2610 if (cam_periph_acquire(periph) == CAM_REQ_CMP) { 2611 softc->tur = 1; 2612 xpt_schedule(periph, CAM_PRIORITY_NORMAL); 2613 } 2614 } 2615 /* Queue us up again */ 2616 if (cd_poll_period != 0) 2617 callout_schedule(&softc->mediapoll_c, cd_poll_period * hz); 2618 } 2619 2620 /* 2621 * Read table of contents 2622 */ 2623 static int 2624 cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, 2625 u_int8_t *data, u_int32_t len, u_int32_t sense_flags) 2626 { 2627 struct scsi_read_toc *scsi_cmd; 2628 u_int32_t ntoc; 2629 struct ccb_scsiio *csio; 2630 union ccb *ccb; 2631 int error; 2632 2633 ntoc = len; 2634 error = 0; 2635 2636 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2637 2638 csio = &ccb->csio; 2639 2640 cam_fill_csio(csio, 2641 /* retries */ cd_retry_count, 2642 /* cbfcnp */ cddone, 2643 /* flags */ CAM_DIR_IN, 2644 /* tag_action */ MSG_SIMPLE_Q_TAG, 2645 /* data_ptr */ data, 2646 /* dxfer_len */ len, 2647 /* sense_len */ SSD_FULL_SIZE, 2648 sizeof(struct scsi_read_toc), 2649 /* timeout */ 50000); 2650 2651 scsi_cmd = (struct scsi_read_toc *)&csio->cdb_io.cdb_bytes; 2652 bzero (scsi_cmd, sizeof(*scsi_cmd)); 2653 2654 if (mode == CD_MSF_FORMAT) 2655 scsi_cmd->byte2 |= CD_MSF; 2656 scsi_cmd->from_track = start; 2657 /* scsi_ulto2b(ntoc, (u_int8_t *)scsi_cmd->data_len); */ 2658 scsi_cmd->data_len[0] = (ntoc) >> 8; 2659 scsi_cmd->data_len[1] = (ntoc) & 0xff; 2660 2661 scsi_cmd->op_code = READ_TOC; 2662 2663 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2664 /*sense_flags*/SF_RETRY_UA | sense_flags); 2665 2666 xpt_release_ccb(ccb); 2667 2668 return(error); 2669 } 2670 2671 static int 2672 cdreadsubchannel(struct cam_periph *periph, u_int32_t mode, 2673 u_int32_t format, int track, 2674 struct cd_sub_channel_info *data, u_int32_t len) 2675 { 2676 struct scsi_read_subchannel *scsi_cmd; 2677 struct ccb_scsiio *csio; 2678 union ccb *ccb; 2679 int error; 2680 2681 error = 0; 2682 2683 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2684 2685 csio = &ccb->csio; 2686 2687 cam_fill_csio(csio, 2688 /* retries */ cd_retry_count, 2689 /* cbfcnp */ cddone, 2690 /* flags */ CAM_DIR_IN, 2691 /* tag_action */ MSG_SIMPLE_Q_TAG, 2692 /* data_ptr */ (u_int8_t *)data, 2693 /* dxfer_len */ len, 2694 /* sense_len */ SSD_FULL_SIZE, 2695 sizeof(struct scsi_read_subchannel), 2696 /* timeout */ 50000); 2697 2698 scsi_cmd = (struct scsi_read_subchannel *)&csio->cdb_io.cdb_bytes; 2699 bzero (scsi_cmd, sizeof(*scsi_cmd)); 2700 2701 scsi_cmd->op_code = READ_SUBCHANNEL; 2702 if (mode == CD_MSF_FORMAT) 2703 scsi_cmd->byte1 |= CD_MSF; 2704 scsi_cmd->byte2 = SRS_SUBQ; 2705 scsi_cmd->subchan_format = format; 2706 scsi_cmd->track = track; 2707 scsi_ulto2b(len, (u_int8_t *)scsi_cmd->data_len); 2708 scsi_cmd->control = 0; 2709 2710 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2711 /*sense_flags*/SF_RETRY_UA); 2712 2713 xpt_release_ccb(ccb); 2714 2715 return(error); 2716 } 2717 2718 2719 /* 2720 * All MODE_SENSE requests in the cd(4) driver MUST go through this 2721 * routine. See comments in cd6byteworkaround() for details. 2722 */ 2723 static int 2724 cdgetmode(struct cam_periph *periph, struct cd_mode_params *data, 2725 u_int32_t page) 2726 { 2727 struct ccb_scsiio *csio; 2728 struct cd_softc *softc; 2729 union ccb *ccb; 2730 int param_len; 2731 int error; 2732 2733 softc = (struct cd_softc *)periph->softc; 2734 2735 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2736 2737 csio = &ccb->csio; 2738 2739 data->cdb_size = softc->minimum_command_size; 2740 if (data->cdb_size < 10) 2741 param_len = sizeof(struct cd_mode_data); 2742 else 2743 param_len = sizeof(struct cd_mode_data_10); 2744 2745 /* Don't say we've got more room than we actually allocated */ 2746 param_len = min(param_len, data->alloc_len); 2747 2748 scsi_mode_sense_len(csio, 2749 /* retries */ cd_retry_count, 2750 /* cbfcnp */ cddone, 2751 /* tag_action */ MSG_SIMPLE_Q_TAG, 2752 /* dbd */ 0, 2753 /* page_code */ SMS_PAGE_CTRL_CURRENT, 2754 /* page */ page, 2755 /* param_buf */ data->mode_buf, 2756 /* param_len */ param_len, 2757 /* minimum_cmd_size */ softc->minimum_command_size, 2758 /* sense_len */ SSD_FULL_SIZE, 2759 /* timeout */ 50000); 2760 2761 /* 2762 * It would be nice not to have to do this, but there's no 2763 * available pointer in the CCB that would allow us to stuff the 2764 * mode params structure in there and retrieve it in 2765 * cd6byteworkaround(), so we can set the cdb size. The cdb size 2766 * lets the caller know what CDB size we ended up using, so they 2767 * can find the actual mode page offset. 2768 */ 2769 STAILQ_INSERT_TAIL(&softc->mode_queue, data, links); 2770 2771 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2772 /*sense_flags*/SF_RETRY_UA); 2773 2774 xpt_release_ccb(ccb); 2775 2776 STAILQ_REMOVE(&softc->mode_queue, data, cd_mode_params, links); 2777 2778 /* 2779 * This is a bit of belt-and-suspenders checking, but if we run 2780 * into a situation where the target sends back multiple block 2781 * descriptors, we might not have enough space in the buffer to 2782 * see the whole mode page. Better to return an error than 2783 * potentially access memory beyond our malloced region. 2784 */ 2785 if (error == 0) { 2786 u_int32_t data_len; 2787 2788 if (data->cdb_size == 10) { 2789 struct scsi_mode_header_10 *hdr10; 2790 2791 hdr10 = (struct scsi_mode_header_10 *)data->mode_buf; 2792 data_len = scsi_2btoul(hdr10->data_length); 2793 data_len += sizeof(hdr10->data_length); 2794 } else { 2795 struct scsi_mode_header_6 *hdr6; 2796 2797 hdr6 = (struct scsi_mode_header_6 *)data->mode_buf; 2798 data_len = hdr6->data_length; 2799 data_len += sizeof(hdr6->data_length); 2800 } 2801 2802 /* 2803 * Complain if there is more mode data available than we 2804 * allocated space for. This could potentially happen if 2805 * we miscalculated the page length for some reason, if the 2806 * drive returns multiple block descriptors, or if it sets 2807 * the data length incorrectly. 2808 */ 2809 if (data_len > data->alloc_len) { 2810 xpt_print(periph->path, "allocated modepage %d length " 2811 "%d < returned length %d\n", page, data->alloc_len, 2812 data_len); 2813 error = ENOSPC; 2814 } 2815 } 2816 return (error); 2817 } 2818 2819 /* 2820 * All MODE_SELECT requests in the cd(4) driver MUST go through this 2821 * routine. See comments in cd6byteworkaround() for details. 2822 */ 2823 static int 2824 cdsetmode(struct cam_periph *periph, struct cd_mode_params *data) 2825 { 2826 struct ccb_scsiio *csio; 2827 struct cd_softc *softc; 2828 union ccb *ccb; 2829 int cdb_size, param_len; 2830 int error; 2831 2832 softc = (struct cd_softc *)periph->softc; 2833 2834 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2835 2836 csio = &ccb->csio; 2837 2838 error = 0; 2839 2840 /* 2841 * If the data is formatted for the 10 byte version of the mode 2842 * select parameter list, we need to use the 10 byte CDB. 2843 * Otherwise, we use whatever the stored minimum command size. 2844 */ 2845 if (data->cdb_size == 10) 2846 cdb_size = data->cdb_size; 2847 else 2848 cdb_size = softc->minimum_command_size; 2849 2850 if (cdb_size >= 10) { 2851 struct scsi_mode_header_10 *mode_header; 2852 u_int32_t data_len; 2853 2854 mode_header = (struct scsi_mode_header_10 *)data->mode_buf; 2855 2856 data_len = scsi_2btoul(mode_header->data_length); 2857 2858 scsi_ulto2b(0, mode_header->data_length); 2859 /* 2860 * SONY drives do not allow a mode select with a medium_type 2861 * value that has just been returned by a mode sense; use a 2862 * medium_type of 0 (Default) instead. 2863 */ 2864 mode_header->medium_type = 0; 2865 2866 /* 2867 * Pass back whatever the drive passed to us, plus the size 2868 * of the data length field. 2869 */ 2870 param_len = data_len + sizeof(mode_header->data_length); 2871 2872 } else { 2873 struct scsi_mode_header_6 *mode_header; 2874 2875 mode_header = (struct scsi_mode_header_6 *)data->mode_buf; 2876 2877 param_len = mode_header->data_length + 1; 2878 2879 mode_header->data_length = 0; 2880 /* 2881 * SONY drives do not allow a mode select with a medium_type 2882 * value that has just been returned by a mode sense; use a 2883 * medium_type of 0 (Default) instead. 2884 */ 2885 mode_header->medium_type = 0; 2886 } 2887 2888 /* Don't say we've got more room than we actually allocated */ 2889 param_len = min(param_len, data->alloc_len); 2890 2891 scsi_mode_select_len(csio, 2892 /* retries */ cd_retry_count, 2893 /* cbfcnp */ cddone, 2894 /* tag_action */ MSG_SIMPLE_Q_TAG, 2895 /* scsi_page_fmt */ 1, 2896 /* save_pages */ 0, 2897 /* param_buf */ data->mode_buf, 2898 /* param_len */ param_len, 2899 /* minimum_cmd_size */ cdb_size, 2900 /* sense_len */ SSD_FULL_SIZE, 2901 /* timeout */ 50000); 2902 2903 /* See comments in cdgetmode() and cd6byteworkaround(). */ 2904 STAILQ_INSERT_TAIL(&softc->mode_queue, data, links); 2905 2906 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2907 /*sense_flags*/SF_RETRY_UA); 2908 2909 xpt_release_ccb(ccb); 2910 2911 STAILQ_REMOVE(&softc->mode_queue, data, cd_mode_params, links); 2912 2913 return (error); 2914 } 2915 2916 2917 static int 2918 cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len) 2919 { 2920 struct ccb_scsiio *csio; 2921 union ccb *ccb; 2922 int error; 2923 u_int8_t cdb_len; 2924 2925 error = 0; 2926 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2927 csio = &ccb->csio; 2928 /* 2929 * Use the smallest possible command to perform the operation. 2930 */ 2931 if ((len & 0xffff0000) == 0) { 2932 /* 2933 * We can fit in a 10 byte cdb. 2934 */ 2935 struct scsi_play_10 *scsi_cmd; 2936 2937 scsi_cmd = (struct scsi_play_10 *)&csio->cdb_io.cdb_bytes; 2938 bzero (scsi_cmd, sizeof(*scsi_cmd)); 2939 scsi_cmd->op_code = PLAY_10; 2940 scsi_ulto4b(blk, (u_int8_t *)scsi_cmd->blk_addr); 2941 scsi_ulto2b(len, (u_int8_t *)scsi_cmd->xfer_len); 2942 cdb_len = sizeof(*scsi_cmd); 2943 } else { 2944 struct scsi_play_12 *scsi_cmd; 2945 2946 scsi_cmd = (struct scsi_play_12 *)&csio->cdb_io.cdb_bytes; 2947 bzero (scsi_cmd, sizeof(*scsi_cmd)); 2948 scsi_cmd->op_code = PLAY_12; 2949 scsi_ulto4b(blk, (u_int8_t *)scsi_cmd->blk_addr); 2950 scsi_ulto4b(len, (u_int8_t *)scsi_cmd->xfer_len); 2951 cdb_len = sizeof(*scsi_cmd); 2952 } 2953 cam_fill_csio(csio, 2954 /*retries*/ cd_retry_count, 2955 cddone, 2956 /*flags*/CAM_DIR_NONE, 2957 MSG_SIMPLE_Q_TAG, 2958 /*dataptr*/NULL, 2959 /*datalen*/0, 2960 /*sense_len*/SSD_FULL_SIZE, 2961 cdb_len, 2962 /*timeout*/50 * 1000); 2963 2964 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 2965 /*sense_flags*/SF_RETRY_UA); 2966 2967 xpt_release_ccb(ccb); 2968 2969 return(error); 2970 } 2971 2972 static int 2973 cdplaymsf(struct cam_periph *periph, u_int32_t startm, u_int32_t starts, 2974 u_int32_t startf, u_int32_t endm, u_int32_t ends, u_int32_t endf) 2975 { 2976 struct scsi_play_msf *scsi_cmd; 2977 struct ccb_scsiio *csio; 2978 union ccb *ccb; 2979 int error; 2980 2981 error = 0; 2982 2983 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 2984 2985 csio = &ccb->csio; 2986 2987 cam_fill_csio(csio, 2988 /* retries */ cd_retry_count, 2989 /* cbfcnp */ cddone, 2990 /* flags */ CAM_DIR_NONE, 2991 /* tag_action */ MSG_SIMPLE_Q_TAG, 2992 /* data_ptr */ NULL, 2993 /* dxfer_len */ 0, 2994 /* sense_len */ SSD_FULL_SIZE, 2995 sizeof(struct scsi_play_msf), 2996 /* timeout */ 50000); 2997 2998 scsi_cmd = (struct scsi_play_msf *)&csio->cdb_io.cdb_bytes; 2999 bzero (scsi_cmd, sizeof(*scsi_cmd)); 3000 3001 scsi_cmd->op_code = PLAY_MSF; 3002 scsi_cmd->start_m = startm; 3003 scsi_cmd->start_s = starts; 3004 scsi_cmd->start_f = startf; 3005 scsi_cmd->end_m = endm; 3006 scsi_cmd->end_s = ends; 3007 scsi_cmd->end_f = endf; 3008 3009 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3010 /*sense_flags*/SF_RETRY_UA); 3011 3012 xpt_release_ccb(ccb); 3013 3014 return(error); 3015 } 3016 3017 3018 static int 3019 cdplaytracks(struct cam_periph *periph, u_int32_t strack, u_int32_t sindex, 3020 u_int32_t etrack, u_int32_t eindex) 3021 { 3022 struct scsi_play_track *scsi_cmd; 3023 struct ccb_scsiio *csio; 3024 union ccb *ccb; 3025 int error; 3026 3027 error = 0; 3028 3029 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3030 3031 csio = &ccb->csio; 3032 3033 cam_fill_csio(csio, 3034 /* retries */ cd_retry_count, 3035 /* cbfcnp */ cddone, 3036 /* flags */ CAM_DIR_NONE, 3037 /* tag_action */ MSG_SIMPLE_Q_TAG, 3038 /* data_ptr */ NULL, 3039 /* dxfer_len */ 0, 3040 /* sense_len */ SSD_FULL_SIZE, 3041 sizeof(struct scsi_play_track), 3042 /* timeout */ 50000); 3043 3044 scsi_cmd = (struct scsi_play_track *)&csio->cdb_io.cdb_bytes; 3045 bzero (scsi_cmd, sizeof(*scsi_cmd)); 3046 3047 scsi_cmd->op_code = PLAY_TRACK; 3048 scsi_cmd->start_track = strack; 3049 scsi_cmd->start_index = sindex; 3050 scsi_cmd->end_track = etrack; 3051 scsi_cmd->end_index = eindex; 3052 3053 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3054 /*sense_flags*/SF_RETRY_UA); 3055 3056 xpt_release_ccb(ccb); 3057 3058 return(error); 3059 } 3060 3061 static int 3062 cdpause(struct cam_periph *periph, u_int32_t go) 3063 { 3064 struct scsi_pause *scsi_cmd; 3065 struct ccb_scsiio *csio; 3066 union ccb *ccb; 3067 int error; 3068 3069 error = 0; 3070 3071 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3072 3073 csio = &ccb->csio; 3074 3075 cam_fill_csio(csio, 3076 /* retries */ cd_retry_count, 3077 /* cbfcnp */ cddone, 3078 /* flags */ CAM_DIR_NONE, 3079 /* tag_action */ MSG_SIMPLE_Q_TAG, 3080 /* data_ptr */ NULL, 3081 /* dxfer_len */ 0, 3082 /* sense_len */ SSD_FULL_SIZE, 3083 sizeof(struct scsi_pause), 3084 /* timeout */ 50000); 3085 3086 scsi_cmd = (struct scsi_pause *)&csio->cdb_io.cdb_bytes; 3087 bzero (scsi_cmd, sizeof(*scsi_cmd)); 3088 3089 scsi_cmd->op_code = PAUSE; 3090 scsi_cmd->resume = go; 3091 3092 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3093 /*sense_flags*/SF_RETRY_UA); 3094 3095 xpt_release_ccb(ccb); 3096 3097 return(error); 3098 } 3099 3100 static int 3101 cdstartunit(struct cam_periph *periph, int load) 3102 { 3103 union ccb *ccb; 3104 int error; 3105 3106 error = 0; 3107 3108 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3109 3110 scsi_start_stop(&ccb->csio, 3111 /* retries */ cd_retry_count, 3112 /* cbfcnp */ cddone, 3113 /* tag_action */ MSG_SIMPLE_Q_TAG, 3114 /* start */ TRUE, 3115 /* load_eject */ load, 3116 /* immediate */ FALSE, 3117 /* sense_len */ SSD_FULL_SIZE, 3118 /* timeout */ 50000); 3119 3120 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3121 /*sense_flags*/SF_RETRY_UA); 3122 3123 xpt_release_ccb(ccb); 3124 3125 return(error); 3126 } 3127 3128 static int 3129 cdstopunit(struct cam_periph *periph, u_int32_t eject) 3130 { 3131 union ccb *ccb; 3132 int error; 3133 3134 error = 0; 3135 3136 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3137 3138 scsi_start_stop(&ccb->csio, 3139 /* retries */ cd_retry_count, 3140 /* cbfcnp */ cddone, 3141 /* tag_action */ MSG_SIMPLE_Q_TAG, 3142 /* start */ FALSE, 3143 /* load_eject */ eject, 3144 /* immediate */ FALSE, 3145 /* sense_len */ SSD_FULL_SIZE, 3146 /* timeout */ 50000); 3147 3148 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3149 /*sense_flags*/SF_RETRY_UA); 3150 3151 xpt_release_ccb(ccb); 3152 3153 return(error); 3154 } 3155 3156 static int 3157 cdsetspeed(struct cam_periph *periph, u_int32_t rdspeed, u_int32_t wrspeed) 3158 { 3159 struct scsi_set_speed *scsi_cmd; 3160 struct ccb_scsiio *csio; 3161 union ccb *ccb; 3162 int error; 3163 3164 error = 0; 3165 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3166 csio = &ccb->csio; 3167 3168 /* Preserve old behavior: units in multiples of CDROM speed */ 3169 if (rdspeed < 177) 3170 rdspeed *= 177; 3171 if (wrspeed < 177) 3172 wrspeed *= 177; 3173 3174 cam_fill_csio(csio, 3175 /* retries */ cd_retry_count, 3176 /* cbfcnp */ cddone, 3177 /* flags */ CAM_DIR_NONE, 3178 /* tag_action */ MSG_SIMPLE_Q_TAG, 3179 /* data_ptr */ NULL, 3180 /* dxfer_len */ 0, 3181 /* sense_len */ SSD_FULL_SIZE, 3182 sizeof(struct scsi_set_speed), 3183 /* timeout */ 50000); 3184 3185 scsi_cmd = (struct scsi_set_speed *)&csio->cdb_io.cdb_bytes; 3186 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3187 3188 scsi_cmd->opcode = SET_CD_SPEED; 3189 scsi_ulto2b(rdspeed, scsi_cmd->readspeed); 3190 scsi_ulto2b(wrspeed, scsi_cmd->writespeed); 3191 3192 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3193 /*sense_flags*/SF_RETRY_UA); 3194 3195 xpt_release_ccb(ccb); 3196 3197 return(error); 3198 } 3199 3200 static int 3201 cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo) 3202 { 3203 union ccb *ccb; 3204 u_int8_t *databuf; 3205 u_int32_t lba; 3206 int error; 3207 int length; 3208 3209 error = 0; 3210 databuf = NULL; 3211 lba = 0; 3212 3213 switch (authinfo->format) { 3214 case DVD_REPORT_AGID: 3215 length = sizeof(struct scsi_report_key_data_agid); 3216 break; 3217 case DVD_REPORT_CHALLENGE: 3218 length = sizeof(struct scsi_report_key_data_challenge); 3219 break; 3220 case DVD_REPORT_KEY1: 3221 length = sizeof(struct scsi_report_key_data_key1_key2); 3222 break; 3223 case DVD_REPORT_TITLE_KEY: 3224 length = sizeof(struct scsi_report_key_data_title); 3225 /* The lba field is only set for the title key */ 3226 lba = authinfo->lba; 3227 break; 3228 case DVD_REPORT_ASF: 3229 length = sizeof(struct scsi_report_key_data_asf); 3230 break; 3231 case DVD_REPORT_RPC: 3232 length = sizeof(struct scsi_report_key_data_rpc); 3233 break; 3234 case DVD_INVALIDATE_AGID: 3235 length = 0; 3236 break; 3237 default: 3238 return (EINVAL); 3239 } 3240 3241 if (length != 0) { 3242 databuf = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); 3243 } else 3244 databuf = NULL; 3245 3246 cam_periph_lock(periph); 3247 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3248 3249 scsi_report_key(&ccb->csio, 3250 /* retries */ cd_retry_count, 3251 /* cbfcnp */ cddone, 3252 /* tag_action */ MSG_SIMPLE_Q_TAG, 3253 /* lba */ lba, 3254 /* agid */ authinfo->agid, 3255 /* key_format */ authinfo->format, 3256 /* data_ptr */ databuf, 3257 /* dxfer_len */ length, 3258 /* sense_len */ SSD_FULL_SIZE, 3259 /* timeout */ 50000); 3260 3261 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3262 /*sense_flags*/SF_RETRY_UA); 3263 3264 if (error != 0) 3265 goto bailout; 3266 3267 if (ccb->csio.resid != 0) { 3268 xpt_print(periph->path, "warning, residual for report key " 3269 "command is %d\n", ccb->csio.resid); 3270 } 3271 3272 switch(authinfo->format) { 3273 case DVD_REPORT_AGID: { 3274 struct scsi_report_key_data_agid *agid_data; 3275 3276 agid_data = (struct scsi_report_key_data_agid *)databuf; 3277 3278 authinfo->agid = (agid_data->agid & RKD_AGID_MASK) >> 3279 RKD_AGID_SHIFT; 3280 break; 3281 } 3282 case DVD_REPORT_CHALLENGE: { 3283 struct scsi_report_key_data_challenge *chal_data; 3284 3285 chal_data = (struct scsi_report_key_data_challenge *)databuf; 3286 3287 bcopy(chal_data->challenge_key, authinfo->keychal, 3288 min(sizeof(chal_data->challenge_key), 3289 sizeof(authinfo->keychal))); 3290 break; 3291 } 3292 case DVD_REPORT_KEY1: { 3293 struct scsi_report_key_data_key1_key2 *key1_data; 3294 3295 key1_data = (struct scsi_report_key_data_key1_key2 *)databuf; 3296 3297 bcopy(key1_data->key1, authinfo->keychal, 3298 min(sizeof(key1_data->key1), sizeof(authinfo->keychal))); 3299 break; 3300 } 3301 case DVD_REPORT_TITLE_KEY: { 3302 struct scsi_report_key_data_title *title_data; 3303 3304 title_data = (struct scsi_report_key_data_title *)databuf; 3305 3306 authinfo->cpm = (title_data->byte0 & RKD_TITLE_CPM) >> 3307 RKD_TITLE_CPM_SHIFT; 3308 authinfo->cp_sec = (title_data->byte0 & RKD_TITLE_CP_SEC) >> 3309 RKD_TITLE_CP_SEC_SHIFT; 3310 authinfo->cgms = (title_data->byte0 & RKD_TITLE_CMGS_MASK) >> 3311 RKD_TITLE_CMGS_SHIFT; 3312 bcopy(title_data->title_key, authinfo->keychal, 3313 min(sizeof(title_data->title_key), 3314 sizeof(authinfo->keychal))); 3315 break; 3316 } 3317 case DVD_REPORT_ASF: { 3318 struct scsi_report_key_data_asf *asf_data; 3319 3320 asf_data = (struct scsi_report_key_data_asf *)databuf; 3321 3322 authinfo->asf = asf_data->success & RKD_ASF_SUCCESS; 3323 break; 3324 } 3325 case DVD_REPORT_RPC: { 3326 struct scsi_report_key_data_rpc *rpc_data; 3327 3328 rpc_data = (struct scsi_report_key_data_rpc *)databuf; 3329 3330 authinfo->reg_type = (rpc_data->byte4 & RKD_RPC_TYPE_MASK) >> 3331 RKD_RPC_TYPE_SHIFT; 3332 authinfo->vend_rsts = 3333 (rpc_data->byte4 & RKD_RPC_VENDOR_RESET_MASK) >> 3334 RKD_RPC_VENDOR_RESET_SHIFT; 3335 authinfo->user_rsts = rpc_data->byte4 & RKD_RPC_USER_RESET_MASK; 3336 authinfo->region = rpc_data->region_mask; 3337 authinfo->rpc_scheme = rpc_data->rpc_scheme1; 3338 break; 3339 } 3340 case DVD_INVALIDATE_AGID: 3341 break; 3342 default: 3343 /* This should be impossible, since we checked above */ 3344 error = EINVAL; 3345 goto bailout; 3346 break; /* NOTREACHED */ 3347 } 3348 3349 bailout: 3350 xpt_release_ccb(ccb); 3351 cam_periph_unlock(periph); 3352 3353 if (databuf != NULL) 3354 free(databuf, M_DEVBUF); 3355 3356 return(error); 3357 } 3358 3359 static int 3360 cdsendkey(struct cam_periph *periph, struct dvd_authinfo *authinfo) 3361 { 3362 union ccb *ccb; 3363 u_int8_t *databuf; 3364 int length; 3365 int error; 3366 3367 error = 0; 3368 databuf = NULL; 3369 3370 switch(authinfo->format) { 3371 case DVD_SEND_CHALLENGE: { 3372 struct scsi_report_key_data_challenge *challenge_data; 3373 3374 length = sizeof(*challenge_data); 3375 3376 challenge_data = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); 3377 3378 databuf = (u_int8_t *)challenge_data; 3379 3380 scsi_ulto2b(length - sizeof(challenge_data->data_len), 3381 challenge_data->data_len); 3382 3383 bcopy(authinfo->keychal, challenge_data->challenge_key, 3384 min(sizeof(authinfo->keychal), 3385 sizeof(challenge_data->challenge_key))); 3386 break; 3387 } 3388 case DVD_SEND_KEY2: { 3389 struct scsi_report_key_data_key1_key2 *key2_data; 3390 3391 length = sizeof(*key2_data); 3392 3393 key2_data = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); 3394 3395 databuf = (u_int8_t *)key2_data; 3396 3397 scsi_ulto2b(length - sizeof(key2_data->data_len), 3398 key2_data->data_len); 3399 3400 bcopy(authinfo->keychal, key2_data->key1, 3401 min(sizeof(authinfo->keychal), sizeof(key2_data->key1))); 3402 3403 break; 3404 } 3405 case DVD_SEND_RPC: { 3406 struct scsi_send_key_data_rpc *rpc_data; 3407 3408 length = sizeof(*rpc_data); 3409 3410 rpc_data = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); 3411 3412 databuf = (u_int8_t *)rpc_data; 3413 3414 scsi_ulto2b(length - sizeof(rpc_data->data_len), 3415 rpc_data->data_len); 3416 3417 rpc_data->region_code = authinfo->region; 3418 break; 3419 } 3420 default: 3421 return (EINVAL); 3422 } 3423 3424 cam_periph_lock(periph); 3425 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3426 3427 scsi_send_key(&ccb->csio, 3428 /* retries */ cd_retry_count, 3429 /* cbfcnp */ cddone, 3430 /* tag_action */ MSG_SIMPLE_Q_TAG, 3431 /* agid */ authinfo->agid, 3432 /* key_format */ authinfo->format, 3433 /* data_ptr */ databuf, 3434 /* dxfer_len */ length, 3435 /* sense_len */ SSD_FULL_SIZE, 3436 /* timeout */ 50000); 3437 3438 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3439 /*sense_flags*/SF_RETRY_UA); 3440 3441 xpt_release_ccb(ccb); 3442 cam_periph_unlock(periph); 3443 3444 if (databuf != NULL) 3445 free(databuf, M_DEVBUF); 3446 3447 return(error); 3448 } 3449 3450 static int 3451 cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct) 3452 { 3453 union ccb *ccb; 3454 u_int8_t *databuf; 3455 u_int32_t address; 3456 int error; 3457 int length; 3458 3459 error = 0; 3460 databuf = NULL; 3461 /* The address is reserved for many of the formats */ 3462 address = 0; 3463 3464 switch(dvdstruct->format) { 3465 case DVD_STRUCT_PHYSICAL: 3466 length = sizeof(struct scsi_read_dvd_struct_data_physical); 3467 break; 3468 case DVD_STRUCT_COPYRIGHT: 3469 length = sizeof(struct scsi_read_dvd_struct_data_copyright); 3470 break; 3471 case DVD_STRUCT_DISCKEY: 3472 length = sizeof(struct scsi_read_dvd_struct_data_disc_key); 3473 break; 3474 case DVD_STRUCT_BCA: 3475 length = sizeof(struct scsi_read_dvd_struct_data_bca); 3476 break; 3477 case DVD_STRUCT_MANUFACT: 3478 length = sizeof(struct scsi_read_dvd_struct_data_manufacturer); 3479 break; 3480 case DVD_STRUCT_CMI: 3481 return (ENODEV); 3482 case DVD_STRUCT_PROTDISCID: 3483 length = sizeof(struct scsi_read_dvd_struct_data_prot_discid); 3484 break; 3485 case DVD_STRUCT_DISCKEYBLOCK: 3486 length = sizeof(struct scsi_read_dvd_struct_data_disc_key_blk); 3487 break; 3488 case DVD_STRUCT_DDS: 3489 length = sizeof(struct scsi_read_dvd_struct_data_dds); 3490 break; 3491 case DVD_STRUCT_MEDIUM_STAT: 3492 length = sizeof(struct scsi_read_dvd_struct_data_medium_status); 3493 break; 3494 case DVD_STRUCT_SPARE_AREA: 3495 length = sizeof(struct scsi_read_dvd_struct_data_spare_area); 3496 break; 3497 case DVD_STRUCT_RMD_LAST: 3498 return (ENODEV); 3499 case DVD_STRUCT_RMD_RMA: 3500 return (ENODEV); 3501 case DVD_STRUCT_PRERECORDED: 3502 length = sizeof(struct scsi_read_dvd_struct_data_leadin); 3503 break; 3504 case DVD_STRUCT_UNIQUEID: 3505 length = sizeof(struct scsi_read_dvd_struct_data_disc_id); 3506 break; 3507 case DVD_STRUCT_DCB: 3508 return (ENODEV); 3509 case DVD_STRUCT_LIST: 3510 /* 3511 * This is the maximum allocation length for the READ DVD 3512 * STRUCTURE command. There's nothing in the MMC3 spec 3513 * that indicates a limit in the amount of data that can 3514 * be returned from this call, other than the limits 3515 * imposed by the 2-byte length variables. 3516 */ 3517 length = 65535; 3518 break; 3519 default: 3520 return (EINVAL); 3521 } 3522 3523 if (length != 0) { 3524 databuf = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); 3525 } else 3526 databuf = NULL; 3527 3528 cam_periph_lock(periph); 3529 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 3530 3531 scsi_read_dvd_structure(&ccb->csio, 3532 /* retries */ cd_retry_count, 3533 /* cbfcnp */ cddone, 3534 /* tag_action */ MSG_SIMPLE_Q_TAG, 3535 /* lba */ address, 3536 /* layer_number */ dvdstruct->layer_num, 3537 /* key_format */ dvdstruct->format, 3538 /* agid */ dvdstruct->agid, 3539 /* data_ptr */ databuf, 3540 /* dxfer_len */ length, 3541 /* sense_len */ SSD_FULL_SIZE, 3542 /* timeout */ 50000); 3543 3544 error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, 3545 /*sense_flags*/SF_RETRY_UA); 3546 3547 if (error != 0) 3548 goto bailout; 3549 3550 switch(dvdstruct->format) { 3551 case DVD_STRUCT_PHYSICAL: { 3552 struct scsi_read_dvd_struct_data_layer_desc *inlayer; 3553 struct dvd_layer *outlayer; 3554 struct scsi_read_dvd_struct_data_physical *phys_data; 3555 3556 phys_data = 3557 (struct scsi_read_dvd_struct_data_physical *)databuf; 3558 inlayer = &phys_data->layer_desc; 3559 outlayer = (struct dvd_layer *)&dvdstruct->data; 3560 3561 dvdstruct->length = sizeof(*inlayer); 3562 3563 outlayer->book_type = (inlayer->book_type_version & 3564 RDSD_BOOK_TYPE_MASK) >> RDSD_BOOK_TYPE_SHIFT; 3565 outlayer->book_version = (inlayer->book_type_version & 3566 RDSD_BOOK_VERSION_MASK); 3567 outlayer->disc_size = (inlayer->disc_size_max_rate & 3568 RDSD_DISC_SIZE_MASK) >> RDSD_DISC_SIZE_SHIFT; 3569 outlayer->max_rate = (inlayer->disc_size_max_rate & 3570 RDSD_MAX_RATE_MASK); 3571 outlayer->nlayers = (inlayer->layer_info & 3572 RDSD_NUM_LAYERS_MASK) >> RDSD_NUM_LAYERS_SHIFT; 3573 outlayer->track_path = (inlayer->layer_info & 3574 RDSD_TRACK_PATH_MASK) >> RDSD_TRACK_PATH_SHIFT; 3575 outlayer->layer_type = (inlayer->layer_info & 3576 RDSD_LAYER_TYPE_MASK); 3577 outlayer->linear_density = (inlayer->density & 3578 RDSD_LIN_DENSITY_MASK) >> RDSD_LIN_DENSITY_SHIFT; 3579 outlayer->track_density = (inlayer->density & 3580 RDSD_TRACK_DENSITY_MASK); 3581 outlayer->bca = (inlayer->bca & RDSD_BCA_MASK) >> 3582 RDSD_BCA_SHIFT; 3583 outlayer->start_sector = scsi_3btoul(inlayer->main_data_start); 3584 outlayer->end_sector = scsi_3btoul(inlayer->main_data_end); 3585 outlayer->end_sector_l0 = 3586 scsi_3btoul(inlayer->end_sector_layer0); 3587 break; 3588 } 3589 case DVD_STRUCT_COPYRIGHT: { 3590 struct scsi_read_dvd_struct_data_copyright *copy_data; 3591 3592 copy_data = (struct scsi_read_dvd_struct_data_copyright *) 3593 databuf; 3594 3595 dvdstruct->cpst = copy_data->cps_type; 3596 dvdstruct->rmi = copy_data->region_info; 3597 dvdstruct->length = 0; 3598 3599 break; 3600 } 3601 default: 3602 /* 3603 * Tell the user what the overall length is, no matter 3604 * what we can actually fit in the data buffer. 3605 */ 3606 dvdstruct->length = length - ccb->csio.resid - 3607 sizeof(struct scsi_read_dvd_struct_data_header); 3608 3609 /* 3610 * But only actually copy out the smaller of what we read 3611 * in or what the structure can take. 3612 */ 3613 bcopy(databuf + sizeof(struct scsi_read_dvd_struct_data_header), 3614 dvdstruct->data, 3615 min(sizeof(dvdstruct->data), dvdstruct->length)); 3616 break; 3617 } 3618 3619 bailout: 3620 xpt_release_ccb(ccb); 3621 cam_periph_unlock(periph); 3622 3623 if (databuf != NULL) 3624 free(databuf, M_DEVBUF); 3625 3626 return(error); 3627 } 3628 3629 void 3630 scsi_report_key(struct ccb_scsiio *csio, u_int32_t retries, 3631 void (*cbfcnp)(struct cam_periph *, union ccb *), 3632 u_int8_t tag_action, u_int32_t lba, u_int8_t agid, 3633 u_int8_t key_format, u_int8_t *data_ptr, u_int32_t dxfer_len, 3634 u_int8_t sense_len, u_int32_t timeout) 3635 { 3636 struct scsi_report_key *scsi_cmd; 3637 3638 scsi_cmd = (struct scsi_report_key *)&csio->cdb_io.cdb_bytes; 3639 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3640 scsi_cmd->opcode = REPORT_KEY; 3641 scsi_ulto4b(lba, scsi_cmd->lba); 3642 scsi_ulto2b(dxfer_len, scsi_cmd->alloc_len); 3643 scsi_cmd->agid_keyformat = (agid << RK_KF_AGID_SHIFT) | 3644 (key_format & RK_KF_KEYFORMAT_MASK); 3645 3646 cam_fill_csio(csio, 3647 retries, 3648 cbfcnp, 3649 /*flags*/ (dxfer_len == 0) ? CAM_DIR_NONE : CAM_DIR_IN, 3650 tag_action, 3651 /*data_ptr*/ data_ptr, 3652 /*dxfer_len*/ dxfer_len, 3653 sense_len, 3654 sizeof(*scsi_cmd), 3655 timeout); 3656 } 3657 3658 void 3659 scsi_send_key(struct ccb_scsiio *csio, u_int32_t retries, 3660 void (*cbfcnp)(struct cam_periph *, union ccb *), 3661 u_int8_t tag_action, u_int8_t agid, u_int8_t key_format, 3662 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, 3663 u_int32_t timeout) 3664 { 3665 struct scsi_send_key *scsi_cmd; 3666 3667 scsi_cmd = (struct scsi_send_key *)&csio->cdb_io.cdb_bytes; 3668 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3669 scsi_cmd->opcode = SEND_KEY; 3670 3671 scsi_ulto2b(dxfer_len, scsi_cmd->param_len); 3672 scsi_cmd->agid_keyformat = (agid << RK_KF_AGID_SHIFT) | 3673 (key_format & RK_KF_KEYFORMAT_MASK); 3674 3675 cam_fill_csio(csio, 3676 retries, 3677 cbfcnp, 3678 /*flags*/ CAM_DIR_OUT, 3679 tag_action, 3680 /*data_ptr*/ data_ptr, 3681 /*dxfer_len*/ dxfer_len, 3682 sense_len, 3683 sizeof(*scsi_cmd), 3684 timeout); 3685 } 3686 3687 3688 void 3689 scsi_read_dvd_structure(struct ccb_scsiio *csio, u_int32_t retries, 3690 void (*cbfcnp)(struct cam_periph *, union ccb *), 3691 u_int8_t tag_action, u_int32_t address, 3692 u_int8_t layer_number, u_int8_t format, u_int8_t agid, 3693 u_int8_t *data_ptr, u_int32_t dxfer_len, 3694 u_int8_t sense_len, u_int32_t timeout) 3695 { 3696 struct scsi_read_dvd_structure *scsi_cmd; 3697 3698 scsi_cmd = (struct scsi_read_dvd_structure *)&csio->cdb_io.cdb_bytes; 3699 bzero(scsi_cmd, sizeof(*scsi_cmd)); 3700 scsi_cmd->opcode = READ_DVD_STRUCTURE; 3701 3702 scsi_ulto4b(address, scsi_cmd->address); 3703 scsi_cmd->layer_number = layer_number; 3704 scsi_cmd->format = format; 3705 scsi_ulto2b(dxfer_len, scsi_cmd->alloc_len); 3706 /* The AGID is the top two bits of this byte */ 3707 scsi_cmd->agid = agid << 6; 3708 3709 cam_fill_csio(csio, 3710 retries, 3711 cbfcnp, 3712 /*flags*/ CAM_DIR_IN, 3713 tag_action, 3714 /*data_ptr*/ data_ptr, 3715 /*dxfer_len*/ dxfer_len, 3716 sense_len, 3717 sizeof(*scsi_cmd), 3718 timeout); 3719 } 3720