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