Bug Summary

File:scsi/cd.c
Warning:line 335, column 5
Value stored to 'error' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cd.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/scsi/cd.c
1/* $OpenBSD: cd.c,v 1.265 2022/01/11 23:10:11 jsg Exp $ */
2/* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */
3
4/*
5 * Copyright (c) 1994, 1995, 1997 Charles M. Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Charles M. Hannum.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Originally written by Julian Elischer (julian@tfs.com)
35 * for TRW Financial Systems for use under the MACH(2.5) operating system.
36 *
37 * TRW Financial Systems, in accordance with their agreement with Carnegie
38 * Mellon University, makes this software available to CMU to distribute
39 * or use in any manner that they see fit as long as this message is kept with
40 * the software. For this reason TFS also grants any other persons or
41 * organisations permission to use or modify this software.
42 *
43 * TFS supplies this software to be publicly redistributed
44 * on the understanding that TFS is not responsible for the correct
45 * functioning of this software in any circumstances.
46 *
47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
48 */
49
50#include <sys/param.h>
51#include <sys/systm.h>
52#include <sys/timeout.h>
53#include <sys/fcntl.h>
54#include <sys/stat.h>
55#include <sys/ioctl.h>
56#include <sys/mtio.h>
57#include <sys/buf.h>
58#include <sys/uio.h>
59#include <sys/malloc.h>
60#include <sys/pool.h>
61#include <sys/errno.h>
62#include <sys/device.h>
63#include <sys/disklabel.h>
64#include <sys/disk.h>
65#include <sys/cdio.h>
66#include <sys/conf.h>
67#include <sys/scsiio.h>
68#include <sys/dkio.h>
69#include <sys/vnode.h>
70
71#include <scsi/scsi_all.h>
72#include <scsi/cd.h>
73#include <scsi/scsi_debug.h>
74#include <scsi/scsi_disk.h> /* rw_10 and start_stop come from there */
75#include <scsi/scsiconf.h>
76
77
78#include <ufs/ffs/fs.h> /* for BBSIZE and SBSIZE */
79
80#define CDOUTSTANDING4 4
81
82#define MAXTRACK99 99
83#define CD_FRAMES75 75
84#define CD_SECS60 60
85
86struct cd_toc {
87 struct ioc_toc_header header;
88 struct cd_toc_entry entries[MAXTRACK99+1]; /* One extra for the */
89 /* leadout */
90};
91
92int cdmatch(struct device *, void *, void *);
93void cdattach(struct device *, struct device *, void *);
94int cdactivate(struct device *, int);
95int cddetach(struct device *, int);
96
97struct cd_softc {
98 struct device sc_dev;
99 struct disk sc_dk;
100
101 int sc_flags;
102#define CDF_DYING0x40 0x40 /* dying, when deactivated */
103 struct scsi_link *sc_link; /* contains targ, lun, etc. */
104 struct cd_parms {
105 u_int32_t secsize;
106 u_int64_t disksize; /* total number sectors */
107 } params;
108 struct bufq sc_bufq;
109 struct scsi_xshandler sc_xsh;
110};
111
112void cdstart(struct scsi_xfer *);
113void cd_buf_done(struct scsi_xfer *);
114int cd_cmd_rw6(struct scsi_generic *, int, u_int64_t, u_int32_t);
115int cd_cmd_rw10(struct scsi_generic *, int, u_int64_t, u_int32_t);
116int cd_cmd_rw12(struct scsi_generic *, int, u_int64_t, u_int32_t);
117void cdminphys(struct buf *);
118int cdgetdisklabel(dev_t, struct cd_softc *, struct disklabel *, int);
119int cd_setchan(struct cd_softc *, int, int, int, int, int);
120int cd_getvol(struct cd_softc *cd, struct ioc_vol *, int);
121int cd_setvol(struct cd_softc *, const struct ioc_vol *, int);
122int cd_load_unload(struct cd_softc *, int, int);
123int cd_set_pa_immed(struct cd_softc *, int);
124int cd_play(struct cd_softc *, int, int);
125int cd_play_tracks(struct cd_softc *, int, int, int, int);
126int cd_play_msf(struct cd_softc *, int, int, int, int, int, int);
127int cd_pause(struct cd_softc *, int);
128int cd_reset(struct cd_softc *);
129int cd_read_subchannel(struct cd_softc *, int, int, int,
130 struct cd_sub_channel_info *, int );
131int cd_read_toc(struct cd_softc *, int, int, void *, int, int);
132int cd_get_parms(struct cd_softc *, int);
133int cd_load_toc(struct cd_softc *, struct cd_toc *, int);
134int cd_interpret_sense(struct scsi_xfer *);
135u_int64_t cd_size(struct scsi_link *, int, u_int32_t *);
136
137int dvd_auth(struct cd_softc *, union dvd_authinfo *);
138int dvd_read_physical(struct cd_softc *, union dvd_struct *);
139int dvd_read_copyright(struct cd_softc *, union dvd_struct *);
140int dvd_read_disckey(struct cd_softc *, union dvd_struct *);
141int dvd_read_bca(struct cd_softc *, union dvd_struct *);
142int dvd_read_manufact(struct cd_softc *, union dvd_struct *);
143int dvd_read_struct(struct cd_softc *, union dvd_struct *);
144
145#if defined(__macppc__)
146int cd_eject(void);
147#endif /* __macppc__ */
148
149const struct cfattach cd_ca = {
150 sizeof(struct cd_softc), cdmatch, cdattach,
151 cddetach, cdactivate
152};
153
154struct cfdriver cd_cd = {
155 NULL((void *)0), "cd", DV_DISK
156};
157
158const struct scsi_inquiry_pattern cd_patterns[] = {
159 {T_CDROM0x05, T_REMOV1,
160 "", "", ""},
161 {T_CDROM0x05, T_FIXED0,
162 "", "", ""},
163 {T_WORM0x04, T_REMOV1,
164 "", "", ""},
165 {T_WORM0x04, T_FIXED0,
166 "", "", ""},
167 {T_DIRECT0x00, T_REMOV1,
168 "NEC CD-ROM DRIVE:260", "", ""},
169#if 0
170 {T_CDROM0x05, T_REMOV1, /* more luns */
171 "PIONEER ", "CD-ROM DRM-600 ", ""},
172#endif /* 0 */
173};
174
175#define cdlookup(unit)(struct cd_softc *)disk_lookup(&cd_cd, (unit)) (struct cd_softc *)disk_lookup(&cd_cd, (unit))
176
177int
178cdmatch(struct device *parent, void *match, void *aux)
179{
180 struct scsi_attach_args *sa = aux;
181 struct scsi_inquiry_data *inq = &sa->sa_sc_link->inqdata;
182 int priority;
183
184 scsi_inqmatch(inq, cd_patterns, nitems(cd_patterns)(sizeof((cd_patterns)) / sizeof((cd_patterns)[0])),
185 sizeof(cd_patterns[0]), &priority);
186
187 return priority;
188}
189
190/*
191 * The routine called by the low level scsi routine when it discovers
192 * A device suitable for this driver
193 */
194void
195cdattach(struct device *parent, struct device *self, void *aux)
196{
197 struct cd_softc *sc = (struct cd_softc *)self;
198 struct scsi_attach_args *sa = aux;
199 struct scsi_link *link = sa->sa_sc_link;
200
201 SC_DEBUG(link, SDEV_DB2, ("cdattach:\n"));
202
203 /*
204 * Store information needed to contact our base driver
205 */
206 sc->sc_link = link;
207 link->interpret_sense = cd_interpret_sense;
208 link->device_softc = sc;
209 if (link->openings > CDOUTSTANDING4)
210 link->openings = CDOUTSTANDING4;
211
212 /*
213 * Initialize disk structures.
214 */
215 sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
216 bufq_init(&sc->sc_bufq, BUFQ_DEFAULT1);
217
218 printf("\n");
219
220 scsi_xsh_set(&sc->sc_xsh, link, cdstart);
221
222 /* Attach disk. */
223 sc->sc_dk.dk_flags = DKF_NOLABELREAD0x0004;
224 disk_attach(&sc->sc_dev, &sc->sc_dk);
225}
226
227
228int
229cdactivate(struct device *self, int act)
230{
231 struct cd_softc *sc = (struct cd_softc *)self;
232
233 switch (act) {
234 case DVACT_RESUME4:
235 /*
236 * When resuming, hardware may have forgotten we locked it. So
237 * if there are any open partitions, lock the CD.
238 */
239 if (sc->sc_dk.dk_openmask != 0)
240 scsi_prevent(sc->sc_link, PR_PREVENT0x01,
241 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 |
242 SCSI_IGNORE_MEDIA_CHANGE0x00080 |
243 SCSI_SILENT0x00020 | SCSI_AUTOCONF0x00003);
244 break;
245 case DVACT_DEACTIVATE1:
246 SET(sc->sc_flags, CDF_DYING)((sc->sc_flags) |= (0x40));
247 scsi_xsh_del(&sc->sc_xsh);
248 break;
249 }
250 return 0;
251}
252
253int
254cddetach(struct device *self, int flags)
255{
256 struct cd_softc *sc = (struct cd_softc *)self;
257
258 bufq_drain(&sc->sc_bufq);
259
260 disk_gone(cdopen, self->dv_unit);
261
262 /* Detach disk. */
263 bufq_destroy(&sc->sc_bufq);
264 disk_detach(&sc->sc_dk);
265
266 return 0;
267}
268
269/*
270 * Open the device. Make sure the partition info is as up-to-date as can be.
271 */
272int
273cdopen(dev_t dev, int flag, int fmt, struct proc *p)
274{
275 struct scsi_link *link;
276 struct cd_softc *sc;
277 int error = 0, part, rawopen, unit;
278
279 unit = DISKUNIT(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) / 16)
;
280 part = DISKPART(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) % 16)
;
281
282 rawopen = (part == RAW_PART2) && (fmt == S_IFCHR0020000);
283
284 sc = cdlookup(unit)(struct cd_softc *)disk_lookup(&cd_cd, (unit));
285 if (sc == NULL((void *)0))
286 return ENXIO6;
287 if (ISSET(sc->sc_flags, CDF_DYING)((sc->sc_flags) & (0x40))) {
288 device_unref(&sc->sc_dev);
289 return ENXIO6;
290 }
291
292 link = sc->sc_link;
293 SC_DEBUG(link, SDEV_DB1,
294 ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
295 cd_cd.cd_ndevs, part));
296
297 if ((error = disk_lock(&sc->sc_dk)) != 0) {
298 device_unref(&sc->sc_dev);
299 return error;
300 }
301
302 if (sc->sc_dk.dk_openmask != 0) {
303 /*
304 * If any partition is open, but the disk has been invalidated,
305 * disallow further opens.
306 */
307 if (!ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002))) {
308 if (rawopen)
309 goto out;
310 error = EIO5;
311 goto bad;
312 }
313 } else {
314 /*
315 * Check that it is still responding and ok. Drive can be in
316 * progress of loading media so use increased retries number
317 * and don't ignore NOT_READY.
318 */
319
320 /* Use cd_interpret_sense() now. */
321 SET(link->flags, SDEV_OPEN)((link->flags) |= (0x0008));
322
323 error = scsi_test_unit_ready(link, TEST_READY_RETRIES5,
324 (rawopen ? SCSI_SILENT0x00020 : 0) | SCSI_IGNORE_ILLEGAL_REQUEST0x00100 |
325 SCSI_IGNORE_MEDIA_CHANGE0x00080);
326
327 /* Start the cd spinning if necessary. */
328 if (error == EIO5)
329 error = scsi_start(link, SSS_START0x01,
330 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 |
331 SCSI_IGNORE_MEDIA_CHANGE0x00080 | SCSI_SILENT0x00020);
332
333 if (error) {
334 if (rawopen) {
335 error = 0;
Value stored to 'error' is never read
336 goto out;
337 } else
338 goto bad;
339 }
340
341 /* Lock the cd in. */
342 error = scsi_prevent(link, PR_PREVENT0x01,
343 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_MEDIA_CHANGE0x00080 |
344 SCSI_SILENT0x00020);
345 if (error)
346 goto bad;
347
348 /* Load the physical device parameters. */
349 SET(link->flags, SDEV_MEDIA_LOADED)((link->flags) |= (0x0002));
350 if (cd_get_parms(sc, (rawopen ? SCSI_SILENT0x00020 : 0) |
351 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_MEDIA_CHANGE0x00080)) {
352 CLR(link->flags, SDEV_MEDIA_LOADED)((link->flags) &= ~(0x0002));
353 error = ENXIO6;
354 goto bad;
355 }
356 SC_DEBUG(link, SDEV_DB3, ("Params loaded\n"));
357
358 /* Fabricate a disk label. */
359 cdgetdisklabel(dev, sc, sc->sc_dk.dk_label, 0);
360 SC_DEBUG(link, SDEV_DB3, ("Disklabel fabricated\n"));
361 }
362
363out:
364 if ((error = disk_openpart(&sc->sc_dk, part, fmt, 1)) != 0)
365 goto bad;
366
367 SET(link->flags, SDEV_OPEN)((link->flags) |= (0x0008));
368 SC_DEBUG(link, SDEV_DB3, ("open complete\n"));
369
370 /* It's OK to fall through because dk_openmask is now non-zero. */
371bad:
372 if (sc->sc_dk.dk_openmask == 0) {
373 scsi_prevent(link, PR_ALLOW0x00,
374 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_MEDIA_CHANGE0x00080 |
375 SCSI_SILENT0x00020);
376 CLR(link->flags, SDEV_OPEN | SDEV_MEDIA_LOADED)((link->flags) &= ~(0x0008 | 0x0002));
377 }
378
379 disk_unlock(&sc->sc_dk);
380 device_unref(&sc->sc_dev);
381 return error;
382}
383
384/*
385 * Close the device. Only called if we are the last occurrence of an open
386 * device.
387 */
388int
389cdclose(dev_t dev, int flag, int fmt, struct proc *p)
390{
391 struct cd_softc *sc;
392 int part = DISKPART(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) % 16)
;
393
394 sc = cdlookup(DISKUNIT(dev))(struct cd_softc *)disk_lookup(&cd_cd, ((((unsigned)((dev
) & 0xff) | (((dev) & 0xffff0000) >> 8)) / 16))
)
;
395 if (sc == NULL((void *)0))
396 return ENXIO6;
397 if (ISSET(sc->sc_flags, CDF_DYING)((sc->sc_flags) & (0x40))) {
398 device_unref(&sc->sc_dev);
399 return ENXIO6;
400 }
401
402 disk_lock_nointr(&sc->sc_dk);
403
404 disk_closepart(&sc->sc_dk, part, fmt);
405
406 if (sc->sc_dk.dk_openmask == 0) {
407 /* XXXX Must wait for I/O to complete! */
408
409 scsi_prevent(sc->sc_link, PR_ALLOW0x00,
410 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_NOT_READY0x00040 |
411 SCSI_SILENT0x00020);
412 CLR(sc->sc_link->flags, SDEV_OPEN | SDEV_MEDIA_LOADED)((sc->sc_link->flags) &= ~(0x0008 | 0x0002));
413
414 if (ISSET(sc->sc_link->flags, SDEV_EJECTING)((sc->sc_link->flags) & (0x0100))) {
415 scsi_start(sc->sc_link, SSS_STOP0x00|SSS_LOEJ0x02, 0);
416
417 CLR(sc->sc_link->flags, SDEV_EJECTING)((sc->sc_link->flags) &= ~(0x0100));
418 }
419
420 scsi_xsh_del(&sc->sc_xsh);
421 }
422
423 disk_unlock(&sc->sc_dk);
424
425 device_unref(&sc->sc_dev);
426 return 0;
427}
428
429/*
430 * Actually translate the requested transfer into one the physical driver can
431 * understand. The transfer is described by a buf and will include only one
432 * physical transfer.
433 */
434void
435cdstrategy(struct buf *bp)
436{
437 struct cd_softc *sc;
438 int s;
439
440 sc = cdlookup(DISKUNIT(bp->b_dev))(struct cd_softc *)disk_lookup(&cd_cd, ((((unsigned)((bp->
b_dev) & 0xff) | (((bp->b_dev) & 0xffff0000) >>
8)) / 16)))
;
441 if (sc == NULL((void *)0)) {
442 bp->b_error = ENXIO6;
443 goto bad;
444 }
445 if (ISSET(sc->sc_flags, CDF_DYING)((sc->sc_flags) & (0x40))) {
446 bp->b_error = ENXIO6;
447 goto bad;
448 }
449
450 SC_DEBUG(sc->sc_link, SDEV_DB2, ("cdstrategy: %ld bytes @ blk %lld\n",
451 bp->b_bcount, (long long)bp->b_blkno));
452 /*
453 * If the device has been made invalid, error out
454 * maybe the media changed, or no media loaded
455 */
456 if (!ISSET(sc->sc_link->flags, SDEV_MEDIA_LOADED)((sc->sc_link->flags) & (0x0002))) {
457 bp->b_error = EIO5;
458 goto bad;
459 }
460
461 /* Validate the request. */
462 if (bounds_check_with_label(bp, sc->sc_dk.dk_label) == -1)
463 goto done;
464
465 /* Place it in the queue of disk activities for this disk. */
466 bufq_queue(&sc->sc_bufq, bp);
467
468 /*
469 * Tell the device to get going on the transfer if it's
470 * not doing anything, otherwise just wait for completion
471 */
472 scsi_xsh_add(&sc->sc_xsh);
473
474 device_unref(&sc->sc_dev);
475 return;
476
477bad:
478 SET(bp->b_flags, B_ERROR)((bp->b_flags) |= (0x00000400));
479 bp->b_resid = bp->b_bcount;
480done:
481 s = splbio()splraise(0x6);
482 biodone(bp);
483 splx(s)spllower(s);
484 if (sc != NULL((void *)0))
485 device_unref(&sc->sc_dev);
486}
487
488int
489cd_cmd_rw6(struct scsi_generic *generic, int read, u_int64_t secno,
490 u_int32_t nsecs)
491{
492 struct scsi_rw *cmd = (struct scsi_rw *)generic;
493
494 cmd->opcode = read ? READ_COMMAND0x08 : WRITE_COMMAND0x0a;
495 _lto3b(secno, cmd->addr);
496 cmd->length = nsecs & 0xff;
497
498 return sizeof(*cmd);
499}
500
501int
502cd_cmd_rw10(struct scsi_generic *generic, int read, u_int64_t secno,
503 u_int32_t nsecs)
504{
505 struct scsi_rw_10 *cmd = (struct scsi_rw_10 *)generic;
506
507 cmd->opcode = read ? READ_100x28 : WRITE_100x2a;
508 _lto4b(secno, cmd->addr);
509 _lto2b(nsecs, cmd->length);
510
511 return sizeof(*cmd);
512}
513
514int
515cd_cmd_rw12(struct scsi_generic *generic, int read, u_int64_t secno,
516 u_int32_t nsecs)
517{
518 struct scsi_rw_12 *cmd = (struct scsi_rw_12 *)generic;
519
520 cmd->opcode = read ? READ_120xa8 : WRITE_120xaa;
521 _lto4b(secno, cmd->addr);
522 _lto4b(nsecs, cmd->length);
523
524 return sizeof(*cmd);
525}
526
527/*
528 * cdstart looks to see if there is a buf waiting for the device
529 * and that the device is not already busy. If both are true,
530 * It dequeues the buf and creates a scsi command to perform the
531 * transfer in the buf. The transfer request will call scsi_done
532 * on completion, which will in turn call this routine again
533 * so that the next queued transfer is performed.
534 * The bufs are queued by the strategy routine (cdstrategy)
535 *
536 * This routine is also called after other non-queued requests
537 * have been made of the scsi driver, to ensure that the queue
538 * continues to be drained.
539 *
540 * must be called at the correct (highish) spl level
541 * cdstart() is called at splbio from cdstrategy and scsi_done
542 */
543void
544cdstart(struct scsi_xfer *xs)
545{
546 struct scsi_link *link = xs->sc_link;
547 struct cd_softc *sc = link->device_softc;
548 struct buf *bp;
549 struct partition *p;
550 u_int64_t secno;
551 u_int32_t nsecs;
552 int read;
553
554 SC_DEBUG(link, SDEV_DB2, ("cdstart\n"));
555
556 if (ISSET(sc->sc_flags, CDF_DYING)((sc->sc_flags) & (0x40))) {
557 scsi_xs_put(xs);
558 return;
559 }
560
561 if (!ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002))) {
562 bufq_drain(&sc->sc_bufq);
563 scsi_xs_put(xs);
564 return;
565 }
566
567 bp = bufq_dequeue(&sc->sc_bufq);
568 if (bp == NULL((void *)0)) {
569 scsi_xs_put(xs);
570 return;
571 }
572 read = ISSET(bp->b_flags, B_READ)((bp->b_flags) & (0x00008000));
573
574 SET(xs->flags, (read ? SCSI_DATA_IN : SCSI_DATA_OUT))((xs->flags) |= ((read ? 0x00800 : 0x01000)));
575 xs->timeout = 30000;
576 xs->data = bp->b_data;
577 xs->datalen = bp->b_bcount;
578 xs->done = cd_buf_done;
579 xs->cookie = bp;
580 xs->bp = bp;
581
582 p = &sc->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)(((unsigned)((bp->b_dev) & 0xff) | (((bp->b_dev) &
0xffff0000) >> 8)) % 16)
];
583 secno = DL_GETPOFFSET(p)(((u_int64_t)(p)->p_offseth << 32) + (p)->p_offset
)
+ DL_BLKTOSEC(sc->sc_dk.dk_label, bp->b_blkno)((bp->b_blkno) / ((sc->sc_dk.dk_label)->d_secsize / (
1 << 9)))
;
584 nsecs = howmany(bp->b_bcount, sc->sc_dk.dk_label->d_secsize)(((bp->b_bcount) + ((sc->sc_dk.dk_label->d_secsize) -
1)) / (sc->sc_dk.dk_label->d_secsize))
;
585
586 if (!ISSET(link->flags, SDEV_ATAPI | SDEV_UMASS)((link->flags) & (0x0200 | 0x0400)) &&
587 (SID_ANSII_REV(&link->inqdata)((&link->inqdata)->version & 0x07) < SCSI_REV_20x02) &&
588 ((secno & 0x1fffff) == secno) &&
589 ((nsecs & 0xff) == nsecs))
590 xs->cmdlen = cd_cmd_rw6(&xs->cmd, read, secno, nsecs);
591 else if (((secno & 0xffffffff) == secno) &&
592 ((nsecs & 0xffff) == nsecs))
593 xs->cmdlen = cd_cmd_rw10(&xs->cmd, read, secno, nsecs);
594 else
595 xs->cmdlen = cd_cmd_rw12(&xs->cmd, read, secno, nsecs);
596
597 disk_busy(&sc->sc_dk);
598 scsi_xs_exec(xs);
599
600 /* Move onto the next io. */
601 if (bufq_peek(&sc->sc_bufq))
602 scsi_xsh_add(&sc->sc_xsh);
603}
604
605void
606cd_buf_done(struct scsi_xfer *xs)
607{
608 struct cd_softc *sc = xs->sc_link->device_softc;
609 struct buf *bp = xs->cookie;
610 int error, s;
611
612 switch (xs->error) {
613 case XS_NOERROR0:
614 bp->b_error = 0;
615 CLR(bp->b_flags, B_ERROR)((bp->b_flags) &= ~(0x00000400));
616 bp->b_resid = xs->resid;
617 break;
618
619 case XS_SENSE1:
620 case XS_SHORTSENSE6:
621 SC_DEBUG_SENSE(xs);
622 error = cd_interpret_sense(xs);
623 if (error == 0) {
624 bp->b_error = 0;
625 CLR(bp->b_flags, B_ERROR)((bp->b_flags) &= ~(0x00000400));
626 bp->b_resid = xs->resid;
627 break;
628 }
629 if (error != ERESTART-1)
630 xs->retries = 0;
631 goto retry;
632
633 case XS_BUSY5:
634 if (xs->retries) {
635 if (scsi_delay(xs, 1) != ERESTART-1)
636 xs->retries = 0;
637 }
638 goto retry;
639
640 case XS_TIMEOUT4:
641retry:
642 if (xs->retries--) {
643 scsi_xs_exec(xs);
644 return;
645 }
646 /* FALLTHROUGH */
647
648 default:
649 bp->b_error = EIO5;
650 SET(bp->b_flags, B_ERROR)((bp->b_flags) |= (0x00000400));
651 bp->b_resid = bp->b_bcount;
652 break;
653 }
654
655 disk_unbusy(&sc->sc_dk, bp->b_bcount - xs->resid, bp->b_blkno,
656 bp->b_flags & B_READ0x00008000);
657
658 s = splbio()splraise(0x6);
659 biodone(bp);
660 splx(s)spllower(s);
661 scsi_xs_put(xs);
662}
663
664void
665cdminphys(struct buf *bp)
666{
667 struct scsi_link *link;
668 struct cd_softc *sc;
669 long max;
670
671 sc = cdlookup(DISKUNIT(bp->b_dev))(struct cd_softc *)disk_lookup(&cd_cd, ((((unsigned)((bp->
b_dev) & 0xff) | (((bp->b_dev) & 0xffff0000) >>
8)) / 16)))
;
672 if (sc == NULL((void *)0))
673 return;
674 link = sc->sc_link;
675
676 /*
677 * If the device is ancient, we want to make sure that
678 * the transfer fits into a 6-byte cdb.
679 *
680 * XXX Note that the SCSI-I spec says that 256-block transfers
681 * are allowed in a 6-byte read/write, and are specified
682 * by setting the "length" to 0. However, we're conservative
683 * here, allowing only 255-block transfers in case an
684 * ancient device gets confused by length == 0. A length of 0
685 * in a 10-byte read/write actually means 0 blocks.
686 */
687 if (!ISSET(link->flags, SDEV_ATAPI | SDEV_UMASS)((link->flags) & (0x0200 | 0x0400)) &&
688 SID_ANSII_REV(&link->inqdata)((&link->inqdata)->version & 0x07) < SCSI_REV_20x02) {
689 max = sc->sc_dk.dk_label->d_secsize * 0xff;
690
691 if (bp->b_bcount > max)
692 bp->b_bcount = max;
693 }
694
695 if (link->bus->sb_adapter->dev_minphys != NULL((void *)0))
696 (*link->bus->sb_adapter->dev_minphys)(bp, link);
697 else
698 minphys(bp);
699
700 device_unref(&sc->sc_dev);
701}
702
703int
704cdread(dev_t dev, struct uio *uio, int ioflag)
705{
706 return physio(cdstrategy, dev, B_READ0x00008000, cdminphys, uio);
707}
708
709int
710cdwrite(dev_t dev, struct uio *uio, int ioflag)
711{
712 return physio(cdstrategy, dev, B_WRITE0x00000000, cdminphys, uio);
713}
714
715/*
716 * Perform special action on behalf of the user.
717 * Knows about the internals of this device
718 */
719int
720cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
721{
722 struct cd_softc *sc;
723 struct disklabel *lp;
724 int part = DISKPART(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) % 16)
;
725 int error = 0;
726
727 sc = cdlookup(DISKUNIT(dev))(struct cd_softc *)disk_lookup(&cd_cd, ((((unsigned)((dev
) & 0xff) | (((dev) & 0xffff0000) >> 8)) / 16))
)
;
728 if (sc == NULL((void *)0))
729 return ENXIO6;
730 if (ISSET(sc->sc_flags, CDF_DYING)((sc->sc_flags) & (0x40))) {
731 device_unref(&sc->sc_dev);
732 return ENXIO6;
733 }
734
735 SC_DEBUG(sc->sc_link, SDEV_DB2, ("cdioctl 0x%lx\n", cmd));
736
737 /*
738 * If the device is not valid.. abandon ship
739 */
740 if (!ISSET(sc->sc_link->flags, SDEV_MEDIA_LOADED)((sc->sc_link->flags) & (0x0002))) {
741 switch (cmd) {
742 case DIOCLOCK((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('d')) << 8) | ((113)))
:
743 case DIOCEJECT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('d')) << 8) | ((112)))
:
744 case SCIOCIDENTIFY((unsigned long)0x40000000 | ((sizeof(struct scsi_addr) &
0x1fff) << 16) | ((('Q')) << 8) | ((9)))
:
745 case SCIOCCOMMAND(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(scsireq_t) & 0x1fff) << 16) | ((('Q')) << 8)
| ((1)))
:
746 case SCIOCDEBUG((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('Q')) << 8) | ((2)))
:
747 case CDIOCLOADUNLOAD((unsigned long)0x80000000 | ((sizeof(struct ioc_load_unload)
& 0x1fff) << 16) | ((('c')) << 8) | ((26)))
:
748 case SCIOCRESET((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('Q')) << 8) | ((7)))
:
749 case CDIOCGETVOL((unsigned long)0x40000000 | ((sizeof(struct ioc_vol) & 0x1fff
) << 16) | ((('c')) << 8) | ((10)))
:
750 case CDIOCSETVOL((unsigned long)0x80000000 | ((sizeof(struct ioc_vol) & 0x1fff
) << 16) | ((('c')) << 8) | ((11)))
:
751 case CDIOCSETMONO((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((12)))
:
752 case CDIOCSETSTEREO((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((13)))
:
753 case CDIOCSETMUTE((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((14)))
:
754 case CDIOCSETLEFT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((15)))
:
755 case CDIOCSETRIGHT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((16)))
:
756 case CDIOCCLOSE((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((27)))
:
757 case CDIOCEJECT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((24)))
:
758 case CDIOCALLOW((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((25)))
:
759 case CDIOCPREVENT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((26)))
:
760 case CDIOCSETDEBUG((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((17)))
:
761 case CDIOCCLRDEBUG((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((18)))
:
762 case CDIOCRESET((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((21)))
:
763 case DVD_AUTH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(union dvd_authinfo) & 0x1fff) << 16) | ((('d')) <<
8) | ((2)))
:
764 case DVD_READ_STRUCT(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(union dvd_struct) & 0x1fff) << 16) | ((('d')) <<
8) | ((0)))
:
765 case MTIOCTOP((unsigned long)0x80000000 | ((sizeof(struct mtop) & 0x1fff
) << 16) | ((('m')) << 8) | ((1)))
:
766 if (part == RAW_PART2)
767 break;
768 /* FALLTHROUGH */
769 default:
770 if (!ISSET(sc->sc_link->flags, SDEV_OPEN)((sc->sc_link->flags) & (0x0008)))
771 error = ENODEV19;
772 else
773 error = EIO5;
774 goto exit;
775 }
776 }
777
778 switch (cmd) {
779 case DIOCRLDINFO((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('d')) << 8) | ((115)))
:
780 lp = malloc(sizeof(*lp), M_TEMP127, M_WAITOK0x0001);
781 cdgetdisklabel(dev, sc, lp, 0);
782 memcpy(sc->sc_dk.dk_label, lp, sizeof(*lp))__builtin_memcpy((sc->sc_dk.dk_label), (lp), (sizeof(*lp))
)
;
783 free(lp, M_TEMP127, sizeof(*lp));
784 break;
785
786 case DIOCGPDINFO((unsigned long)0x40000000 | ((sizeof(struct disklabel) &
0x1fff) << 16) | ((('d')) << 8) | ((114)))
:
787 cdgetdisklabel(dev, sc, (struct disklabel *)addr, 1);
788 break;
789
790 case DIOCGDINFO((unsigned long)0x40000000 | ((sizeof(struct disklabel) &
0x1fff) << 16) | ((('d')) << 8) | ((101)))
:
791 *(struct disklabel *)addr = *(sc->sc_dk.dk_label);
792 break;
793
794 case DIOCGPART((unsigned long)0x80000000 | ((sizeof(struct partinfo) & 0x1fff
) << 16) | ((('d')) << 8) | ((104)))
:
795 ((struct partinfo *)addr)->disklab = sc->sc_dk.dk_label;
796 ((struct partinfo *)addr)->part =
797 &sc->sc_dk.dk_label->d_partitions[DISKPART(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) % 16)
];
798 break;
799
800 case DIOCWDINFO((unsigned long)0x80000000 | ((sizeof(struct disklabel) &
0x1fff) << 16) | ((('d')) << 8) | ((103)))
:
801 case DIOCSDINFO((unsigned long)0x80000000 | ((sizeof(struct disklabel) &
0x1fff) << 16) | ((('d')) << 8) | ((102)))
:
802 if (!ISSET(flag, FWRITE)((flag) & (0x0002))) {
803 error = EBADF9;
804 break;
805 }
806
807 if ((error = disk_lock(&sc->sc_dk)) != 0)
808 break;
809
810 error = setdisklabel(sc->sc_dk.dk_label,
811 (struct disklabel *)addr, sc->sc_dk.dk_openmask);
812 if (error == 0) {
813 }
814
815 disk_unlock(&sc->sc_dk);
816 break;
817
818 case CDIOCPLAYTRACKS((unsigned long)0x80000000 | ((sizeof(struct ioc_play_track) &
0x1fff) << 16) | ((('c')) << 8) | ((1)))
: {
819 struct ioc_play_track *args = (struct ioc_play_track *)addr;
820
821 if ((error = cd_set_pa_immed(sc, 0)) != 0)
822 break;
823 error = cd_play_tracks(sc, args->start_track,
824 args->start_index, args->end_track, args->end_index);
825 break;
826 }
827 case CDIOCPLAYMSF((unsigned long)0x80000000 | ((sizeof(struct ioc_play_msf) &
0x1fff) << 16) | ((('c')) << 8) | ((25)))
: {
828 struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
829
830 if ((error = cd_set_pa_immed(sc, 0)) != 0)
831 break;
832 error = cd_play_msf(sc, args->start_m, args->start_s,
833 args->start_f, args->end_m, args->end_s, args->end_f);
834 break;
835 }
836 case CDIOCPLAYBLOCKS((unsigned long)0x80000000 | ((sizeof(struct ioc_play_blocks)
& 0x1fff) << 16) | ((('c')) << 8) | ((2)))
: {
837 struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
838
839 if ((error = cd_set_pa_immed(sc, 0)) != 0)
840 break;
841 error = cd_play(sc, args->blk, args->len);
842 break;
843 }
844 case CDIOCREADSUBCHANNEL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ioc_read_subchannel) & 0x1fff) << 16) | (((
'c')) << 8) | ((3)))
: {
845 struct ioc_read_subchannel *args =
846 (struct ioc_read_subchannel *)addr;
847 struct cd_sub_channel_info *data;
848 int len = args->data_len;
849
850 if (len > sizeof(*data) ||
851 len < sizeof(struct cd_sub_channel_header)) {
852 error = EINVAL22;
853 break;
854 }
855 data = dma_alloc(sizeof(*data), PR_WAITOK0x0001);
856 error = cd_read_subchannel(sc, args->address_format,
857 args->data_format, args->track, data, len);
858 if (error) {
859 dma_free(data, sizeof(*data));
860 break;
861 }
862 len = min(len, _2btol(data->header.data_len) +
863 sizeof(struct cd_sub_channel_header));
864 error = copyout(data, args->data, len);
865 dma_free(data, sizeof(*data));
866 break;
867 }
868 case CDIOREADTOCHEADER((unsigned long)0x40000000 | ((sizeof(struct ioc_toc_header) &
0x1fff) << 16) | ((('c')) << 8) | ((4)))
: {
869 struct ioc_toc_header *th;
870
871 th = dma_alloc(sizeof(*th), PR_WAITOK0x0001);
872 if ((error = cd_read_toc(sc, 0, 0, th, sizeof(*th), 0)) != 0) {
873 dma_free(th, sizeof(*th));
874 break;
875 }
876 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC)((sc->sc_link->quirks) & (0x0040)))
877 th->len = letoh16(th->len)((__uint16_t)(th->len));
878 else
879 th->len = betoh16(th->len)(__uint16_t)(__builtin_constant_p(th->len) ? (__uint16_t)(
((__uint16_t)(th->len) & 0xffU) << 8 | ((__uint16_t
)(th->len) & 0xff00U) >> 8) : __swap16md(th->
len))
;
880 if (th->len > 0)
881 memcpy(addr, th, sizeof(*th))__builtin_memcpy((addr), (th), (sizeof(*th)));
882 else
883 error = EIO5;
884 dma_free(th, sizeof(*th));
885 break;
886 }
887 case CDIOREADTOCENTRYS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ioc_read_toc_entry) & 0x1fff) << 16) | ((('c'
)) << 8) | ((5)))
: {
888 struct cd_toc *toc;
889 struct ioc_read_toc_entry *te =
890 (struct ioc_read_toc_entry *)addr;
891 struct ioc_toc_header *th;
892 struct cd_toc_entry *cte;
893 int len = te->data_len;
894 int ntracks;
895
896 toc = dma_alloc(sizeof(*toc), PR_WAITOK0x0001 | PR_ZERO0x0008);
897
898 th = &toc->header;
899
900 if (len > sizeof(toc->entries) ||
901 len < sizeof(struct cd_toc_entry)) {
902 dma_free(toc, sizeof(*toc));
903 error = EINVAL22;
904 break;
905 }
906 error = cd_read_toc(sc, te->address_format, te->starting_track,
907 toc, len + sizeof(struct ioc_toc_header), 0);
908 if (error) {
909 dma_free(toc, sizeof(*toc));
910 break;
911 }
912 if (te->address_format == CD_LBA_FORMAT1)
913 for (ntracks =
914 th->ending_track - th->starting_track + 1;
915 ntracks >= 0; ntracks--) {
916 cte = &toc->entries[ntracks];
917 cte->addr_type = CD_LBA_FORMAT1;
918 if (ISSET(sc->sc_link->quirks,((sc->sc_link->quirks) & (0x0040))
919 ADEV_LITTLETOC)((sc->sc_link->quirks) & (0x0040))) {
920#if BYTE_ORDER1234 == BIG_ENDIAN4321
921 swap16_multi((u_int16_t *)&cte->addr,do { __size_t __swap16_multi_n = (sizeof(cte->addr) / 2); __uint16_t
*__swap16_multi_v = ((u_int16_t *)&cte->addr); while (
__swap16_multi_n) { *__swap16_multi_v = (__uint16_t)(__builtin_constant_p
(*__swap16_multi_v) ? (__uint16_t)(((__uint16_t)(*__swap16_multi_v
) & 0xffU) << 8 | ((__uint16_t)(*__swap16_multi_v) &
0xff00U) >> 8) : __swap16md(*__swap16_multi_v)); __swap16_multi_v
++; __swap16_multi_n--; } } while (0)
922 sizeof(cte->addr) / 2)do { __size_t __swap16_multi_n = (sizeof(cte->addr) / 2); __uint16_t
*__swap16_multi_v = ((u_int16_t *)&cte->addr); while (
__swap16_multi_n) { *__swap16_multi_v = (__uint16_t)(__builtin_constant_p
(*__swap16_multi_v) ? (__uint16_t)(((__uint16_t)(*__swap16_multi_v
) & 0xffU) << 8 | ((__uint16_t)(*__swap16_multi_v) &
0xff00U) >> 8) : __swap16md(*__swap16_multi_v)); __swap16_multi_v
++; __swap16_multi_n--; } } while (0)
;
923#endif /* BYTE_ORDER == BIG_ENDIAN */
924 } else
925 cte->addr.lba = betoh32(cte->addr.lba)(__uint32_t)(__builtin_constant_p(cte->addr.lba) ? (__uint32_t
)(((__uint32_t)(cte->addr.lba) & 0xff) << 24 | (
(__uint32_t)(cte->addr.lba) & 0xff00) << 8 | ((__uint32_t
)(cte->addr.lba) & 0xff0000) >> 8 | ((__uint32_t
)(cte->addr.lba) & 0xff000000) >> 24) : __swap32md
(cte->addr.lba))
;
926 }
927 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC)((sc->sc_link->quirks) & (0x0040))) {
928 th->len = letoh16(th->len)((__uint16_t)(th->len));
929 } else
930 th->len = betoh16(th->len)(__uint16_t)(__builtin_constant_p(th->len) ? (__uint16_t)(
((__uint16_t)(th->len) & 0xffU) << 8 | ((__uint16_t
)(th->len) & 0xff00U) >> 8) : __swap16md(th->
len))
;
931 len = min(len, th->len - (sizeof(th->starting_track) +
932 sizeof(th->ending_track)));
933
934 error = copyout(toc->entries, te->data, len);
935 dma_free(toc, sizeof(*toc));
936 break;
937 }
938 case CDIOREADMSADDR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(int) & 0x1fff) << 16) | ((('c')) << 8) | ((6
)))
: {
939 struct cd_toc *toc;
940 int sessno = *(int *)addr;
941 struct cd_toc_entry *cte;
942
943 if (sessno != 0) {
944 error = EINVAL22;
945 break;
946 }
947
948 toc = dma_alloc(sizeof(*toc), PR_WAITOK0x0001 | PR_ZERO0x0008);
949
950 error = cd_read_toc(sc, 0, 0, toc,
951 sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry),
952 0x40 /* control word for "get MS info" */);
953
954 if (error) {
955 dma_free(toc, sizeof(*toc));
956 break;
957 }
958
959 cte = &toc->entries[0];
960 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC)((sc->sc_link->quirks) & (0x0040))) {
961#if BYTE_ORDER1234 == BIG_ENDIAN4321
962 swap16_multi((u_int16_t *)&cte->addr,do { __size_t __swap16_multi_n = (sizeof(cte->addr) / 2); __uint16_t
*__swap16_multi_v = ((u_int16_t *)&cte->addr); while (
__swap16_multi_n) { *__swap16_multi_v = (__uint16_t)(__builtin_constant_p
(*__swap16_multi_v) ? (__uint16_t)(((__uint16_t)(*__swap16_multi_v
) & 0xffU) << 8 | ((__uint16_t)(*__swap16_multi_v) &
0xff00U) >> 8) : __swap16md(*__swap16_multi_v)); __swap16_multi_v
++; __swap16_multi_n--; } } while (0)
963 sizeof(cte->addr) / 2)do { __size_t __swap16_multi_n = (sizeof(cte->addr) / 2); __uint16_t
*__swap16_multi_v = ((u_int16_t *)&cte->addr); while (
__swap16_multi_n) { *__swap16_multi_v = (__uint16_t)(__builtin_constant_p
(*__swap16_multi_v) ? (__uint16_t)(((__uint16_t)(*__swap16_multi_v
) & 0xffU) << 8 | ((__uint16_t)(*__swap16_multi_v) &
0xff00U) >> 8) : __swap16md(*__swap16_multi_v)); __swap16_multi_v
++; __swap16_multi_n--; } } while (0)
;
964#endif /* BYTE_ORDER == BIG_ENDIAN */
965 } else
966 cte->addr.lba = betoh32(cte->addr.lba)(__uint32_t)(__builtin_constant_p(cte->addr.lba) ? (__uint32_t
)(((__uint32_t)(cte->addr.lba) & 0xff) << 24 | (
(__uint32_t)(cte->addr.lba) & 0xff00) << 8 | ((__uint32_t
)(cte->addr.lba) & 0xff0000) >> 8 | ((__uint32_t
)(cte->addr.lba) & 0xff000000) >> 24) : __swap32md
(cte->addr.lba))
;
967 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC)((sc->sc_link->quirks) & (0x0040)))
968 toc->header.len = letoh16(toc->header.len)((__uint16_t)(toc->header.len));
969 else
970 toc->header.len = betoh16(toc->header.len)(__uint16_t)(__builtin_constant_p(toc->header.len) ? (__uint16_t
)(((__uint16_t)(toc->header.len) & 0xffU) << 8 |
((__uint16_t)(toc->header.len) & 0xff00U) >> 8)
: __swap16md(toc->header.len))
;
971
972 *(int *)addr = (toc->header.len >= 10 && cte->track > 1) ?
973 cte->addr.lba : 0;
974 dma_free(toc, sizeof(*toc));
975 break;
976 }
977 case CDIOCSETPATCH((unsigned long)0x80000000 | ((sizeof(struct ioc_patch) &
0x1fff) << 16) | ((('c')) << 8) | ((9)))
: {
978 struct ioc_patch *arg = (struct ioc_patch *)addr;
979
980 error = cd_setchan(sc, arg->patch[0], arg->patch[1],
981 arg->patch[2], arg->patch[3], 0);
982 break;
983 }
984 case CDIOCGETVOL((unsigned long)0x40000000 | ((sizeof(struct ioc_vol) & 0x1fff
) << 16) | ((('c')) << 8) | ((10)))
: {
985 struct ioc_vol *arg = (struct ioc_vol *)addr;
986
987 error = cd_getvol(sc, arg, 0);
988 break;
989 }
990 case CDIOCSETVOL((unsigned long)0x80000000 | ((sizeof(struct ioc_vol) & 0x1fff
) << 16) | ((('c')) << 8) | ((11)))
: {
991 struct ioc_vol *arg = (struct ioc_vol *)addr;
992
993 error = cd_setvol(sc, arg, 0);
994 break;
995 }
996
997 case CDIOCSETMONO((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((12)))
:
998 error = cd_setchan(sc, BOTH_CHANNEL1 | 2, BOTH_CHANNEL1 | 2, MUTE_CHANNEL0x0,
999 MUTE_CHANNEL0x0, 0);
1000 break;
1001
1002 case CDIOCSETSTEREO((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((13)))
:
1003 error = cd_setchan(sc, LEFT_CHANNEL1, RIGHT_CHANNEL2,
1004 MUTE_CHANNEL0x0, MUTE_CHANNEL0x0, 0);
1005 break;
1006
1007 case CDIOCSETMUTE((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((14)))
:
1008 error = cd_setchan(sc, MUTE_CHANNEL0x0, MUTE_CHANNEL0x0, MUTE_CHANNEL0x0,
1009 MUTE_CHANNEL0x0, 0);
1010 break;
1011
1012 case CDIOCSETLEFT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((15)))
:
1013 error = cd_setchan(sc, LEFT_CHANNEL1, LEFT_CHANNEL1, MUTE_CHANNEL0x0,
1014 MUTE_CHANNEL0x0, 0);
1015 break;
1016
1017 case CDIOCSETRIGHT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((16)))
:
1018 error = cd_setchan(sc, RIGHT_CHANNEL2, RIGHT_CHANNEL2,
1019 MUTE_CHANNEL0x0, MUTE_CHANNEL0x0, 0);
1020 break;
1021
1022 case CDIOCRESUME((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((20)))
:
1023 error = cd_pause(sc, 1);
1024 break;
1025
1026 case CDIOCPAUSE((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((19)))
:
1027 error = cd_pause(sc, 0);
1028 break;
1029 case CDIOCSTART((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((22)))
:
1030 error = scsi_start(sc->sc_link, SSS_START0x01, 0);
1031 break;
1032
1033 case CDIOCSTOP((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((23)))
:
1034 error = scsi_start(sc->sc_link, SSS_STOP0x00, 0);
1035 break;
1036
1037close_tray:
1038 case CDIOCCLOSE((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((27)))
:
1039 error = scsi_start(sc->sc_link, SSS_START0x01|SSS_LOEJ0x02,
1040 SCSI_IGNORE_NOT_READY0x00040 | SCSI_IGNORE_MEDIA_CHANGE0x00080);
1041 break;
1042
1043 case MTIOCTOP((unsigned long)0x80000000 | ((sizeof(struct mtop) & 0x1fff
) << 16) | ((('m')) << 8) | ((1)))
:
1044 if (((struct mtop *)addr)->mt_op == MTRETEN8)
1045 goto close_tray;
1046 if (((struct mtop *)addr)->mt_op != MTOFFL6) {
1047 error = EIO5;
1048 break;
1049 }
1050 /* FALLTHROUGH */
1051 case CDIOCEJECT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((24)))
: /* FALLTHROUGH */
1052 case DIOCEJECT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('d')) << 8) | ((112)))
:
1053 SET(sc->sc_link->flags, SDEV_EJECTING)((sc->sc_link->flags) |= (0x0100));
1054 break;
1055 case CDIOCALLOW((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((25)))
:
1056 error = scsi_prevent(sc->sc_link, PR_ALLOW0x00, 0);
1057 break;
1058 case CDIOCPREVENT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((26)))
:
1059 error = scsi_prevent(sc->sc_link, PR_PREVENT0x01, 0);
1060 break;
1061 case DIOCLOCK((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('d')) << 8) | ((113)))
:
1062 error = scsi_prevent(sc->sc_link,
1063 (*(int *)addr) ? PR_PREVENT0x01 : PR_ALLOW0x00, 0);
1064 break;
1065 case CDIOCSETDEBUG((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((17)))
:
1066 SET(sc->sc_link->flags, SDEV_DB1 | SDEV_DB2)((sc->sc_link->flags) |= (0x0010 | 0x0020));
1067 break;
1068 case CDIOCCLRDEBUG((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((18)))
:
1069 CLR(sc->sc_link->flags, SDEV_DB1 | SDEV_DB2)((sc->sc_link->flags) &= ~(0x0010 | 0x0020));
1070 break;
1071 case CDIOCRESET((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('c')) << 8) | ((21)))
:
1072 case SCIOCRESET((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('Q')) << 8) | ((7)))
:
1073 error = cd_reset(sc);
1074 break;
1075 case CDIOCLOADUNLOAD((unsigned long)0x80000000 | ((sizeof(struct ioc_load_unload)
& 0x1fff) << 16) | ((('c')) << 8) | ((26)))
: {
1076 struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
1077
1078 error = cd_load_unload(sc, args->options, args->slot);
1079 break;
1080 }
1081
1082 case DVD_AUTH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(union dvd_authinfo) & 0x1fff) << 16) | ((('d')) <<
8) | ((2)))
:
1083 error = dvd_auth(sc, (union dvd_authinfo *)addr);
1084 break;
1085 case DVD_READ_STRUCT(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(union dvd_struct) & 0x1fff) << 16) | ((('d')) <<
8) | ((0)))
:
1086 error = dvd_read_struct(sc, (union dvd_struct *)addr);
1087 break;
1088 default:
1089 if (DISKPART(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) % 16)
!= RAW_PART2) {
1090 error = ENOTTY25;
1091 break;
1092 }
1093 error = scsi_do_ioctl(sc->sc_link, cmd, addr, flag);
1094 break;
1095 }
1096
1097exit:
1098
1099 device_unref(&sc->sc_dev);
1100 return error;
1101}
1102
1103/*
1104 * Load the label information on the named device
1105 * Actually fabricate a disklabel
1106 *
1107 * EVENTUALLY take information about different
1108 * data tracks from the TOC and put it in the disklabel
1109 */
1110int
1111cdgetdisklabel(dev_t dev, struct cd_softc *sc, struct disklabel *lp,
1112 int spoofonly)
1113{
1114 struct cd_toc *toc;
1115 int tocidx, n, audioonly = 1;
1116
1117 bzero(lp, sizeof(struct disklabel))__builtin_bzero((lp), (sizeof(struct disklabel)));
1118
1119 lp->d_secsize = sc->params.secsize;
1120 lp->d_ntracks = 1;
1121 lp->d_nsectors = 100;
1122 lp->d_secpercyl = 100;
1123 lp->d_ncylinders = (sc->params.disksize / 100) + 1;
1124
1125 if (ISSET(sc->sc_link->flags, SDEV_ATAPI)((sc->sc_link->flags) & (0x0200))) {
1126 strncpy(lp->d_typename, "ATAPI CD-ROM", sizeof(lp->d_typename));
1127 lp->d_type = DTYPE_ATAPI13;
1128 } else {
1129 strncpy(lp->d_typename, "SCSI CD-ROM", sizeof(lp->d_typename));
1130 lp->d_type = DTYPE_SCSI4;
1131 }
1132
1133 strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
1134 DL_SETDSIZE(lp, sc->params.disksize)do { u_int64_t __x = (sc->params.disksize); (lp)->d_secperunith
= __x >> 32; (lp)->d_secperunit = __x; } while (0)
;
1135 lp->d_version = 1;
1136
1137 /* XXX - these values for BBSIZE and SBSIZE assume ffs */
1138 lp->d_bbsize = BBSIZE8192;
1139 lp->d_sbsize = SBSIZE8192;
1140
1141 lp->d_magic = DISKMAGIC((u_int32_t)0x82564557);
1142 lp->d_magic2 = DISKMAGIC((u_int32_t)0x82564557);
1143 lp->d_checksum = dkcksum(lp);
1144
1145 toc = dma_alloc(sizeof(*toc), PR_WAITOK0x0001 | PR_ZERO0x0008);
1146 if (cd_load_toc(sc, toc, CD_LBA_FORMAT1)) {
1147 audioonly = 0; /* No valid TOC found == not an audio CD. */
1148 goto done;
1149 }
1150
1151 n = toc->header.ending_track - toc->header.starting_track + 1;
1152 for (tocidx = 0; tocidx < n; tocidx++)
1153 if (toc->entries[tocidx].control & 4) {
1154 audioonly = 0; /* Found a non-audio track. */
1155 goto done;
1156 }
1157
1158done:
1159 dma_free(toc, sizeof(*toc));
1160
1161 if (audioonly)
1162 return 0;
1163 return readdisklabel(DISKLABELDEV(dev)((((dev_t)((((((((unsigned)(dev) >> 8) & 0xff))) &
0xff) << 8) | (((((((((unsigned)((dev) & 0xff) | (
((dev) & 0xffff0000) >> 8)) / 16))) * 16) + ((2))))
& 0xff) | ((((((((((unsigned)((dev) & 0xff) | (((dev
) & 0xffff0000) >> 8)) / 16))) * 16) + ((2)))) &
0xffff00) << 8)))))
, cdstrategy, lp, spoofonly);
1164}
1165
1166int
1167cd_setchan(struct cd_softc *sc, int p0, int p1, int p2, int p3, int flags)
1168{
1169 union scsi_mode_sense_buf *data;
1170 struct cd_audio_page *audio = NULL((void *)0);
1171 int error, big;
1172
1173 data = dma_alloc(sizeof(*data), PR_NOWAIT0x0002);
1174 if (data == NULL((void *)0))
1175 return ENOMEM12;
1176
1177 error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE0x0e, data,
1178 (void **)&audio, sizeof(*audio), flags, &big);
1179 if (error == 0 && audio == NULL((void *)0))
1180 error = EIO5;
1181
1182 if (error == 0) {
1183 audio->port[LEFT_PORT0].channels = p0;
1184 audio->port[RIGHT_PORT1].channels = p1;
1185 audio->port[2].channels = p2;
1186 audio->port[3].channels = p3;
1187 if (big)
1188 error = scsi_mode_select_big(sc->sc_link, SMS_PF0x10,
1189 &data->hdr_big, flags, 20000);
1190 else
1191 error = scsi_mode_select(sc->sc_link, SMS_PF0x10,
1192 &data->hdr, flags, 20000);
1193 }
1194
1195 dma_free(data, sizeof(*data));
1196 return error;
1197}
1198
1199int
1200cd_getvol(struct cd_softc *sc, struct ioc_vol *arg, int flags)
1201{
1202 union scsi_mode_sense_buf *data;
1203 struct cd_audio_page *audio = NULL((void *)0);
1204 int big, error;
1205
1206 data = dma_alloc(sizeof(*data), PR_NOWAIT0x0002);
1207 if (data == NULL((void *)0))
1208 return ENOMEM12;
1209
1210 error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE0x0e, data,
1211 (void **)&audio, sizeof(*audio), flags, &big);
1212 if (error == 0 && audio == NULL((void *)0))
1213 error = EIO5;
1214
1215 if (error == 0) {
1216 arg->vol[0] = audio->port[0].volume;
1217 arg->vol[1] = audio->port[1].volume;
1218 arg->vol[2] = audio->port[2].volume;
1219 arg->vol[3] = audio->port[3].volume;
1220 }
1221
1222 dma_free(data, sizeof(*data));
1223 return 0;
1224}
1225
1226int
1227cd_setvol(struct cd_softc *sc, const struct ioc_vol *arg, int flags)
1228{
1229 union scsi_mode_sense_buf *data;
1230 struct cd_audio_page *audio = NULL((void *)0);
1231 u_int8_t mask_volume[4];
1232 int error, big;
1233
1234 data = dma_alloc(sizeof(*data), PR_NOWAIT0x0002);
1235 if (data == NULL((void *)0))
1236 return ENOMEM12;
1237
1238 error = scsi_do_mode_sense(sc->sc_link,
1239 AUDIO_PAGE0x0e | SMS_PAGE_CTRL_CHANGEABLE0x40, data, (void **)&audio,
1240 sizeof(*audio), flags, &big);
1241 if (error == 0 && audio == NULL((void *)0))
1242 error = EIO5;
1243 if (error != 0) {
1244 dma_free(data, sizeof(*data));
1245 return error;
1246 }
1247
1248 mask_volume[0] = audio->port[0].volume;
1249 mask_volume[1] = audio->port[1].volume;
1250 mask_volume[2] = audio->port[2].volume;
1251 mask_volume[3] = audio->port[3].volume;
1252
1253 error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE0x0e, data,
1254 (void **)&audio, sizeof(*audio), flags, &big);
1255 if (error == 0 && audio == NULL((void *)0))
1256 error = EIO5;
1257 if (error != 0) {
1258 dma_free(data, sizeof(*data));
1259 return error;
1260 }
1261
1262 audio->port[0].volume = arg->vol[0] & mask_volume[0];
1263 audio->port[1].volume = arg->vol[1] & mask_volume[1];
1264 audio->port[2].volume = arg->vol[2] & mask_volume[2];
1265 audio->port[3].volume = arg->vol[3] & mask_volume[3];
1266
1267 if (big)
1268 error = scsi_mode_select_big(sc->sc_link, SMS_PF0x10,
1269 &data->hdr_big, flags, 20000);
1270 else
1271 error = scsi_mode_select(sc->sc_link, SMS_PF0x10,
1272 &data->hdr, flags, 20000);
1273
1274 dma_free(data, sizeof(*data));
1275 return error;
1276}
1277
1278int
1279cd_load_unload(struct cd_softc *sc, int options, int slot)
1280{
1281 struct scsi_load_unload *cmd;
1282 struct scsi_xfer *xs;
1283 int error;
1284
1285 xs = scsi_xs_get(sc->sc_link, 0);
1286 if (xs == NULL((void *)0))
1287 return ENOMEM12;
1288 xs->cmdlen = sizeof(*cmd);
1289 xs->timeout = 200000;
1290
1291 cmd = (struct scsi_load_unload *)&xs->cmd;
1292 cmd->opcode = LOAD_UNLOAD0xa6;
1293 cmd->options = options; /* ioctl uses ATAPI values */
1294 cmd->slot = slot;
1295
1296 error = scsi_xs_sync(xs);
1297 scsi_xs_put(xs);
1298
1299 return error;
1300}
1301
1302int
1303cd_set_pa_immed(struct cd_softc *sc, int flags)
1304{
1305 union scsi_mode_sense_buf *data;
1306 struct cd_audio_page *audio = NULL((void *)0);
1307 int error, oflags, big;
1308
1309 if (ISSET(sc->sc_link->flags, SDEV_ATAPI)((sc->sc_link->flags) & (0x0200)))
1310 /* XXX Noop? */
1311 return 0;
1312
1313 data = dma_alloc(sizeof(*data), PR_NOWAIT0x0002);
1314 if (data == NULL((void *)0))
1315 return ENOMEM12;
1316
1317 error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE0x0e, data,
1318 (void **)&audio, sizeof(*audio), flags, &big);
1319 if (error == 0 && audio == NULL((void *)0))
1320 error = EIO5;
1321
1322 if (error == 0) {
1323 oflags = audio->flags;
1324 CLR(audio->flags, CD_PA_SOTC)((audio->flags) &= ~(0x02));
1325 SET(audio->flags, CD_PA_IMMED)((audio->flags) |= (0x04));
1326 if (audio->flags != oflags) {
1327 if (big)
1328 error = scsi_mode_select_big(sc->sc_link,
1329 SMS_PF0x10, &data->hdr_big, flags, 20000);
1330 else
1331 error = scsi_mode_select(sc->sc_link, SMS_PF0x10,
1332 &data->hdr, flags, 20000);
1333 }
1334 }
1335
1336 dma_free(data, sizeof(*data));
1337 return error;
1338}
1339
1340/*
1341 * Get scsi driver to send a "start playing" command
1342 */
1343int
1344cd_play(struct cd_softc *sc, int secno, int nsecs)
1345{
1346 struct scsi_play *cmd;
1347 struct scsi_xfer *xs;
1348 int error;
1349
1350 xs = scsi_xs_get(sc->sc_link, 0);
1351 if (xs == NULL((void *)0))
1352 return ENOMEM12;
1353 xs->cmdlen = sizeof(*cmd);
1354 xs->timeout = 200000;
1355
1356 cmd = (struct scsi_play *)&xs->cmd;
1357 cmd->opcode = PLAY0x45;
1358 _lto4b(secno, cmd->blk_addr);
1359 _lto2b(nsecs, cmd->xfer_len);
1360
1361 error = scsi_xs_sync(xs);
1362 scsi_xs_put(xs);
1363
1364 return error;
1365}
1366
1367/*
1368 * Get scsi driver to send a "start playing" command
1369 */
1370int
1371cd_play_tracks(struct cd_softc *sc, int strack, int sindex, int etrack,
1372 int eindex)
1373{
1374 struct cd_toc *toc;
1375 int error;
1376 u_char endf, ends, endm;
1377
1378 if (!etrack)
1379 return EIO5;
1380 if (strack > etrack)
1381 return EINVAL22;
1382
1383 toc = dma_alloc(sizeof(*toc), PR_WAITOK0x0001 | PR_ZERO0x0008);
1384
1385 if ((error = cd_load_toc(sc, toc, CD_MSF_FORMAT2)) != 0)
1386 goto done;
1387
1388 if (++etrack > (toc->header.ending_track+1))
1389 etrack = toc->header.ending_track+1;
1390
1391 strack -= toc->header.starting_track;
1392 etrack -= toc->header.starting_track;
1393 if (strack < 0) {
1394 error = EINVAL22;
1395 goto done;
1396 }
1397
1398 /*
1399 * The track ends one frame before the next begins. The last track
1400 * is taken care of by the leadoff track.
1401 */
1402 endm = toc->entries[etrack].addr.msf.minute;
1403 ends = toc->entries[etrack].addr.msf.second;
1404 endf = toc->entries[etrack].addr.msf.frame;
1405 if (endf-- == 0) {
1406 endf = CD_FRAMES75 - 1;
1407 if (ends-- == 0) {
1408 ends = CD_SECS60 - 1;
1409 if (endm-- == 0) {
1410 error = EINVAL22;
1411 goto done;
1412 }
1413 }
1414 }
1415
1416 error = cd_play_msf(sc, toc->entries[strack].addr.msf.minute,
1417 toc->entries[strack].addr.msf.second,
1418 toc->entries[strack].addr.msf.frame,
1419 endm, ends, endf);
1420
1421done:
1422 dma_free(toc, sizeof(*toc));
1423 return error;
1424}
1425
1426/*
1427 * Get scsi driver to send a "play msf" command
1428 */
1429int
1430cd_play_msf(struct cd_softc *sc, int startm, int starts, int startf, int endm,
1431 int ends, int endf)
1432{
1433 struct scsi_play_msf *cmd;
1434 struct scsi_xfer *xs;
1435 int error;
1436
1437 xs = scsi_xs_get(sc->sc_link, 0);
1438 if (xs == NULL((void *)0))
1439 return ENOMEM12;
1440 xs->cmdlen = sizeof(*cmd);
1441 xs->timeout = 20000;
1442
1443 cmd = (struct scsi_play_msf *)&xs->cmd;
1444 cmd->opcode = PLAY_MSF0x47;
1445 cmd->start_m = startm;
1446 cmd->start_s = starts;
1447 cmd->start_f = startf;
1448 cmd->end_m = endm;
1449 cmd->end_s = ends;
1450 cmd->end_f = endf;
1451
1452 error = scsi_xs_sync(xs);
1453 scsi_xs_put(xs);
1454
1455 return error;
1456}
1457
1458/*
1459 * Get scsi driver to send a "start up" command
1460 */
1461int
1462cd_pause(struct cd_softc *sc, int go)
1463{
1464 struct scsi_pause *cmd;
1465 struct scsi_xfer *xs;
1466 int error;
1467
1468 xs = scsi_xs_get(sc->sc_link, 0);
1469 if (xs == NULL((void *)0))
1470 return ENOMEM12;
1471 xs->cmdlen = sizeof(*cmd);
1472 xs->timeout = 2000;
1473
1474 cmd = (struct scsi_pause *)&xs->cmd;
1475 cmd->opcode = PAUSE0x4b;
1476 cmd->resume = go;
1477
1478 error = scsi_xs_sync(xs);
1479 scsi_xs_put(xs);
1480
1481 return error;
1482}
1483
1484/*
1485 * Get scsi driver to send a "RESET" command
1486 */
1487int
1488cd_reset(struct cd_softc *sc)
1489{
1490 struct scsi_xfer *xs;
1491 int error;
1492
1493 xs = scsi_xs_get(sc->sc_link, SCSI_RESET0x00200);
1494 if (xs == NULL((void *)0))
1495 return ENOMEM12;
1496
1497 xs->timeout = 2000;
1498
1499 error = scsi_xs_sync(xs);
1500 scsi_xs_put(xs);
1501
1502 return error;
1503}
1504
1505/*
1506 * Read subchannel
1507 */
1508int
1509cd_read_subchannel(struct cd_softc *sc, int mode, int format, int track,
1510 struct cd_sub_channel_info *data, int len)
1511{
1512 struct scsi_read_subchannel *cmd;
1513 struct scsi_xfer *xs;
1514 int error;
1515
1516 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800 | SCSI_SILENT0x00020);
1517 if (xs == NULL((void *)0))
1518 return ENOMEM12;
1519 xs->cmdlen = sizeof(*cmd);
1520 xs->data = (void *)data;
1521 xs->datalen = len;
1522 xs->timeout = 5000;
1523
1524 cmd = (struct scsi_read_subchannel *)&xs->cmd;
1525 cmd->opcode = READ_SUBCHANNEL0x42;
1526 if (mode == CD_MSF_FORMAT2)
1527 SET(cmd->byte2, CD_MSF)((cmd->byte2) |= (0x02));
1528 cmd->byte3 = SRS_SUBQ0x40;
1529 cmd->subchan_format = format;
1530 cmd->track = track;
1531 _lto2b(len, cmd->data_len);
1532
1533 error = scsi_xs_sync(xs);
1534 scsi_xs_put(xs);
1535
1536 return error;
1537}
1538
1539/*
1540 * Read table of contents
1541 */
1542int
1543cd_read_toc(struct cd_softc *sc, int mode, int start, void *data, int len,
1544 int control)
1545{
1546 struct scsi_read_toc *cmd;
1547 struct scsi_xfer *xs;
1548 int error;
1549
1550 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800 |
1551 SCSI_IGNORE_ILLEGAL_REQUEST0x00100);
1552 if (xs == NULL((void *)0))
1553 return ENOMEM12;
1554 xs->cmdlen = sizeof(*cmd);
1555 xs->data = data;
1556 xs->datalen = len;
1557 xs->timeout = 5000;
1558
1559 bzero(data, len)__builtin_bzero((data), (len));
1560
1561 cmd = (struct scsi_read_toc *)&xs->cmd;
1562 cmd->opcode = READ_TOC0x43;
1563
1564 if (mode == CD_MSF_FORMAT2)
1565 SET(cmd->byte2, CD_MSF)((cmd->byte2) |= (0x02));
1566 cmd->from_track = start;
1567 _lto2b(len, cmd->data_len);
1568 cmd->control = control;
1569
1570 error = scsi_xs_sync(xs);
1571 scsi_xs_put(xs);
1572
1573 return error;
1574}
1575
1576int
1577cd_load_toc(struct cd_softc *sc, struct cd_toc *toc, int fmt)
1578{
1579 int n, len, error;
1580
1581 error = cd_read_toc(sc, 0, 0, toc, sizeof(toc->header), 0);
1582
1583 if (error == 0) {
1584 if (toc->header.ending_track < toc->header.starting_track)
1585 return EIO5;
1586 /* +2 to account for leading out track. */
1587 n = toc->header.ending_track - toc->header.starting_track + 2;
1588 len = n * sizeof(struct cd_toc_entry) + sizeof(toc->header);
1589 error = cd_read_toc(sc, fmt, 0, toc, len, 0);
1590 }
1591
1592 return error;
1593}
1594
1595
1596/*
1597 * Get the scsi driver to send a full inquiry to the device and use the
1598 * results to fill out the disk parameter structure.
1599 */
1600int
1601cd_get_parms(struct cd_softc *sc, int flags)
1602{
1603 /* Reasonable defaults for drives that don't support READ_CAPACITY */
1604 sc->params.secsize = 2048;
1605 sc->params.disksize = 400000;
1606
1607 if (ISSET(sc->sc_link->quirks, ADEV_NOCAPACITY)((sc->sc_link->quirks) & (0x0080)))
1608 return 0;
1609
1610 sc->params.disksize = cd_size(sc->sc_link, flags, &sc->params.secsize);
1611
1612 if ((sc->params.secsize < 512) ||
1613 ((sc->params.secsize & 511) != 0))
1614 sc->params.secsize = 2048; /* some drives lie ! */
1615
1616 if (sc->params.disksize < 100)
1617 sc->params.disksize = 400000;
1618
1619 return 0;
1620}
1621
1622daddr_t
1623cdsize(dev_t dev)
1624{
1625 /* CD-ROMs are read-only. */
1626 return -1;
1627}
1628
1629int
1630cddump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
1631{
1632 /* Not implemented. */
1633 return ENXIO6;
1634}
1635
1636#define dvd_copy_key(dst, src)__builtin_memcpy(((dst)), ((src)), (5)) memcpy((dst), (src), DVD_KEY_SIZE)__builtin_memcpy(((dst)), ((src)), (5))
1637#define dvd_copy_challenge(dst, src)__builtin_memcpy(((dst)), ((src)), (10)) memcpy((dst), (src), DVD_CHALLENGE_SIZE)__builtin_memcpy(((dst)), ((src)), (10))
1638
1639#define DVD_AUTH_BUFSIZE20 20
1640
1641int
1642dvd_auth(struct cd_softc *sc, union dvd_authinfo *a)
1643{
1644 struct scsi_generic *cmd;
1645 struct scsi_xfer *xs;
1646 u_int8_t *buf;
1647 int error;
1648
1649 buf = dma_alloc(DVD_AUTH_BUFSIZE20, PR_WAITOK0x0001 | PR_ZERO0x0008);
1650 if (buf == NULL((void *)0))
1651 return ENOMEM12;
1652
1653 xs = scsi_xs_get(sc->sc_link, 0);
1654 if (xs == NULL((void *)0)) {
1655 error = ENOMEM12;
1656 goto done;
1657 }
1658 xs->cmdlen = sizeof(*cmd);
1659 xs->timeout = 30000;
1660 xs->data = buf;
1661
1662 cmd = &xs->cmd;
1663
1664 switch (a->type) {
1665 case DVD_LU_SEND_AGID0:
1666 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1667 cmd->bytes[8] = 8;
1668 cmd->bytes[9] = 0 | (0 << 6);
1669 xs->datalen = 8;
1670 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
1671
1672 error = scsi_xs_sync(xs);
1673 scsi_xs_put(xs);
1674
1675 if (error == 0)
1676 a->lsa.agid = buf[7] >> 6;
1677 break;
1678
1679 case DVD_LU_SEND_CHALLENGE3:
1680 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1681 cmd->bytes[8] = 16;
1682 cmd->bytes[9] = 1 | (a->lsc.agid << 6);
1683 xs->datalen = 16;
1684 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
1685
1686 error = scsi_xs_sync(xs);
1687 scsi_xs_put(xs);
1688 if (error == 0)
1689 dvd_copy_challenge(a->lsc.chal, &buf[4])__builtin_memcpy(((a->lsc.chal)), ((&buf[4])), (10));
1690 break;
1691
1692 case DVD_LU_SEND_KEY12:
1693 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1694 cmd->bytes[8] = 12;
1695 cmd->bytes[9] = 2 | (a->lsk.agid << 6);
1696 xs->datalen = 12;
1697 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
1698
1699 error = scsi_xs_sync(xs);
1700 scsi_xs_put(xs);
1701
1702 if (error == 0)
1703 dvd_copy_key(a->lsk.key, &buf[4])__builtin_memcpy(((a->lsk.key)), ((&buf[4])), (5));
1704 break;
1705
1706 case DVD_LU_SEND_TITLE_KEY7:
1707 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1708 _lto4b(a->lstk.lba, &cmd->bytes[1]);
1709 cmd->bytes[8] = 12;
1710 cmd->bytes[9] = 4 | (a->lstk.agid << 6);
1711 xs->datalen = 12;
1712 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
1713
1714 error = scsi_xs_sync(xs);
1715 scsi_xs_put(xs);
1716
1717 if (error == 0) {
1718 a->lstk.cpm = (buf[4] >> 7) & 1;
1719 a->lstk.cp_sec = (buf[4] >> 6) & 1;
1720 a->lstk.cgms = (buf[4] >> 4) & 3;
1721 dvd_copy_key(a->lstk.title_key, &buf[5])__builtin_memcpy(((a->lstk.title_key)), ((&buf[5])), (
5))
;
1722 }
1723 break;
1724
1725 case DVD_LU_SEND_ASF8:
1726 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1727 cmd->bytes[8] = 8;
1728 cmd->bytes[9] = 5 | (a->lsasf.agid << 6);
1729 xs->datalen = 8;
1730 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
1731
1732 error = scsi_xs_sync(xs);
1733 scsi_xs_put(xs);
1734
1735 if (error == 0)
1736 a->lsasf.asf = buf[7] & 1;
1737 break;
1738
1739 case DVD_HOST_SEND_CHALLENGE1:
1740 cmd->opcode = GPCMD_SEND_KEY0xa3;
1741 cmd->bytes[8] = 16;
1742 cmd->bytes[9] = 1 | (a->hsc.agid << 6);
1743 buf[1] = 14;
1744 dvd_copy_challenge(&buf[4], a->hsc.chal)__builtin_memcpy(((&buf[4])), ((a->hsc.chal)), (10));
1745 xs->datalen = 16;
1746 SET(xs->flags, SCSI_DATA_OUT)((xs->flags) |= (0x01000));
1747
1748 error = scsi_xs_sync(xs);
1749 scsi_xs_put(xs);
1750
1751 if (error == 0)
1752 a->type = DVD_LU_SEND_KEY12;
1753 break;
1754
1755 case DVD_HOST_SEND_KEY24:
1756 cmd->opcode = GPCMD_SEND_KEY0xa3;
1757 cmd->bytes[8] = 12;
1758 cmd->bytes[9] = 3 | (a->hsk.agid << 6);
1759 buf[1] = 10;
1760 dvd_copy_key(&buf[4], a->hsk.key)__builtin_memcpy(((&buf[4])), ((a->hsk.key)), (5));
1761 xs->datalen = 12;
1762 SET(xs->flags, SCSI_DATA_OUT)((xs->flags) |= (0x01000));
1763
1764 error = scsi_xs_sync(xs);
1765 scsi_xs_put(xs);
1766
1767 if (error == 0)
1768 a->type = DVD_AUTH_ESTABLISHED5;
1769 else
1770 a->type = DVD_AUTH_FAILURE6;
1771 break;
1772
1773 case DVD_INVALIDATE_AGID9:
1774 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1775 cmd->bytes[9] = 0x3f | (a->lsa.agid << 6);
1776 xs->data = NULL((void *)0);
1777
1778 error = scsi_xs_sync(xs);
1779 scsi_xs_put(xs);
1780 break;
1781
1782 case DVD_LU_SEND_RPC_STATE10:
1783 cmd->opcode = GPCMD_REPORT_KEY0xa4;
1784 cmd->bytes[8] = 8;
1785 cmd->bytes[9] = 8 | (0 << 6);
1786 xs->datalen = 8;
1787 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
1788
1789 error = scsi_xs_sync(xs);
1790 scsi_xs_put(xs);
1791
1792 if (error == 0) {
1793 a->lrpcs.type = (buf[4] >> 6) & 3;
1794 a->lrpcs.vra = (buf[4] >> 3) & 7;
1795 a->lrpcs.ucca = (buf[4]) & 7;
1796 a->lrpcs.region_mask = buf[5];
1797 a->lrpcs.rpc_scheme = buf[6];
1798 }
1799 break;
1800
1801 case DVD_HOST_SEND_RPC_STATE11:
1802 cmd->opcode = GPCMD_SEND_KEY0xa3;
1803 cmd->bytes[8] = 8;
1804 cmd->bytes[9] = 6 | (0 << 6);
1805 buf[1] = 6;
1806 buf[4] = a->hrpcs.pdrc;
1807 xs->datalen = 8;
1808 SET(xs->flags, SCSI_DATA_OUT)((xs->flags) |= (0x01000));
1809
1810 error = scsi_xs_sync(xs);
1811 scsi_xs_put(xs);
1812 break;
1813
1814 default:
1815 scsi_xs_put(xs);
1816 error = ENOTTY25;
1817 break;
1818 }
1819done:
1820 dma_free(buf, DVD_AUTH_BUFSIZE20);
1821 return error;
1822}
1823
1824#define DVD_READ_PHYSICAL_BUFSIZE(4 + 4 * 20) (4 + 4 * 20)
1825int
1826dvd_read_physical(struct cd_softc *sc, union dvd_struct *s)
1827{
1828 struct scsi_generic *cmd;
1829 struct dvd_layer *layer;
1830 struct scsi_xfer *xs;
1831 u_int8_t *buf, *bufp;
1832 int error, i;
1833
1834 buf = dma_alloc(DVD_READ_PHYSICAL_BUFSIZE(4 + 4 * 20), PR_WAITOK0x0001 | PR_ZERO0x0008);
1835 if (buf == NULL((void *)0))
1836 return ENOMEM12;
1837
1838 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800);
1839 if (xs == NULL((void *)0)) {
1840 error = ENOMEM12;
1841 goto done;
1842 }
1843 xs->cmdlen = sizeof(*cmd);
1844 xs->data = buf;
1845 xs->datalen = DVD_READ_PHYSICAL_BUFSIZE(4 + 4 * 20);
1846 xs->timeout = 30000;
1847
1848 cmd = &xs->cmd;
1849 cmd->opcode = GPCMD_READ_DVD_STRUCTURE0xad;
1850 cmd->bytes[6] = s->type;
1851 _lto2b(xs->datalen, &cmd->bytes[7]);
1852
1853 cmd->bytes[5] = s->physical.layer_num;
1854
1855 error = scsi_xs_sync(xs);
1856 scsi_xs_put(xs);
1857
1858 if (error == 0) {
1859 for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0];
1860 i < 4; i++, bufp += 20, layer++) {
1861 bzero(layer, sizeof(*layer))__builtin_bzero((layer), (sizeof(*layer)));
1862 layer->book_version = bufp[0] & 0xf;
1863 layer->book_type = bufp[0] >> 4;
1864 layer->min_rate = bufp[1] & 0xf;
1865 layer->disc_size = bufp[1] >> 4;
1866 layer->layer_type = bufp[2] & 0xf;
1867 layer->track_path = (bufp[2] >> 4) & 1;
1868 layer->nlayers = (bufp[2] >> 5) & 3;
1869 layer->track_density = bufp[3] & 0xf;
1870 layer->linear_density = bufp[3] >> 4;
1871 layer->start_sector = _4btol(&bufp[4]);
1872 layer->end_sector = _4btol(&bufp[8]);
1873 layer->end_sector_l0 = _4btol(&bufp[12]);
1874 layer->bca = bufp[16] >> 7;
1875 }
1876 }
1877done:
1878 dma_free(buf, DVD_READ_PHYSICAL_BUFSIZE(4 + 4 * 20));
1879 return error;
1880}
1881
1882#define DVD_READ_COPYRIGHT_BUFSIZE8 8
1883int
1884dvd_read_copyright(struct cd_softc *sc, union dvd_struct *s)
1885{
1886 struct scsi_generic *cmd;
1887 struct scsi_xfer *xs;
1888 u_int8_t *buf;
1889 int error;
1890
1891 buf = dma_alloc(DVD_READ_COPYRIGHT_BUFSIZE8, PR_WAITOK0x0001 | PR_ZERO0x0008);
1892 if (buf == NULL((void *)0))
1893 return ENOMEM12;
1894
1895 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800);
1896 if (xs == NULL((void *)0)) {
1897 error = ENOMEM12;
1898 goto done;
1899 }
1900 xs->cmdlen = sizeof(*cmd);
1901 xs->data = buf;
1902 xs->datalen = DVD_READ_COPYRIGHT_BUFSIZE8;
1903 xs->timeout = 30000;
1904
1905 cmd = &xs->cmd;
1906 cmd->opcode = GPCMD_READ_DVD_STRUCTURE0xad;
1907 cmd->bytes[6] = s->type;
1908 _lto2b(xs->datalen, &cmd->bytes[7]);
1909
1910 cmd->bytes[5] = s->copyright.layer_num;
1911
1912 error = scsi_xs_sync(xs);
1913 scsi_xs_put(xs);
1914
1915 if (error == 0) {
1916 s->copyright.cpst = buf[4];
1917 s->copyright.rmi = buf[5];
1918 }
1919done:
1920 dma_free(buf, DVD_READ_COPYRIGHT_BUFSIZE8);
1921 return error;
1922}
1923
1924int
1925dvd_read_disckey(struct cd_softc *sc, union dvd_struct *s)
1926{
1927 struct scsi_read_dvd_structure_data *buf;
1928 struct scsi_read_dvd_structure *cmd;
1929 struct scsi_xfer *xs;
1930 int error;
1931
1932 buf = dma_alloc(sizeof(*buf), PR_WAITOK0x0001 | PR_ZERO0x0008);
1933 if (buf == NULL((void *)0))
1934 return ENOMEM12;
1935
1936 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800);
1937 if (xs == NULL((void *)0)) {
1938 error = ENOMEM12;
1939 goto done;
1940 }
1941 xs->cmdlen = sizeof(*cmd);
1942 xs->data = (void *)buf;
1943 xs->datalen = sizeof(*buf);
1944 xs->timeout = 30000;
1945
1946 cmd = (struct scsi_read_dvd_structure *)&xs->cmd;
1947 cmd->opcode = GPCMD_READ_DVD_STRUCTURE0xad;
1948 cmd->format = s->type;
1949 cmd->agid = s->disckey.agid << 6;
1950 _lto2b(xs->datalen, cmd->length);
1951
1952 error = scsi_xs_sync(xs);
1953 scsi_xs_put(xs);
1954
1955 if (error == 0)
1956 memcpy(s->disckey.value, buf->data, sizeof(s->disckey.value))__builtin_memcpy((s->disckey.value), (buf->data), (sizeof
(s->disckey.value)))
;
1957done:
1958 dma_free(buf, sizeof(*buf));
1959 return error;
1960}
1961
1962#define DVD_READ_BCA_BUFLEN(4 + 188) (4 + 188)
1963
1964int
1965dvd_read_bca(struct cd_softc *sc, union dvd_struct *s)
1966{
1967 struct scsi_generic *cmd;
1968 struct scsi_xfer *xs;
1969 u_int8_t *buf;
1970 int error;
1971
1972 buf = dma_alloc(DVD_READ_BCA_BUFLEN(4 + 188), PR_WAITOK0x0001 | PR_ZERO0x0008);
1973 if (buf == NULL((void *)0))
1974 return ENOMEM12;
1975
1976 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800);
1977 if (xs == NULL((void *)0)) {
1978 error = ENOMEM12;
1979 goto done;
1980 }
1981 xs->cmdlen = sizeof(*cmd);
1982 xs->data = buf;
1983 xs->datalen = DVD_READ_BCA_BUFLEN(4 + 188);
1984 xs->timeout = 30000;
1985
1986 cmd = &xs->cmd;
1987 cmd->opcode = GPCMD_READ_DVD_STRUCTURE0xad;
1988 cmd->bytes[6] = s->type;
1989 _lto2b(xs->datalen, &cmd->bytes[7]);
1990
1991 error = scsi_xs_sync(xs);
1992 scsi_xs_put(xs);
1993
1994 if (error == 0) {
1995 s->bca.len = _2btol(&buf[0]);
1996 if (s->bca.len < 12 || s->bca.len > 188)
1997 return EIO5;
1998 memcpy(s->bca.value, &buf[4], s->bca.len)__builtin_memcpy((s->bca.value), (&buf[4]), (s->bca
.len))
;
1999 }
2000done:
2001 dma_free(buf, DVD_READ_BCA_BUFLEN(4 + 188));
2002 return error;
2003}
2004
2005int
2006dvd_read_manufact(struct cd_softc *sc, union dvd_struct *s)
2007{
2008 struct scsi_read_dvd_structure_data *buf;
2009 struct scsi_read_dvd_structure *cmd;
2010 struct scsi_xfer *xs;
2011 int error;
2012
2013 buf = dma_alloc(sizeof(*buf), PR_WAITOK0x0001 | PR_ZERO0x0008);
2014 if (buf == NULL((void *)0))
2015 return ENOMEM12;
2016
2017 xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN0x00800);
2018 if (xs == NULL((void *)0)) {
2019 error = ENOMEM12;
2020 goto done;
2021 }
2022 xs->cmdlen = sizeof(*cmd);
2023 xs->data = (void *)buf;
2024 xs->datalen = sizeof(*buf);
2025 xs->timeout = 30000;
2026
2027 cmd = (struct scsi_read_dvd_structure *)&xs->cmd;
2028 cmd->opcode = GPCMD_READ_DVD_STRUCTURE0xad;
2029 cmd->format = s->type;
2030 _lto2b(xs->datalen, cmd->length);
2031
2032 error = scsi_xs_sync(xs);
2033 scsi_xs_put(xs);
2034
2035 if (error == 0) {
2036 s->manufact.len = _2btol(buf->len);
2037 if (s->manufact.len >= 0 && s->manufact.len <= 2048)
2038 memcpy(s->manufact.value, buf->data, s->manufact.len)__builtin_memcpy((s->manufact.value), (buf->data), (s->
manufact.len))
;
2039 else
2040 error = EIO5;
2041 }
2042done:
2043 dma_free(buf, sizeof(*buf));
2044 return error;
2045}
2046
2047int
2048dvd_read_struct(struct cd_softc *sc, union dvd_struct *s)
2049{
2050 switch (s->type) {
2051 case DVD_STRUCT_PHYSICAL0x00:
2052 return dvd_read_physical(sc, s);
2053 case DVD_STRUCT_COPYRIGHT0x01:
2054 return dvd_read_copyright(sc, s);
2055 case DVD_STRUCT_DISCKEY0x02:
2056 return dvd_read_disckey(sc, s);
2057 case DVD_STRUCT_BCA0x03:
2058 return dvd_read_bca(sc, s);
2059 case DVD_STRUCT_MANUFACT0x04:
2060 return dvd_read_manufact(sc, s);
2061 default:
2062 return EINVAL22;
2063 }
2064}
2065
2066int
2067cd_interpret_sense(struct scsi_xfer *xs)
2068{
2069 struct scsi_sense_data *sense = &xs->sense;
2070 struct scsi_link *link = xs->sc_link;
2071 u_int8_t skey = sense->flags & SSD_KEY0x0F;
2072 u_int8_t serr = sense->error_code & SSD_ERRCODE0x7F;
2073
2074 if (!ISSET(link->flags, SDEV_OPEN)((link->flags) & (0x0008)) ||
2075 (serr != SSD_ERRCODE_CURRENT0x70 && serr != SSD_ERRCODE_DEFERRED0x71))
2076 return scsi_interpret_sense(xs);
2077
2078 /*
2079 * We do custom processing in cd for the unit becoming ready
2080 * case. We do not allow xs->retries to be decremented on the
2081 * "Unit Becoming Ready" case. This is because CD drives
2082 * report "Unit Becoming Ready" when loading media and can
2083 * take a long time. Rather than having a massive timeout for
2084 * all operations (which would cause other problems), we allow
2085 * operations to wait (but be interruptible with Ctrl-C)
2086 * forever as long as the drive is reporting that it is
2087 * becoming ready. All other cases of not being ready are
2088 * handled by the default handler.
2089 */
2090 switch(skey) {
2091 case SKEY_NOT_READY0x02:
2092 if (ISSET(xs->flags, SCSI_IGNORE_NOT_READY)((xs->flags) & (0x00040)))
2093 return 0;
2094 if (ASC_ASCQ(sense)((sense->add_sense_code << 8) | sense->add_sense_code_qual
)
== SENSE_NOT_READY_BECOMING_READY0x0401) {
2095 SC_DEBUG(link, SDEV_DB1, ("not ready: busy (%#x)\n",
2096 sense->add_sense_code_qual));
2097 /* don't count this as a retry */
2098 xs->retries++;
2099 return scsi_delay(xs, 1);
2100 }
2101 break;
2102 /* XXX more to come here for a few other cases */
2103 default:
2104 break;
2105 }
2106 return scsi_interpret_sense(xs);
2107}
2108
2109/*
2110 * Find out from the device what its capacity is.
2111 */
2112u_int64_t
2113cd_size(struct scsi_link *link, int flags, u_int32_t *blksize)
2114{
2115 struct scsi_read_cap_data_16 *rdcap16;
2116 struct scsi_read_cap_data *rdcap;
2117 u_int64_t max_addr;
2118 int error;
2119
2120 if (blksize != NULL((void *)0))
2121 *blksize = 0;
2122
2123 CLR(flags, SCSI_IGNORE_ILLEGAL_REQUEST)((flags) &= ~(0x00100));
2124
2125 /*
2126 * Start with a READ CAPACITY(10).
2127 */
2128 rdcap = dma_alloc(sizeof(*rdcap), ((flags & SCSI_NOSLEEP0x00001) ?
2129 PR_NOWAIT0x0002 : PR_WAITOK0x0001) | PR_ZERO0x0008);
2130 if (rdcap == NULL((void *)0))
2131 return 0;
2132
2133 error = scsi_read_cap_10(link, rdcap, flags);
2134 if (error) {
2135 dma_free(rdcap, sizeof(*rdcap));
2136 return 0;
2137 }
2138
2139 max_addr = _4btol(rdcap->addr);
2140 if (blksize != NULL((void *)0))
2141 *blksize = _4btol(rdcap->length);
2142 dma_free(rdcap, sizeof(*rdcap));
2143
2144 /*
2145 * pre-SPC (i.e. pre-SCSI-3) devices reporting less than 2^32-1 sectors
2146 * can stop here.
2147 */
2148 if (SID_ANSII_REV(&link->inqdata)((&link->inqdata)->version & 0x07) < SCSI_REV_SPC0x03 &&
2149 max_addr != 0xffffffff)
2150 goto exit;
2151
2152 rdcap16 = dma_alloc(sizeof(*rdcap16), ((flags & SCSI_NOSLEEP0x00001) ?
2153 PR_NOWAIT0x0002 : PR_WAITOK0x0001) | PR_ZERO0x0008);
2154 if (rdcap16 == NULL((void *)0))
2155 goto exit;
2156
2157 error = scsi_read_cap_16(link, rdcap16, flags);
2158 if (error) {
2159 dma_free(rdcap16, sizeof(*rdcap16));
2160 goto exit;
2161 }
2162
2163 max_addr = _8btol(rdcap16->addr);
2164 if (blksize != NULL((void *)0))
2165 *blksize = _4btol(rdcap16->length);
2166 /* XXX The other READ CAPACITY(16) info could be stored away. */
2167 dma_free(rdcap16, sizeof(*rdcap16));
2168
2169 return max_addr + 1;
2170
2171exit:
2172 /* Return READ CAPACITY 10 values. */
2173 if (max_addr != 0xffffffff)
2174 return max_addr + 1;
2175 else if (blksize != NULL((void *)0))
2176 *blksize = 0;
2177 return 0;
2178}
2179
2180#if defined(__macppc__)
2181int
2182cd_eject(void)
2183{
2184 struct cd_softc *sc;
2185 int error = 0;
2186
2187 if (cd_cd.cd_ndevs == 0 || (sc = cd_cd.cd_devs[0]) == NULL((void *)0))
2188 return ENXIO6;
2189
2190 if ((error = disk_lock(&sc->sc_dk)) != 0)
2191 return error;
2192
2193 if (sc->sc_dk.dk_openmask == 0) {
2194 SET(sc->sc_link->flags, SDEV_EJECTING)((sc->sc_link->flags) |= (0x0100));
2195
2196 scsi_prevent(sc->sc_link, PR_ALLOW0x00,
2197 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_NOT_READY0x00040 |
2198 SCSI_SILENT0x00020 | SCSI_IGNORE_MEDIA_CHANGE0x00080);
2199 CLR(sc->sc_link->flags, SDEV_MEDIA_LOADED)((sc->sc_link->flags) &= ~(0x0002));
2200
2201 scsi_start(sc->sc_link, SSS_STOP0x00|SSS_LOEJ0x02, 0);
2202
2203 CLR(sc->sc_link->flags, SDEV_EJECTING)((sc->sc_link->flags) &= ~(0x0100));
2204 }
2205 disk_unlock(&sc->sc_dk);
2206
2207 return error;
2208}
2209#endif /* __macppc__ */