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