scd.c (104448) | scd.c (106449) |
---|---|
1#include "opt_geom.h" 2#ifndef GEOM 3/*- 4 * Copyright (c) 1995 Mikael Hybsch 5 * All rights reserved. 6 * 7 * Portions of this file are copied from mcd.c 8 * which has the following copyrights: --- 29 unchanged lines hidden (view full) --- 38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 41 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 | 1#include "opt_geom.h" 2#ifndef GEOM 3/*- 4 * Copyright (c) 1995 Mikael Hybsch 5 * All rights reserved. 6 * 7 * Portions of this file are copied from mcd.c 8 * which has the following copyrights: --- 29 unchanged lines hidden (view full) --- 38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 41 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 |
46/* $FreeBSD: head/sys/dev/scd/scd.c 104448 2002-10-04 08:33:10Z mdodd $ */ | 46/* $FreeBSD: head/sys/dev/scd/scd.c 106449 2002-11-05 09:37:32Z mdodd $ */ |
47 48/* Please send any comments to micke@dynas.se */ 49 50#define SCD_DEBUG 0 51 | 47 48/* Please send any comments to micke@dynas.se */ 49 50#define SCD_DEBUG 0 51 |
52#include "scd.h" | |
53#include <sys/param.h> 54#include <sys/systm.h> 55#include <sys/kernel.h> 56#include <sys/conf.h> 57#include <sys/bio.h> 58#include <sys/cdio.h> 59#include <sys/disklabel.h> 60#include <sys/bus.h> 61 62#include <machine/stdarg.h> 63 | 52#include <sys/param.h> 53#include <sys/systm.h> 54#include <sys/kernel.h> 55#include <sys/conf.h> 56#include <sys/bio.h> 57#include <sys/cdio.h> 58#include <sys/disklabel.h> 59#include <sys/bus.h> 60 61#include <machine/stdarg.h> 62 |
64#include <i386/isa/isa_device.h> 65#include <i386/isa/scdreg.h> | 63#include <machine/bus_pio.h> 64#include <machine/bus.h> 65#include <machine/resource.h> 66#include <sys/rman.h> |
66 | 67 |
68#include <isa/isavar.h> |
|
67 | 69 |
70#include <dev/scd/scdreg.h> 71#include <dev/scd/scdvar.h> 72 |
|
68#define scd_part(dev) ((minor(dev)) & 7) 69#define scd_unit(dev) (((minor(dev)) & 0x38) >> 3) 70#define scd_phys(dev) (((minor(dev)) & 0x40) >> 6) 71#define RAW_PART 2 72 73/* flags */ 74#define SCDOPEN 0x0001 /* device opened */ 75#define SCDVALID 0x0002 /* parameters loaded */ --- 13 unchanged lines hidden (view full) --- 89 90#define RDELAY_WAIT 300 91#define RDELAY_WAITREAD 300 92 93#define SCDBLKSIZE 2048 94 95#ifdef SCD_DEBUG 96 static int scd_debuglevel = SCD_DEBUG; | 73#define scd_part(dev) ((minor(dev)) & 7) 74#define scd_unit(dev) (((minor(dev)) & 0x38) >> 3) 75#define scd_phys(dev) (((minor(dev)) & 0x40) >> 6) 76#define RAW_PART 2 77 78/* flags */ 79#define SCDOPEN 0x0001 /* device opened */ 80#define SCDVALID 0x0002 /* parameters loaded */ --- 13 unchanged lines hidden (view full) --- 94 95#define RDELAY_WAIT 300 96#define RDELAY_WAITREAD 300 97 98#define SCDBLKSIZE 2048 99 100#ifdef SCD_DEBUG 101 static int scd_debuglevel = SCD_DEBUG; |
97# define XDEBUG(level, data) {if (scd_debuglevel >= level) printf data;} | 102# define XDEBUG(sc, level, fmt, args...) \ 103 do { \ 104 if (scd_debuglevel >= level) \ 105 device_printf(sc->dev, fmt, ## args); \ 106 } while (0) |
98#else | 107#else |
99# define XDEBUG(level, data) | 108# define XDEBUG(sc, level, fmt, args...) |
100#endif 101 | 109#endif 110 |
102struct scd_mbx { 103 short unit; 104 short port; 105 short retry; 106 short nblk; 107 int sz; 108 u_long skip; 109 struct bio *bp; 110 int p_offset; 111 short count; 112}; | 111#define IS_ATTENTION(sc) ((SCD_READ(sc, IREG_STATUS) & SBIT_ATTENTION) != 0) 112#define IS_BUSY(sc) ((SCD_READ(sc, IREG_STATUS) & SBIT_BUSY) != 0) 113#define IS_DATA_RDY(sc) ((SCD_READ(sc, IREG_STATUS) & SBIT_DATA_READY) != 0) 114#define STATUS_BIT(sc, bit) ((SCD_READ(sc, IREG_STATUS) & (bit)) != 0) 115#define FSTATUS_BIT(sc, bit) ((SCD_READ(sc, IREG_FSTATUS) & (bit)) != 0) |
113 | 116 |
114static struct scd_data { 115 int iobase; 116 char double_speed; 117 char *name; 118 short flags; 119 int blksize; 120 u_long disksize; 121 struct disklabel dlabel; 122 int openflag; 123 struct { 124 unsigned int adr :4; 125 unsigned int ctl :4; /* xcdplayer needs this */ 126 unsigned char start_msf[3]; 127 } toc[MAX_TRACKS]; 128 short first_track; 129 short last_track; 130 struct ioc_play_msf last_play; 131 132 short audio_status; 133 struct bio_queue_head head; /* head of bio queue */ 134 struct scd_mbx mbx; 135} scd_data[NSCD]; 136 | |
137/* prototypes */ 138static void hsg2msf(int hsg, bcd_t *msf); 139static int msf2hsg(bcd_t *msf); 140 | 117/* prototypes */ 118static void hsg2msf(int hsg, bcd_t *msf); 119static int msf2hsg(bcd_t *msf); 120 |
141static void process_attention(unsigned unit); 142static __inline void write_control(unsigned port, unsigned data); 143static int waitfor_status_bits(int unit, int bits_set, int bits_clear); 144static int send_cmd(u_int unit, u_char cmd, u_int nargs, ...); 145static void init_drive(unsigned unit); 146static int spin_up(unsigned unit); 147static int read_toc(unsigned unit); 148static int get_result(u_int unit, int result_len, u_char *result); 149static void print_error(int unit, int errcode); | 121static void process_attention(struct scd_softc *); 122static int waitfor_status_bits(struct scd_softc *, int bits_set, int bits_clear); 123static int send_cmd(struct scd_softc *, u_char cmd, u_int nargs, ...); 124static void init_drive(struct scd_softc *); 125static int spin_up(struct scd_softc *); 126static int read_toc(struct scd_softc *); 127static int get_result(struct scd_softc *, int result_len, u_char *result); 128static void print_error(struct scd_softc *, int errcode); |
150 | 129 |
151static void scd_start(int unit); | 130static void scd_start(struct scd_softc *); |
152static timeout_t scd_timeout; | 131static timeout_t scd_timeout; |
153static void scd_doread(int state, struct scd_mbx *mbxin); | 132static void scd_doread(struct scd_softc *, int state, struct scd_mbx *mbxin); |
154 | 133 |
155static int scd_eject(int unit); 156static int scd_stop(int unit); 157static int scd_pause(int unit); 158static int scd_resume(int unit); 159static int scd_playtracks(int unit, struct ioc_play_track *pt); 160static int scd_playmsf(int unit, struct ioc_play_msf *msf); 161static int scd_play(int unit, struct ioc_play_msf *msf); 162static int scd_subchan(int unit, struct ioc_read_subchannel *sc); 163static int read_subcode(int unit, struct sony_subchannel_position_data *sc); | 134static int scd_eject(struct scd_softc *); 135static int scd_stop(struct scd_softc *); 136static int scd_pause(struct scd_softc *); 137static int scd_resume(struct scd_softc *); 138static int scd_playtracks(struct scd_softc *, struct ioc_play_track *pt); 139static int scd_playmsf(struct scd_softc *, struct ioc_play_msf *msf); 140static int scd_play(struct scd_softc *, struct ioc_play_msf *msf); 141static int scd_subchan(struct scd_softc *, struct ioc_read_subchannel *sch); 142static int read_subcode(struct scd_softc *, struct sony_subchannel_position_data *sch); |
164 165/* for xcdplayer */ | 143 144/* for xcdplayer */ |
166static int scd_toc_header(int unit, struct ioc_toc_header *th); 167static int scd_toc_entrys(int unit, struct ioc_read_toc_entry *te); 168static int scd_toc_entry(int unit, struct ioc_read_toc_single_entry *te); | 145static int scd_toc_header(struct scd_softc *, struct ioc_toc_header *th); 146static int scd_toc_entrys(struct scd_softc *, struct ioc_read_toc_entry *te); 147static int scd_toc_entry(struct scd_softc *, struct ioc_read_toc_single_entry *te); |
169#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */ 170 | 148#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */ 149 |
171static int scd_probe(struct isa_device *dev); 172static int scd_attach(struct isa_device *dev); 173struct isa_driver scddriver = { 174 INTR_TYPE_BIO, 175 scd_probe, 176 scd_attach, 177 "scd" 178}; 179COMPAT_ISA_DRIVER(scd, scddriver); 180 181/* For canceling our timeout */ 182static struct callout_handle tohandle = CALLOUT_HANDLE_INITIALIZER(&tohanle); 183 | |
184static d_open_t scdopen; 185static d_close_t scdclose; 186static d_ioctl_t scdioctl; 187static d_strategy_t scdstrategy; 188 189#define CDEV_MAJOR 45 190 191static struct cdevsw scd_cdevsw = { --- 8 unchanged lines hidden (view full) --- 200 /* name */ "scd", 201 /* maj */ CDEV_MAJOR, 202 /* dump */ nodump, 203 /* psize */ nopsize, 204 /* flags */ D_DISK, 205}; 206 207 | 150static d_open_t scdopen; 151static d_close_t scdclose; 152static d_ioctl_t scdioctl; 153static d_strategy_t scdstrategy; 154 155#define CDEV_MAJOR 45 156 157static struct cdevsw scd_cdevsw = { --- 8 unchanged lines hidden (view full) --- 166 /* name */ "scd", 167 /* maj */ CDEV_MAJOR, 168 /* dump */ nodump, 169 /* psize */ nopsize, 170 /* flags */ D_DISK, 171}; 172 173 |
208static int 209scd_attach(struct isa_device *dev) | 174int 175scd_attach(struct scd_softc *sc) |
210{ | 176{ |
211 int unit = dev->id_unit; 212 struct scd_data *cd = scd_data + unit; | 177 struct scd_data *cd; 178 int unit; |
213 | 179 |
214 cd->iobase = dev->id_iobase; /* Already set by probe, but ... */ | 180 cd = &sc->data; 181 unit = device_get_unit(sc->dev); |
215 | 182 |
216 /* name filled in probe */ 217 printf("scd%d: <%s>\n", dev->id_unit, scd_data[dev->id_unit].name); | 183 init_drive(sc); |
218 | 184 |
219 init_drive(dev->id_unit); 220 | |
221 cd->flags = SCDINIT; 222 cd->audio_status = CD_AS_AUDIO_INVALID; 223 bioq_init(&cd->head); 224 | 185 cd->flags = SCDINIT; 186 cd->audio_status = CD_AS_AUDIO_INVALID; 187 bioq_init(&cd->head); 188 |
225 make_dev(&scd_cdevsw, dkmakeminor(unit, 0, 0), 226 UID_ROOT, GID_OPERATOR, 0640, "scd%da", unit); 227 make_dev(&scd_cdevsw, dkmakeminor(unit, 0, RAW_PART), 228 UID_ROOT, GID_OPERATOR, 0640, "scd%dc", unit); 229 return 1; | 189 sc->scd_dev_t = make_dev(&scd_cdevsw, 8 * unit, 190 UID_ROOT, GID_OPERATOR, 0640, "scd%d", unit); 191 sc->scd_dev_t->si_drv1 = (void *)sc; 192 193 return 0; |
230} 231 232static int 233scdopen(dev_t dev, int flags, int fmt, struct thread *td) 234{ | 194} 195 196static int 197scdopen(dev_t dev, int flags, int fmt, struct thread *td) 198{ |
235 int unit,part,phys; | 199 struct scd_softc *sc; 200 int part,phys; |
236 int rc; 237 struct scd_data *cd; 238 | 201 int rc; 202 struct scd_data *cd; 203 |
239 unit = scd_unit(dev); 240 if (unit >= NSCD) 241 return ENXIO; | 204 sc = (struct scd_softc *)dev->si_drv1; |
242 | 205 |
243 cd = scd_data + unit; | 206 cd = &sc->data; |
244 part = scd_part(dev); 245 phys = scd_phys(dev); 246 247 /* not initialized*/ 248 if (!(cd->flags & SCDINIT)) 249 return ENXIO; 250 251 /* invalidated in the meantime? mark all open part's invalid */ 252 if (cd->openflag) 253 return ENXIO; 254 | 207 part = scd_part(dev); 208 phys = scd_phys(dev); 209 210 /* not initialized*/ 211 if (!(cd->flags & SCDINIT)) 212 return ENXIO; 213 214 /* invalidated in the meantime? mark all open part's invalid */ 215 if (cd->openflag) 216 return ENXIO; 217 |
255 XDEBUG(1,("scd%d: DEBUG: status = 0x%x\n", unit, inb(cd->iobase+IREG_STATUS))); | 218 XDEBUG(sc, 1, "DEBUG: status = 0x%x\n", SCD_READ(sc, IREG_STATUS)); |
256 | 219 |
257 if ((rc = spin_up(unit)) != 0) { 258 print_error(unit, rc); | 220 if ((rc = spin_up(sc)) != 0) { 221 print_error(sc, rc); |
259 return EIO; 260 } 261 if (!(cd->flags & SCDTOC)) { 262 int loop_count = 3; 263 | 222 return EIO; 223 } 224 if (!(cd->flags & SCDTOC)) { 225 int loop_count = 3; 226 |
264 while (loop_count-- > 0 && (rc = read_toc(unit)) != 0) { | 227 while (loop_count-- > 0 && (rc = read_toc(sc)) != 0) { |
265 if (rc == ERR_NOT_SPINNING) { | 228 if (rc == ERR_NOT_SPINNING) { |
266 rc = spin_up(unit); | 229 rc = spin_up(sc); |
267 if (rc) { | 230 if (rc) { |
268 print_error(unit, rc);\ | 231 print_error(sc, rc);\ |
269 return EIO; 270 } 271 continue; 272 } | 232 return EIO; 233 } 234 continue; 235 } |
273 printf("scd%d: TOC read error 0x%x\n", unit, rc); | 236 device_printf(sc->dev, "TOC read error 0x%x\n", rc); |
274 return EIO; 275 } 276 } 277 278 dev->si_bsize_phys = cd->blksize; 279 280 cd->openflag = 1; 281 cd->flags |= SCDVALID; 282 283 return 0; 284} 285 286static int 287scdclose(dev_t dev, int flags, int fmt, struct thread *td) 288{ | 237 return EIO; 238 } 239 } 240 241 dev->si_bsize_phys = cd->blksize; 242 243 cd->openflag = 1; 244 cd->flags |= SCDVALID; 245 246 return 0; 247} 248 249static int 250scdclose(dev_t dev, int flags, int fmt, struct thread *td) 251{ |
289 int unit,part,phys; | 252 struct scd_softc *sc; 253 int part,phys; |
290 struct scd_data *cd; 291 | 254 struct scd_data *cd; 255 |
292 unit = scd_unit(dev); 293 if (unit >= NSCD) 294 return ENXIO; | 256 sc = (struct scd_softc *)dev->si_drv1; |
295 | 257 |
296 cd = scd_data + unit; | 258 cd = &sc->data; |
297 part = scd_part(dev); 298 phys = scd_phys(dev); 299 300 if (!(cd->flags & SCDINIT) || !cd->openflag) 301 return ENXIO; 302 303 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) { | 259 part = scd_part(dev); 260 phys = scd_phys(dev); 261 262 if (!(cd->flags & SCDINIT) || !cd->openflag) 263 return ENXIO; 264 265 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) { |
304 (void)send_cmd(unit, CMD_SPIN_DOWN, 0); | 266 (void)send_cmd(sc, CMD_SPIN_DOWN, 0); |
305 cd->flags &= ~SCDSPINNING; 306 } 307 308 309 /* close channel */ 310 cd->openflag = 0; 311 312 return 0; 313} 314 315static void 316scdstrategy(struct bio *bp) 317{ 318 struct scd_data *cd; 319 int s; | 267 cd->flags &= ~SCDSPINNING; 268 } 269 270 271 /* close channel */ 272 cd->openflag = 0; 273 274 return 0; 275} 276 277static void 278scdstrategy(struct bio *bp) 279{ 280 struct scd_data *cd; 281 int s; |
320 int unit = scd_unit(bp->bio_dev); | 282 struct scd_softc *sc; |
321 | 283 |
322 cd = scd_data + unit; | 284 sc = (struct scd_softc *)bp->bio_dev->si_drv1; 285 cd = &sc->data; |
323 | 286 |
324 XDEBUG(2, ("scd%d: DEBUG: strategy: block=%ld, bcount=%ld\n", 325 unit, (long)bp->bio_blkno, bp->bio_bcount)); | 287 XDEBUG(sc, 2, "DEBUG: strategy: block=%ld, bcount=%ld\n", 288 (long)bp->bio_blkno, bp->bio_bcount); |
326 | 289 |
327 if (unit >= NSCD || bp->bio_blkno < 0 || (bp->bio_bcount % SCDBLKSIZE)) { 328 printf("scd%d: strategy failure: blkno = %ld, bcount = %ld\n", 329 unit, (long)bp->bio_blkno, bp->bio_bcount); | 290 if (bp->bio_blkno < 0 || (bp->bio_bcount % SCDBLKSIZE)) { 291 device_printf(sc->dev, "strategy failure: blkno = %ld, bcount = %ld\n", 292 (long)bp->bio_blkno, bp->bio_bcount); |
330 bp->bio_error = EINVAL; 331 bp->bio_flags |= BIO_ERROR; 332 goto bad; 333 } 334 335 /* if device invalidated (e.g. media change, door open), error */ 336 if (!(cd->flags & SCDVALID)) { | 293 bp->bio_error = EINVAL; 294 bp->bio_flags |= BIO_ERROR; 295 goto bad; 296 } 297 298 /* if device invalidated (e.g. media change, door open), error */ 299 if (!(cd->flags & SCDVALID)) { |
337 printf("scd%d: media changed\n", unit); | 300 device_printf(sc->dev, "media changed\n"); |
338 bp->bio_error = EIO; 339 goto bad; 340 } 341 342 /* read only */ 343 if (!(bp->bio_cmd == BIO_READ)) { 344 bp->bio_error = EROFS; 345 goto bad; --- 15 unchanged lines hidden (view full) --- 361 bp->bio_resid = 0; 362 363 /* queue it */ 364 s = splbio(); 365 bioqdisksort(&cd->head, bp); 366 splx(s); 367 368 /* now check whether we can perform processing */ | 301 bp->bio_error = EIO; 302 goto bad; 303 } 304 305 /* read only */ 306 if (!(bp->bio_cmd == BIO_READ)) { 307 bp->bio_error = EROFS; 308 goto bad; --- 15 unchanged lines hidden (view full) --- 324 bp->bio_resid = 0; 325 326 /* queue it */ 327 s = splbio(); 328 bioqdisksort(&cd->head, bp); 329 splx(s); 330 331 /* now check whether we can perform processing */ |
369 scd_start(unit); | 332 scd_start(sc); |
370 return; 371 372bad: 373 bp->bio_flags |= BIO_ERROR; 374done: 375 bp->bio_resid = bp->bio_bcount; 376 biodone(bp); 377 return; 378} 379 380static void | 333 return; 334 335bad: 336 bp->bio_flags |= BIO_ERROR; 337done: 338 bp->bio_resid = bp->bio_bcount; 339 biodone(bp); 340 return; 341} 342 343static void |
381scd_start(int unit) | 344scd_start(struct scd_softc *sc) |
382{ | 345{ |
383 struct scd_data *cd = scd_data + unit; | 346 struct scd_data *cd = &sc->data; |
384 struct bio *bp; 385 struct partition *p; 386 int s = splbio(); 387 388 if (cd->flags & SCDMBXBSY) { 389 splx(s); 390 return; 391 } --- 7 unchanged lines hidden (view full) --- 399 } else { 400 /* nothing to do */ 401 splx(s); 402 return; 403 } 404 405 p = cd->dlabel.d_partitions + scd_part(bp->bio_dev); 406 | 347 struct bio *bp; 348 struct partition *p; 349 int s = splbio(); 350 351 if (cd->flags & SCDMBXBSY) { 352 splx(s); 353 return; 354 } --- 7 unchanged lines hidden (view full) --- 362 } else { 363 /* nothing to do */ 364 splx(s); 365 return; 366 } 367 368 p = cd->dlabel.d_partitions + scd_part(bp->bio_dev); 369 |
407 cd->mbx.unit = unit; 408 cd->mbx.port = cd->iobase; | |
409 cd->mbx.retry = 3; 410 cd->mbx.bp = bp; 411 cd->mbx.p_offset = p->p_offset; 412 splx(s); 413 | 370 cd->mbx.retry = 3; 371 cd->mbx.bp = bp; 372 cd->mbx.p_offset = p->p_offset; 373 splx(s); 374 |
414 scd_doread(SCD_S_BEGIN,&(cd->mbx)); | 375 scd_doread(sc, SCD_S_BEGIN, &(cd->mbx)); |
415 return; 416} 417 418static int 419scdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) 420{ 421 struct scd_data *cd; | 376 return; 377} 378 379static int 380scdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) 381{ 382 struct scd_data *cd; |
422 int unit,part; | 383 struct scd_softc *sc; 384 int part; |
423 | 385 |
424 unit = scd_unit(dev); | 386 sc = (struct scd_softc *)dev->si_drv1; |
425 part = scd_part(dev); | 387 part = scd_part(dev); |
426 cd = scd_data + unit; | 388 cd = &sc->data; |
427 | 389 |
428 XDEBUG(1, ("scd%d: ioctl: cmd=0x%lx\n", unit, cmd)); | 390 XDEBUG(sc, 1, "ioctl: cmd=0x%lx\n", cmd); |
429 430 if (!(cd->flags & SCDVALID)) 431 return EIO; 432 433 switch (cmd) { 434 case DIOCGDINFO: 435 *(struct disklabel *)addr = cd->dlabel; 436 return 0; 437 case CDIOCPLAYTRACKS: | 391 392 if (!(cd->flags & SCDVALID)) 393 return EIO; 394 395 switch (cmd) { 396 case DIOCGDINFO: 397 *(struct disklabel *)addr = cd->dlabel; 398 return 0; 399 case CDIOCPLAYTRACKS: |
438 return scd_playtracks(unit, (struct ioc_play_track *) addr); | 400 return scd_playtracks(sc, (struct ioc_play_track *) addr); |
439 case CDIOCPLAYBLOCKS: 440 return EINVAL; 441 case CDIOCPLAYMSF: | 401 case CDIOCPLAYBLOCKS: 402 return EINVAL; 403 case CDIOCPLAYMSF: |
442 return scd_playmsf(unit, (struct ioc_play_msf *) addr); | 404 return scd_playmsf(sc, (struct ioc_play_msf *) addr); |
443 case CDIOCREADSUBCHANNEL: | 405 case CDIOCREADSUBCHANNEL: |
444 return scd_subchan(unit, (struct ioc_read_subchannel *) addr); | 406 return scd_subchan(sc, (struct ioc_read_subchannel *) addr); |
445 case CDIOREADTOCHEADER: | 407 case CDIOREADTOCHEADER: |
446 return scd_toc_header (unit, (struct ioc_toc_header *) addr); | 408 return scd_toc_header (sc, (struct ioc_toc_header *) addr); |
447 case CDIOREADTOCENTRYS: | 409 case CDIOREADTOCENTRYS: |
448 return scd_toc_entrys (unit, (struct ioc_read_toc_entry*) addr); | 410 return scd_toc_entrys (sc, (struct ioc_read_toc_entry*) addr); |
449 case CDIOREADTOCENTRY: | 411 case CDIOREADTOCENTRY: |
450 return scd_toc_entry (unit, (struct ioc_read_toc_single_entry*) addr); | 412 return scd_toc_entry (sc, (struct ioc_read_toc_single_entry*) addr); |
451 case CDIOCSETPATCH: 452 case CDIOCGETVOL: 453 case CDIOCSETVOL: 454 case CDIOCSETMONO: 455 case CDIOCSETSTERIO: 456 case CDIOCSETMUTE: 457 case CDIOCSETLEFT: 458 case CDIOCSETRIGHT: 459 return EINVAL; 460 case CDIOCRESUME: | 413 case CDIOCSETPATCH: 414 case CDIOCGETVOL: 415 case CDIOCSETVOL: 416 case CDIOCSETMONO: 417 case CDIOCSETSTERIO: 418 case CDIOCSETMUTE: 419 case CDIOCSETLEFT: 420 case CDIOCSETRIGHT: 421 return EINVAL; 422 case CDIOCRESUME: |
461 return scd_resume(unit); | 423 return scd_resume(sc); |
462 case CDIOCPAUSE: | 424 case CDIOCPAUSE: |
463 return scd_pause(unit); | 425 return scd_pause(sc); |
464 case CDIOCSTART: 465 return EINVAL; 466 case CDIOCSTOP: | 426 case CDIOCSTART: 427 return EINVAL; 428 case CDIOCSTOP: |
467 return scd_stop(unit); | 429 return scd_stop(sc); |
468 case CDIOCEJECT: | 430 case CDIOCEJECT: |
469 return scd_eject(unit); | 431 return scd_eject(sc); |
470 case CDIOCALLOW: 471 return 0; 472 case CDIOCSETDEBUG: 473#ifdef SCD_DEBUG 474 scd_debuglevel++; 475#endif 476 return 0; 477 case CDIOCCLRDEBUG: 478#ifdef SCD_DEBUG 479 scd_debuglevel = 0; 480 481#endif 482 return 0; 483 default: | 432 case CDIOCALLOW: 433 return 0; 434 case CDIOCSETDEBUG: 435#ifdef SCD_DEBUG 436 scd_debuglevel++; 437#endif 438 return 0; 439 case CDIOCCLRDEBUG: 440#ifdef SCD_DEBUG 441 scd_debuglevel = 0; 442 443#endif 444 return 0; 445 default: |
484 printf("scd%d: unsupported ioctl (cmd=0x%lx)\n", unit, cmd); | 446 device_printf(sc->dev, "unsupported ioctl (cmd=0x%lx)\n", cmd); |
485 return ENOTTY; 486 } 487} 488 489/*************************************************************** 490 * lower level of driver starts here 491 **************************************************************/ 492 493static int | 447 return ENOTTY; 448 } 449} 450 451/*************************************************************** 452 * lower level of driver starts here 453 **************************************************************/ 454 455static int |
494scd_playtracks(int unit, struct ioc_play_track *pt) | 456scd_playtracks(struct scd_softc *sc, struct ioc_play_track *pt) |
495{ | 457{ |
496 struct scd_data *cd = scd_data + unit; | 458 struct scd_data *cd = &sc->data; |
497 struct ioc_play_msf msf; 498 int a = pt->start_track; 499 int z = pt->end_track; 500 int rc; 501 | 459 struct ioc_play_msf msf; 460 int a = pt->start_track; 461 int z = pt->end_track; 462 int rc; 463 |
502 if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { | 464 if (!(cd->flags & SCDTOC) && (rc = read_toc(sc)) != 0) { |
503 if (rc == -ERR_NOT_SPINNING) { | 465 if (rc == -ERR_NOT_SPINNING) { |
504 if (spin_up(unit) != 0) | 466 if (spin_up(sc) != 0) |
505 return EIO; | 467 return EIO; |
506 rc = read_toc(unit); | 468 rc = read_toc(sc); |
507 } 508 if (rc != 0) { | 469 } 470 if (rc != 0) { |
509 print_error(unit, rc); | 471 print_error(sc, rc); |
510 return EIO; 511 } 512 } 513 | 472 return EIO; 473 } 474 } 475 |
514 XDEBUG(1, ("scd%d: playtracks from %d:%d to %d:%d\n", unit, 515 a, pt->start_index, z, pt->end_index)); | 476 XDEBUG(sc, 1, "playtracks from %d:%d to %d:%d\n", 477 a, pt->start_index, z, pt->end_index); |
516 517 if ( a < cd->first_track 518 || a > cd->last_track 519 || a > z 520 || z > cd->last_track) 521 return EINVAL; 522 523 bcopy(cd->toc[a].start_msf, &msf.start_m, 3); 524 hsg2msf(msf2hsg(cd->toc[z+1].start_msf)-1, &msf.end_m); 525 | 478 479 if ( a < cd->first_track 480 || a > cd->last_track 481 || a > z 482 || z > cd->last_track) 483 return EINVAL; 484 485 bcopy(cd->toc[a].start_msf, &msf.start_m, 3); 486 hsg2msf(msf2hsg(cd->toc[z+1].start_msf)-1, &msf.end_m); 487 |
526 return scd_play(unit, &msf); | 488 return scd_play(sc, &msf); |
527} 528 529/* The start/end msf is expected to be in bin format */ 530static int | 489} 490 491/* The start/end msf is expected to be in bin format */ 492static int |
531scd_playmsf(int unit, struct ioc_play_msf *msfin) | 493scd_playmsf(struct scd_softc *sc, struct ioc_play_msf *msfin) |
532{ 533 struct ioc_play_msf msf; 534 535 msf.start_m = bin2bcd(msfin->start_m); 536 msf.start_s = bin2bcd(msfin->start_s); 537 msf.start_f = bin2bcd(msfin->start_f); 538 msf.end_m = bin2bcd(msfin->end_m); 539 msf.end_s = bin2bcd(msfin->end_s); 540 msf.end_f = bin2bcd(msfin->end_f); 541 | 494{ 495 struct ioc_play_msf msf; 496 497 msf.start_m = bin2bcd(msfin->start_m); 498 msf.start_s = bin2bcd(msfin->start_s); 499 msf.start_f = bin2bcd(msfin->start_f); 500 msf.end_m = bin2bcd(msfin->end_m); 501 msf.end_s = bin2bcd(msfin->end_s); 502 msf.end_f = bin2bcd(msfin->end_f); 503 |
542 return scd_play(unit, &msf); | 504 return scd_play(sc, &msf); |
543} 544 545/* The start/end msf is expected to be in bcd format */ 546static int | 505} 506 507/* The start/end msf is expected to be in bcd format */ 508static int |
547scd_play(int unit, struct ioc_play_msf *msf) | 509scd_play(struct scd_softc *sc, struct ioc_play_msf *msf) |
548{ | 510{ |
549 struct scd_data *cd = scd_data + unit; | 511 struct scd_data *cd = &sc->data; |
550 int i, rc; 551 | 512 int i, rc; 513 |
552 XDEBUG(1, ("scd%d: playing: %02x:%02x:%02x -> %02x:%02x:%02x\n", unit, | 514 XDEBUG(sc, 1, "playing: %02x:%02x:%02x -> %02x:%02x:%02x\n", |
553 msf->start_m, msf->start_s, msf->start_f, | 515 msf->start_m, msf->start_s, msf->start_f, |
554 msf->end_m, msf->end_s, msf->end_f)); | 516 msf->end_m, msf->end_s, msf->end_f); |
555 556 for (i = 0; i < 2; i++) { | 517 518 for (i = 0; i < 2; i++) { |
557 rc = send_cmd(unit, CMD_PLAY_AUDIO, 7, | 519 rc = send_cmd(sc, CMD_PLAY_AUDIO, 7, |
558 0x03, 559 msf->start_m, msf->start_s, msf->start_f, 560 msf->end_m, msf->end_s, msf->end_f); 561 if (rc == -ERR_NOT_SPINNING) { 562 cd->flags &= ~SCDSPINNING; | 520 0x03, 521 msf->start_m, msf->start_s, msf->start_f, 522 msf->end_m, msf->end_s, msf->end_f); 523 if (rc == -ERR_NOT_SPINNING) { 524 cd->flags &= ~SCDSPINNING; |
563 if (spin_up(unit) != 0) | 525 if (spin_up(sc) != 0) |
564 return EIO; 565 } else if (rc < 0) { | 526 return EIO; 527 } else if (rc < 0) { |
566 print_error(unit, rc); | 528 print_error(sc, rc); |
567 return EIO; 568 } else { 569 break; 570 } 571 } 572 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 573 bcopy((char *)msf, (char *)&cd->last_play, sizeof(struct ioc_play_msf)); 574 return 0; 575} 576 577static int | 529 return EIO; 530 } else { 531 break; 532 } 533 } 534 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 535 bcopy((char *)msf, (char *)&cd->last_play, sizeof(struct ioc_play_msf)); 536 return 0; 537} 538 539static int |
578scd_stop(int unit) | 540scd_stop(struct scd_softc *sc) |
579{ | 541{ |
580 struct scd_data *cd = scd_data + unit; | 542 struct scd_data *cd = &sc->data; |
581 | 543 |
582 (void)send_cmd(unit, CMD_STOP_AUDIO, 0); | 544 (void)send_cmd(sc, CMD_STOP_AUDIO, 0); |
583 cd->audio_status = CD_AS_PLAY_COMPLETED; 584 return 0; 585} 586 587static int | 545 cd->audio_status = CD_AS_PLAY_COMPLETED; 546 return 0; 547} 548 549static int |
588scd_pause(int unit) | 550scd_pause(struct scd_softc *sc) |
589{ | 551{ |
590 struct scd_data *cd = scd_data + unit; | 552 struct scd_data *cd = &sc->data; |
591 struct sony_subchannel_position_data subpos; 592 593 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) 594 return EINVAL; 595 | 553 struct sony_subchannel_position_data subpos; 554 555 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) 556 return EINVAL; 557 |
596 if (read_subcode(unit, &subpos) != 0) | 558 if (read_subcode(sc, &subpos) != 0) |
597 return EIO; 598 | 559 return EIO; 560 |
599 if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0) | 561 if (send_cmd(sc, CMD_STOP_AUDIO, 0) != 0) |
600 return EIO; 601 602 cd->last_play.start_m = subpos.abs_msf[0]; 603 cd->last_play.start_s = subpos.abs_msf[1]; 604 cd->last_play.start_f = subpos.abs_msf[2]; 605 cd->audio_status = CD_AS_PLAY_PAUSED; 606 | 562 return EIO; 563 564 cd->last_play.start_m = subpos.abs_msf[0]; 565 cd->last_play.start_s = subpos.abs_msf[1]; 566 cd->last_play.start_f = subpos.abs_msf[2]; 567 cd->audio_status = CD_AS_PLAY_PAUSED; 568 |
607 XDEBUG(1, ("scd%d: pause @ %02x:%02x:%02x\n", unit, | 569 XDEBUG(sc, 1, "pause @ %02x:%02x:%02x\n", |
608 cd->last_play.start_m, 609 cd->last_play.start_s, | 570 cd->last_play.start_m, 571 cd->last_play.start_s, |
610 cd->last_play.start_f)); | 572 cd->last_play.start_f); |
611 612 return 0; 613} 614 615static int | 573 574 return 0; 575} 576 577static int |
616scd_resume(int unit) | 578scd_resume(struct scd_softc *sc) |
617{ | 579{ |
618 if (scd_data[unit].audio_status != CD_AS_PLAY_PAUSED) | 580 581 if (sc->data.audio_status != CD_AS_PLAY_PAUSED) |
619 return EINVAL; | 582 return EINVAL; |
620 return scd_play(unit, &scd_data[unit].last_play); | 583 return scd_play(sc, &sc->data.last_play); |
621} 622 623static int | 584} 585 586static int |
624scd_eject(int unit) | 587scd_eject(struct scd_softc *sc) |
625{ | 588{ |
626 struct scd_data *cd = scd_data + unit; | 589 struct scd_data *cd = &sc->data; |
627 628 cd->audio_status = CD_AS_AUDIO_INVALID; 629 cd->flags &= ~(SCDSPINNING|SCDTOC); 630 | 590 591 cd->audio_status = CD_AS_AUDIO_INVALID; 592 cd->flags &= ~(SCDSPINNING|SCDTOC); 593 |
631 if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0 || 632 send_cmd(unit, CMD_SPIN_DOWN, 0) != 0 || 633 send_cmd(unit, CMD_EJECT, 0) != 0) | 594 if (send_cmd(sc, CMD_STOP_AUDIO, 0) != 0 || 595 send_cmd(sc, CMD_SPIN_DOWN, 0) != 0 || 596 send_cmd(sc, CMD_EJECT, 0) != 0) |
634 { 635 return EIO; 636 } 637 return 0; 638} 639 640static int | 597 { 598 return EIO; 599 } 600 return 0; 601} 602 603static int |
641scd_subchan(int unit, struct ioc_read_subchannel *sc) | 604scd_subchan(struct scd_softc *sc, struct ioc_read_subchannel *sch) |
642{ | 605{ |
643 struct scd_data *cd = scd_data + unit; | 606 struct scd_data *cd = &sc->data; |
644 struct sony_subchannel_position_data q; 645 struct cd_sub_channel_info data; 646 | 607 struct sony_subchannel_position_data q; 608 struct cd_sub_channel_info data; 609 |
647 XDEBUG(1, ("scd%d: subchan af=%d, df=%d\n", unit, 648 sc->address_format, 649 sc->data_format)); | 610 XDEBUG(sc, 1, "subchan af=%d, df=%d\n", 611 sch->address_format, sch->data_format); |
650 | 612 |
651 if (sc->address_format != CD_MSF_FORMAT) | 613 if (sch->address_format != CD_MSF_FORMAT) |
652 return EINVAL; 653 | 614 return EINVAL; 615 |
654 if (sc->data_format != CD_CURRENT_POSITION) | 616 if (sch->data_format != CD_CURRENT_POSITION) |
655 return EINVAL; 656 | 617 return EINVAL; 618 |
657 if (read_subcode(unit, &q) != 0) | 619 if (read_subcode(sc, &q) != 0) |
658 return EIO; 659 660 data.header.audio_status = cd->audio_status; 661 data.what.position.data_format = CD_MSF_FORMAT; 662 data.what.position.track_number = bcd2bin(q.track_number); 663 data.what.position.reladdr.msf.unused = 0; 664 data.what.position.reladdr.msf.minute = bcd2bin(q.rel_msf[0]); 665 data.what.position.reladdr.msf.second = bcd2bin(q.rel_msf[1]); 666 data.what.position.reladdr.msf.frame = bcd2bin(q.rel_msf[2]); 667 data.what.position.absaddr.msf.unused = 0; 668 data.what.position.absaddr.msf.minute = bcd2bin(q.abs_msf[0]); 669 data.what.position.absaddr.msf.second = bcd2bin(q.abs_msf[1]); 670 data.what.position.absaddr.msf.frame = bcd2bin(q.abs_msf[2]); 671 | 620 return EIO; 621 622 data.header.audio_status = cd->audio_status; 623 data.what.position.data_format = CD_MSF_FORMAT; 624 data.what.position.track_number = bcd2bin(q.track_number); 625 data.what.position.reladdr.msf.unused = 0; 626 data.what.position.reladdr.msf.minute = bcd2bin(q.rel_msf[0]); 627 data.what.position.reladdr.msf.second = bcd2bin(q.rel_msf[1]); 628 data.what.position.reladdr.msf.frame = bcd2bin(q.rel_msf[2]); 629 data.what.position.absaddr.msf.unused = 0; 630 data.what.position.absaddr.msf.minute = bcd2bin(q.abs_msf[0]); 631 data.what.position.absaddr.msf.second = bcd2bin(q.abs_msf[1]); 632 data.what.position.absaddr.msf.frame = bcd2bin(q.abs_msf[2]); 633 |
672 if (copyout(&data, sc->data, min(sizeof(struct cd_sub_channel_info), sc->data_len))!=0) | 634 if (copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len))!=0) |
673 return EFAULT; 674 return 0; 675} 676 | 635 return EFAULT; 636 return 0; 637} 638 |
677static __inline void 678write_control(unsigned port, unsigned data) | 639int 640scd_probe(struct scd_softc *sc) |
679{ | 641{ |
680 outb(port + OREG_CONTROL, data); 681} 682 683static int 684scd_probe(struct isa_device *dev) 685{ | |
686 struct sony_drive_configuration drive_config; | 642 struct sony_drive_configuration drive_config; |
687 int unit = dev->id_unit; | 643 struct scd_data *cd; |
688 int rc; 689 static char namebuf[8+16+8+3]; 690 char *s = namebuf; 691 int loop_count = 0; 692 | 644 int rc; 645 static char namebuf[8+16+8+3]; 646 char *s = namebuf; 647 int loop_count = 0; 648 |
693 scd_data[unit].flags = SCDPROBING; 694 scd_data[unit].iobase = dev->id_iobase; | 649 cd = &sc->data; 650 cd->flags = SCDPROBING; |
695 696 bzero(&drive_config, sizeof(drive_config)); 697 698again: 699 /* Reset drive */ | 651 652 bzero(&drive_config, sizeof(drive_config)); 653 654again: 655 /* Reset drive */ |
700 write_control(dev->id_iobase, CBIT_RESET_DRIVE); | 656 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESET_DRIVE); |
701 702 /* Calm down */ 703 DELAY(300000); 704 705 /* Only the ATTENTION bit may be set */ | 657 658 /* Calm down */ 659 DELAY(300000); 660 661 /* Only the ATTENTION bit may be set */ |
706 if ((inb(dev->id_iobase+IREG_STATUS) & ~1) != 0) { 707 XDEBUG(1, ("scd: too many bits set. probe failed.\n")); 708 return 0; | 662 if ((SCD_READ(sc, IREG_STATUS) & ~1) != 0) { 663 XDEBUG(sc, 1, "too many bits set. probe failed.\n"); 664 return (ENXIO); |
709 } | 665 } |
710 rc = send_cmd(unit, CMD_GET_DRIVE_CONFIG, 0); | 666 rc = send_cmd(sc, CMD_GET_DRIVE_CONFIG, 0); |
711 if (rc != sizeof(drive_config)) { 712 /* Sometimes if the drive is playing audio I get */ 713 /* the bad result 82. Fix by repeating the reset */ 714 if (rc > 0 && loop_count++ == 0) 715 goto again; | 667 if (rc != sizeof(drive_config)) { 668 /* Sometimes if the drive is playing audio I get */ 669 /* the bad result 82. Fix by repeating the reset */ 670 if (rc > 0 && loop_count++ == 0) 671 goto again; |
716 return 0; | 672 return (ENXIO); |
717 } | 673 } |
718 if (get_result(unit, rc, (u_char *)&drive_config) != 0) 719 return 0; | 674 if (get_result(sc, rc, (u_char *)&drive_config) != 0) 675 return (ENXIO); |
720 721 bcopy(drive_config.vendor, namebuf, 8); 722 s = namebuf+8; 723 while (*(s-1) == ' ') /* Strip trailing spaces */ 724 s--; 725 *s++ = ' '; 726 bcopy(drive_config.product, s, 16); 727 s += 16; 728 while (*(s-1) == ' ') 729 s--; 730 *s++ = ' '; 731 bcopy(drive_config.revision, s, 8); 732 s += 8; 733 while (*(s-1) == ' ') 734 s--; 735 *s = 0; 736 | 676 677 bcopy(drive_config.vendor, namebuf, 8); 678 s = namebuf+8; 679 while (*(s-1) == ' ') /* Strip trailing spaces */ 680 s--; 681 *s++ = ' '; 682 bcopy(drive_config.product, s, 16); 683 s += 16; 684 while (*(s-1) == ' ') 685 s--; 686 *s++ = ' '; 687 bcopy(drive_config.revision, s, 8); 688 s += 8; 689 while (*(s-1) == ' ') 690 s--; 691 *s = 0; 692 |
737 scd_data[unit].name = namebuf; | 693 cd->name = namebuf; |
738 739 if (drive_config.config & 0x10) | 694 695 if (drive_config.config & 0x10) |
740 scd_data[unit].double_speed = 1; | 696 cd->double_speed = 1; |
741 else | 697 else |
742 scd_data[unit].double_speed = 0; | 698 cd->double_speed = 0; |
743 | 699 |
744 return 4; | 700 return (0); |
745} 746 747static int | 701} 702 703static int |
748read_subcode(int unit, struct sony_subchannel_position_data *sc) | 704read_subcode(struct scd_softc *sc, struct sony_subchannel_position_data *scp) |
749{ 750 int rc; 751 | 705{ 706 int rc; 707 |
752 rc = send_cmd(unit, CMD_GET_SUBCHANNEL_DATA, 0); 753 if (rc < 0 || rc < sizeof(*sc)) | 708 rc = send_cmd(sc, CMD_GET_SUBCHANNEL_DATA, 0); 709 if (rc < 0 || rc < sizeof(*scp)) |
754 return EIO; | 710 return EIO; |
755 if (get_result(unit, rc, (u_char *)sc) != 0) | 711 if (get_result(sc, rc, (u_char *)scp) != 0) |
756 return EIO; 757 return 0; 758} 759 760/* State machine copied from mcd.c */ 761 762/* This (and the code in mcd.c) will not work with more than one drive */ | 712 return EIO; 713 return 0; 714} 715 716/* State machine copied from mcd.c */ 717 718/* This (and the code in mcd.c) will not work with more than one drive */ |
763/* because there is only one mbxsave below. Should fix that some day. */ 764/* (mbxsave & state should probably be included in the scd_data struct and */ | 719/* because there is only one sc->ch_mbxsave below. Should fix that some day. */ 720/* (sc->ch_mbxsave & state should probably be included in the scd_data struct and */ |
765/* the unit number used as first argument to scd_doread().) /Micke */ 766 767/* state machine to process read requests 768 * initialize with SCD_S_BEGIN: reset state machine 769 * SCD_S_WAITSTAT: wait for ready (!busy) 770 * SCD_S_WAITSPIN: wait for drive to spin up (if not spinning) 771 * SCD_S_WAITFIFO: wait for param fifo to get ready, them exec. command. 772 * SCD_S_WAITREAD: wait for data ready, read data 773 * SCD_S_WAITPARAM: wait for command result params, read them, error if bad data read. 774 */ 775 | 721/* the unit number used as first argument to scd_doread().) /Micke */ 722 723/* state machine to process read requests 724 * initialize with SCD_S_BEGIN: reset state machine 725 * SCD_S_WAITSTAT: wait for ready (!busy) 726 * SCD_S_WAITSPIN: wait for drive to spin up (if not spinning) 727 * SCD_S_WAITFIFO: wait for param fifo to get ready, them exec. command. 728 * SCD_S_WAITREAD: wait for data ready, read data 729 * SCD_S_WAITPARAM: wait for command result params, read them, error if bad data read. 730 */ 731 |
776static struct scd_mbx *mbxsave; 777 | |
778static void 779scd_timeout(void *arg) 780{ | 732static void 733scd_timeout(void *arg) 734{ |
781 scd_doread((int)arg, mbxsave); | 735 struct scd_softc *sc; 736 sc = (struct scd_softc *)arg; 737 738 scd_doread(sc, sc->ch_state, sc->ch_mbxsave); |
782} 783 784static void | 739} 740 741static void |
785scd_doread(int state, struct scd_mbx *mbxin) | 742scd_doread(struct scd_softc *sc, int state, struct scd_mbx *mbxin) |
786{ | 743{ |
787 struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? mbxsave : mbxin; 788 int unit = mbx->unit; 789 int port = mbx->port; | 744 struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? sc->ch_mbxsave : mbxin; |
790 struct bio *bp = mbx->bp; | 745 struct bio *bp = mbx->bp; |
791 struct scd_data *cd = scd_data + unit; 792 int reg,i; | 746 struct scd_data *cd = &sc->data; 747 int i; |
793 int blknum; 794 caddr_t addr; 795 static char sdata[3]; /* Must be preserved between calls to this function */ 796 797loop: 798 switch (state) { 799 case SCD_S_BEGIN: | 748 int blknum; 749 caddr_t addr; 750 static char sdata[3]; /* Must be preserved between calls to this function */ 751 752loop: 753 switch (state) { 754 case SCD_S_BEGIN: |
800 mbx = mbxsave = mbxin; | 755 mbx = sc->ch_mbxsave = mbxin; |
801 802 case SCD_S_BEGIN1: 803 /* get status */ 804 mbx->count = RDELAY_WAIT; 805 | 756 757 case SCD_S_BEGIN1: 758 /* get status */ 759 mbx->count = RDELAY_WAIT; 760 |
806 process_attention(unit); | 761 process_attention(sc); |
807 goto trystat; 808 809 case SCD_S_WAITSTAT: | 762 goto trystat; 763 764 case SCD_S_WAITSTAT: |
810 untimeout(scd_timeout,(caddr_t)SCD_S_WAITSTAT, tohandle); | 765 sc->ch_state = SCD_S_WAITSTAT; 766 untimeout(scd_timeout, (caddr_t)sc, sc->ch); |
811 if (mbx->count-- <= 0) { | 767 if (mbx->count-- <= 0) { |
812 printf("scd%d: timeout. drive busy.\n",unit); | 768 device_printf(sc->dev, "timeout. drive busy.\n"); |
813 goto harderr; 814 } 815 816trystat: | 769 goto harderr; 770 } 771 772trystat: |
817 if (IS_BUSY(port)) { 818 tohandle = timeout(scd_timeout, 819 (caddr_t)SCD_S_WAITSTAT,hz/100); /* XXX */ | 773 if (IS_BUSY(sc)) { 774 sc->ch_state = SCD_S_WAITSTAT; 775 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
820 return; 821 } 822 | 776 return; 777 } 778 |
823 process_attention(unit); | 779 process_attention(sc); |
824 825 /* reject, if audio active */ 826 if (cd->audio_status & CD_AS_PLAY_IN_PROGRESS) { | 780 781 /* reject, if audio active */ 782 if (cd->audio_status & CD_AS_PLAY_IN_PROGRESS) { |
827 printf("scd%d: audio is active\n",unit); | 783 device_printf(sc->dev, "audio is active\n"); |
828 goto harderr; 829 } 830 831 mbx->sz = cd->blksize; 832 833 /* for first block */ 834 mbx->nblk = (bp->bio_bcount + (mbx->sz-1)) / mbx->sz; 835 mbx->skip = 0; 836 837nextblock: 838 if (!(cd->flags & SCDVALID)) 839 goto changed; 840 841 blknum = (bp->bio_blkno / (mbx->sz/DEV_BSIZE)) 842 + mbx->p_offset + mbx->skip/mbx->sz; 843 | 784 goto harderr; 785 } 786 787 mbx->sz = cd->blksize; 788 789 /* for first block */ 790 mbx->nblk = (bp->bio_bcount + (mbx->sz-1)) / mbx->sz; 791 mbx->skip = 0; 792 793nextblock: 794 if (!(cd->flags & SCDVALID)) 795 goto changed; 796 797 blknum = (bp->bio_blkno / (mbx->sz/DEV_BSIZE)) 798 + mbx->p_offset + mbx->skip/mbx->sz; 799 |
844 XDEBUG(2, ("scd%d: scd_doread: read blknum=%d\n", unit, blknum)); | 800 XDEBUG(sc, 2, "scd_doread: read blknum=%d\n", blknum); |
845 846 /* build parameter block */ 847 hsg2msf(blknum, sdata); 848 | 801 802 /* build parameter block */ 803 hsg2msf(blknum, sdata); 804 |
849 write_control(port, CBIT_RESULT_READY_CLEAR); 850 write_control(port, CBIT_RPARAM_CLEAR); 851 write_control(port, CBIT_DATA_READY_CLEAR); | 805 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); 806 SCD_WRITE(sc, OREG_CONTROL, CBIT_RPARAM_CLEAR); 807 SCD_WRITE(sc, OREG_CONTROL, CBIT_DATA_READY_CLEAR); |
852 | 808 |
853 if (FSTATUS_BIT(port, FBIT_WPARAM_READY)) | 809 if (FSTATUS_BIT(sc, FBIT_WPARAM_READY)) |
854 goto writeparam; 855 856 mbx->count = 100; | 810 goto writeparam; 811 812 mbx->count = 100; |
857 tohandle = timeout(scd_timeout, 858 (caddr_t)SCD_S_WAITFIFO,hz/100); /* XXX */ | 813 sc->ch_state = SCD_S_WAITFIFO; 814 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
859 return; 860 861 case SCD_S_WAITSPIN: | 815 return; 816 817 case SCD_S_WAITSPIN: |
862 untimeout(scd_timeout,(caddr_t)SCD_S_WAITSPIN, tohandle); | 818 sc->ch_state = SCD_S_WAITSPIN; 819 untimeout(scd_timeout,(caddr_t)sc, sc->ch); |
863 if (mbx->count-- <= 0) { | 820 if (mbx->count-- <= 0) { |
864 printf("scd%d: timeout waiting for drive to spin up.\n", unit); | 821 device_printf(sc->dev, "timeout waiting for drive to spin up.\n"); |
865 goto harderr; 866 } | 822 goto harderr; 823 } |
867 if (!STATUS_BIT(port, SBIT_RESULT_READY)) { 868 tohandle = timeout(scd_timeout, 869 (caddr_t)SCD_S_WAITSPIN,hz/100); /* XXX */ | 824 if (!STATUS_BIT(sc, SBIT_RESULT_READY)) { 825 sc->ch_state = SCD_S_WAITSPIN; 826 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
870 return; 871 } | 827 return; 828 } |
872 write_control(port, CBIT_RESULT_READY_CLEAR); 873 switch ((i = inb(port+IREG_RESULT)) & 0xf0) { | 829 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); 830 switch ((i = SCD_READ(sc, IREG_RESULT)) & 0xf0) { |
874 case 0x20: | 831 case 0x20: |
875 i = inb(port+IREG_RESULT); 876 print_error(unit, i); | 832 i = SCD_READ(sc, IREG_RESULT); 833 print_error(sc, i); |
877 goto harderr; 878 case 0x00: | 834 goto harderr; 835 case 0x00: |
879 (void)inb(port+IREG_RESULT); | 836 (void)SCD_READ(sc, IREG_RESULT); |
880 cd->flags |= SCDSPINNING; 881 break; 882 } | 837 cd->flags |= SCDSPINNING; 838 break; 839 } |
883 XDEBUG(1, ("scd%d: DEBUG: spin up complete\n", unit)); | 840 XDEBUG(sc, 1, "DEBUG: spin up complete\n"); |
884 885 state = SCD_S_BEGIN1; 886 goto loop; 887 888 case SCD_S_WAITFIFO: | 841 842 state = SCD_S_BEGIN1; 843 goto loop; 844 845 case SCD_S_WAITFIFO: |
889 untimeout(scd_timeout,(caddr_t)SCD_S_WAITFIFO, tohandle); | 846 sc->ch_state = SCD_S_WAITFIFO; 847 untimeout(scd_timeout,(caddr_t)sc, sc->ch); |
890 if (mbx->count-- <= 0) { | 848 if (mbx->count-- <= 0) { |
891 printf("scd%d: timeout. write param not ready.\n",unit); | 849 device_printf(sc->dev, "timeout. write param not ready.\n"); |
892 goto harderr; 893 } | 850 goto harderr; 851 } |
894 if (!FSTATUS_BIT(port, FBIT_WPARAM_READY)) { 895 tohandle = timeout(scd_timeout, 896 (caddr_t)SCD_S_WAITFIFO,hz/100); /* XXX */ | 852 if (!FSTATUS_BIT(sc, FBIT_WPARAM_READY)) { 853 sc->ch_state = SCD_S_WAITFIFO; 854 sc->ch = timeout(scd_timeout, (caddr_t)sc,hz/100); /* XXX */ |
897 return; 898 } | 855 return; 856 } |
899 XDEBUG(1, ("scd%d: mbx->count (writeparamwait) = %d(%d)\n", unit, mbx->count, 100)); | 857 XDEBUG(sc, 1, "mbx->count (writeparamwait) = %d(%d)\n", mbx->count, 100); |
900 901writeparam: 902 /* The reason this test isn't done 'till now is to make sure */ 903 /* that it is ok to send the SPIN_UP cmd below. */ 904 if (!(cd->flags & SCDSPINNING)) { | 858 859writeparam: 860 /* The reason this test isn't done 'till now is to make sure */ 861 /* that it is ok to send the SPIN_UP cmd below. */ 862 if (!(cd->flags & SCDSPINNING)) { |
905 XDEBUG(1, ("scd%d: spinning up drive ...\n", unit)); 906 outb(port+OREG_COMMAND, CMD_SPIN_UP); | 863 XDEBUG(sc, 1, "spinning up drive ...\n"); 864 SCD_WRITE(sc, OREG_COMMAND, CMD_SPIN_UP); |
907 mbx->count = 300; | 865 mbx->count = 300; |
908 tohandle = timeout(scd_timeout, 909 (caddr_t)SCD_S_WAITSPIN,hz/100); /* XXX */ | 866 sc->ch_state = SCD_S_WAITSPIN; 867 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
910 return; 911 } 912 | 868 return; 869 } 870 |
913 reg = port + OREG_WPARAMS; | |
914 /* send the read command */ 915 disable_intr(); | 871 /* send the read command */ 872 disable_intr(); |
916 outb(reg, sdata[0]); 917 outb(reg, sdata[1]); 918 outb(reg, sdata[2]); 919 outb(reg, 0); 920 outb(reg, 0); 921 outb(reg, 1); 922 outb(port+OREG_COMMAND, CMD_READ); | 873 SCD_WRITE(sc, OREG_WPARAMS, sdata[0]); 874 SCD_WRITE(sc, OREG_WPARAMS, sdata[1]); 875 SCD_WRITE(sc, OREG_WPARAMS, sdata[2]); 876 SCD_WRITE(sc, OREG_WPARAMS, 0); 877 SCD_WRITE(sc, OREG_WPARAMS, 0); 878 SCD_WRITE(sc, OREG_WPARAMS, 1); 879 SCD_WRITE(sc, OREG_COMMAND, CMD_READ); |
923 enable_intr(); 924 925 mbx->count = RDELAY_WAITREAD; 926 for (i = 0; i < 50; i++) { | 880 enable_intr(); 881 882 mbx->count = RDELAY_WAITREAD; 883 for (i = 0; i < 50; i++) { |
927 if (STATUS_BIT(port, SBIT_DATA_READY)) | 884 if (STATUS_BIT(sc, SBIT_DATA_READY)) |
928 goto got_data; 929 DELAY(100); 930 } 931 | 885 goto got_data; 886 DELAY(100); 887 } 888 |
932 tohandle = timeout(scd_timeout, 933 (caddr_t)SCD_S_WAITREAD,hz/100); /* XXX */ | 889 sc->ch_state = SCD_S_WAITREAD; 890 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
934 return; 935 936 case SCD_S_WAITREAD: | 891 return; 892 893 case SCD_S_WAITREAD: |
937 untimeout(scd_timeout,(caddr_t)SCD_S_WAITREAD, tohandle); | 894 sc->ch_state = SCD_S_WAITREAD; 895 untimeout(scd_timeout,(caddr_t)sc, sc->ch); |
938 if (mbx->count-- <= 0) { | 896 if (mbx->count-- <= 0) { |
939 if (STATUS_BIT(port, SBIT_RESULT_READY)) | 897 if (STATUS_BIT(sc, SBIT_RESULT_READY)) |
940 goto got_param; | 898 goto got_param; |
941 printf("scd%d: timeout while reading data\n",unit); | 899 device_printf(sc->dev, "timeout while reading data\n"); |
942 goto readerr; 943 } | 900 goto readerr; 901 } |
944 if (!STATUS_BIT(port, SBIT_DATA_READY)) { 945 process_attention(unit); | 902 if (!STATUS_BIT(sc, SBIT_DATA_READY)) { 903 process_attention(sc); |
946 if (!(cd->flags & SCDVALID)) 947 goto changed; | 904 if (!(cd->flags & SCDVALID)) 905 goto changed; |
948 tohandle = timeout(scd_timeout, 949 (caddr_t)SCD_S_WAITREAD,hz/100); /* XXX */ | 906 sc->ch_state = SCD_S_WAITREAD; 907 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
950 return; 951 } | 908 return; 909 } |
952 XDEBUG(2, ("scd%d: mbx->count (after RDY_BIT) = %d(%d)\n", unit, mbx->count, RDELAY_WAITREAD)); | 910 XDEBUG(sc, 2, "mbx->count (after RDY_BIT) = %d(%d)\n", mbx->count, RDELAY_WAITREAD); |
953 954got_data: 955 /* data is ready */ 956 addr = bp->bio_data + mbx->skip; | 911 912got_data: 913 /* data is ready */ 914 addr = bp->bio_data + mbx->skip; |
957 write_control(port, CBIT_DATA_READY_CLEAR); 958 insb(port+IREG_DATA, addr, mbx->sz); | 915 SCD_WRITE(sc, OREG_CONTROL, CBIT_DATA_READY_CLEAR); 916 SCD_READ_MULTI(sc, IREG_DATA, addr, mbx->sz); |
959 960 mbx->count = 100; 961 for (i = 0; i < 20; i++) { | 917 918 mbx->count = 100; 919 for (i = 0; i < 20; i++) { |
962 if (STATUS_BIT(port, SBIT_RESULT_READY)) | 920 if (STATUS_BIT(sc, SBIT_RESULT_READY)) |
963 goto waitfor_param; 964 DELAY(100); 965 } 966 goto waitfor_param; 967 968 case SCD_S_WAITPARAM: | 921 goto waitfor_param; 922 DELAY(100); 923 } 924 goto waitfor_param; 925 926 case SCD_S_WAITPARAM: |
969 untimeout(scd_timeout,(caddr_t)SCD_S_WAITPARAM, tohandle); | 927 sc->ch_state = SCD_S_WAITPARAM; 928 untimeout(scd_timeout,(caddr_t)sc, sc->ch); |
970 if (mbx->count-- <= 0) { | 929 if (mbx->count-- <= 0) { |
971 printf("scd%d: timeout waiting for params\n",unit); | 930 device_printf(sc->dev, "timeout waiting for params\n"); |
972 goto readerr; 973 } 974 975waitfor_param: | 931 goto readerr; 932 } 933 934waitfor_param: |
976 if (!STATUS_BIT(port, SBIT_RESULT_READY)) { 977 tohandle = timeout(scd_timeout, 978 (caddr_t)SCD_S_WAITPARAM,hz/100); /* XXX */ | 935 if (!STATUS_BIT(sc, SBIT_RESULT_READY)) { 936 sc->ch_state = SCD_S_WAITPARAM; 937 sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ |
979 return; 980 } 981#if SCD_DEBUG 982 if (mbx->count < 100 && scd_debuglevel > 0) | 938 return; 939 } 940#if SCD_DEBUG 941 if (mbx->count < 100 && scd_debuglevel > 0) |
983 printf("scd%d: mbx->count (paramwait) = %d(%d)\n", unit, mbx->count, 100); | 942 device_printf(sc->dev, "mbx->count (paramwait) = %d(%d)\n", mbx->count, 100); |
984#endif 985 986got_param: | 943#endif 944 945got_param: |
987 write_control(port, CBIT_RESULT_READY_CLEAR); 988 switch ((i = inb(port+IREG_RESULT)) & 0xf0) { | 946 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); 947 switch ((i = SCD_READ(sc, IREG_RESULT)) & 0xf0) { |
989 case 0x50: 990 switch (i) { 991 case ERR_FATAL_READ_ERROR1: 992 case ERR_FATAL_READ_ERROR2: | 948 case 0x50: 949 switch (i) { 950 case ERR_FATAL_READ_ERROR1: 951 case ERR_FATAL_READ_ERROR2: |
993 printf("scd%d: unrecoverable read error 0x%x\n", unit, i); | 952 device_printf(sc->dev, "unrecoverable read error 0x%x\n", i); |
994 goto harderr; 995 } 996 break; 997 case 0x20: | 953 goto harderr; 954 } 955 break; 956 case 0x20: |
998 i = inb(port+IREG_RESULT); | 957 i = SCD_READ(sc, IREG_RESULT); |
999 switch (i) { 1000 case ERR_NOT_SPINNING: | 958 switch (i) { 959 case ERR_NOT_SPINNING: |
1001 XDEBUG(1, ("scd%d: read error: drive not spinning\n", unit)); | 960 XDEBUG(sc, 1, "read error: drive not spinning\n"); |
1002 if (mbx->retry-- > 0) { 1003 state = SCD_S_BEGIN1; 1004 cd->flags &= ~SCDSPINNING; 1005 goto loop; 1006 } 1007 goto harderr; 1008 default: | 961 if (mbx->retry-- > 0) { 962 state = SCD_S_BEGIN1; 963 cd->flags &= ~SCDSPINNING; 964 goto loop; 965 } 966 goto harderr; 967 default: |
1009 print_error(unit, i); | 968 print_error(sc, i); |
1010 goto readerr; 1011 } 1012 case 0x00: | 969 goto readerr; 970 } 971 case 0x00: |
1013 i = inb(port+IREG_RESULT); | 972 i = SCD_READ(sc, IREG_RESULT); |
1014 break; 1015 } 1016 1017 if (--mbx->nblk > 0) { 1018 mbx->skip += mbx->sz; 1019 goto nextblock; 1020 } 1021 1022 /* return buffer */ 1023 bp->bio_resid = 0; 1024 biodone(bp); 1025 1026 cd->flags &= ~SCDMBXBSY; | 973 break; 974 } 975 976 if (--mbx->nblk > 0) { 977 mbx->skip += mbx->sz; 978 goto nextblock; 979 } 980 981 /* return buffer */ 982 bp->bio_resid = 0; 983 biodone(bp); 984 985 cd->flags &= ~SCDMBXBSY; |
1027 scd_start(mbx->unit); | 986 scd_start(sc); |
1028 return; 1029 } 1030 1031readerr: 1032 if (mbx->retry-- > 0) { | 987 return; 988 } 989 990readerr: 991 if (mbx->retry-- > 0) { |
1033 printf("scd%d: retrying ...\n",unit); | 992 device_printf(sc->dev, "retrying ...\n"); |
1034 state = SCD_S_BEGIN1; 1035 goto loop; 1036 } 1037harderr: 1038 /* invalidate the buffer */ 1039 bp->bio_error = EIO; 1040 bp->bio_flags |= BIO_ERROR; 1041 bp->bio_resid = bp->bio_bcount; 1042 biodone(bp); 1043 1044 cd->flags &= ~SCDMBXBSY; | 993 state = SCD_S_BEGIN1; 994 goto loop; 995 } 996harderr: 997 /* invalidate the buffer */ 998 bp->bio_error = EIO; 999 bp->bio_flags |= BIO_ERROR; 1000 bp->bio_resid = bp->bio_bcount; 1001 biodone(bp); 1002 1003 cd->flags &= ~SCDMBXBSY; |
1045 scd_start(mbx->unit); | 1004 scd_start(sc); |
1046 return; 1047 1048changed: | 1005 return; 1006 1007changed: |
1049 printf("scd%d: media changed\n", unit); | 1008 device_printf(sc->dev, "media changed\n"); |
1050 goto harderr; 1051} 1052 1053static void 1054hsg2msf(int hsg, bcd_t *msf) 1055{ 1056 hsg += 150; 1057 M_msf(msf) = bin2bcd(hsg / 4500); --- 6 unchanged lines hidden (view full) --- 1064msf2hsg(bcd_t *msf) 1065{ 1066 return (bcd2bin(M_msf(msf)) * 60 + 1067 bcd2bin(S_msf(msf))) * 75 + 1068 bcd2bin(F_msf(msf)) - 150; 1069} 1070 1071static void | 1009 goto harderr; 1010} 1011 1012static void 1013hsg2msf(int hsg, bcd_t *msf) 1014{ 1015 hsg += 150; 1016 M_msf(msf) = bin2bcd(hsg / 4500); --- 6 unchanged lines hidden (view full) --- 1023msf2hsg(bcd_t *msf) 1024{ 1025 return (bcd2bin(M_msf(msf)) * 60 + 1026 bcd2bin(S_msf(msf))) * 75 + 1027 bcd2bin(F_msf(msf)) - 150; 1028} 1029 1030static void |
1072process_attention(unsigned unit) | 1031process_attention(struct scd_softc *sc) |
1073{ | 1032{ |
1074 unsigned port = scd_data[unit].iobase; | |
1075 unsigned char code; 1076 int count = 0; 1077 | 1033 unsigned char code; 1034 int count = 0; 1035 |
1078 while (IS_ATTENTION(port) && count++ < 30) { 1079 write_control(port, CBIT_ATTENTION_CLEAR); 1080 code = inb(port+IREG_RESULT); | 1036 while (IS_ATTENTION(sc) && count++ < 30) { 1037 SCD_WRITE(sc, OREG_CONTROL, CBIT_ATTENTION_CLEAR); 1038 code = SCD_READ(sc, IREG_RESULT); |
1081 1082#if SCD_DEBUG 1083 if (scd_debuglevel > 0) { 1084 if (count == 1) | 1039 1040#if SCD_DEBUG 1041 if (scd_debuglevel > 0) { 1042 if (count == 1) |
1085 printf("scd%d: DEBUG: ATTENTIONS = 0x%x", unit, code); | 1043 device_printf(sc->dev, "DEBUG: ATTENTIONS = 0x%x", code); |
1086 else 1087 printf(",0x%x", code); 1088 } 1089#endif 1090 1091 switch (code) { 1092 case ATTEN_SPIN_DOWN: | 1044 else 1045 printf(",0x%x", code); 1046 } 1047#endif 1048 1049 switch (code) { 1050 case ATTEN_SPIN_DOWN: |
1093 scd_data[unit].flags &= ~SCDSPINNING; | 1051 sc->data.flags &= ~SCDSPINNING; |
1094 break; 1095 1096 case ATTEN_SPIN_UP_DONE: | 1052 break; 1053 1054 case ATTEN_SPIN_UP_DONE: |
1097 scd_data[unit].flags |= SCDSPINNING; | 1055 sc->data.flags |= SCDSPINNING; |
1098 break; 1099 1100 case ATTEN_AUDIO_DONE: | 1056 break; 1057 1058 case ATTEN_AUDIO_DONE: |
1101 scd_data[unit].audio_status = CD_AS_PLAY_COMPLETED; | 1059 sc->data.audio_status = CD_AS_PLAY_COMPLETED; |
1102 break; 1103 1104 case ATTEN_DRIVE_LOADED: | 1060 break; 1061 1062 case ATTEN_DRIVE_LOADED: |
1105 scd_data[unit].flags &= ~(SCDTOC|SCDSPINNING|SCDVALID); 1106 scd_data[unit].audio_status = CD_AS_AUDIO_INVALID; | 1063 sc->data.flags &= ~(SCDTOC|SCDSPINNING|SCDVALID); 1064 sc->data.audio_status = CD_AS_AUDIO_INVALID; |
1107 break; 1108 1109 case ATTEN_EJECT_PUSHED: | 1065 break; 1066 1067 case ATTEN_EJECT_PUSHED: |
1110 scd_data[unit].flags &= ~SCDVALID; | 1068 sc->data.flags &= ~SCDVALID; |
1111 break; 1112 } 1113 DELAY(100); 1114 } 1115#if SCD_DEBUG 1116 if (scd_debuglevel > 0 && count > 0) 1117 printf("\n"); 1118#endif 1119} 1120 1121/* Returns 0 OR sony error code */ 1122static int | 1069 break; 1070 } 1071 DELAY(100); 1072 } 1073#if SCD_DEBUG 1074 if (scd_debuglevel > 0 && count > 0) 1075 printf("\n"); 1076#endif 1077} 1078 1079/* Returns 0 OR sony error code */ 1080static int |
1123spin_up(unsigned unit) | 1081spin_up(struct scd_softc *sc) |
1124{ 1125 unsigned char res_reg[12]; 1126 unsigned int res_size; 1127 int rc; 1128 int loop_count = 0; 1129 1130again: | 1082{ 1083 unsigned char res_reg[12]; 1084 unsigned int res_size; 1085 int rc; 1086 int loop_count = 0; 1087 1088again: |
1131 rc = send_cmd(unit, CMD_SPIN_UP, 0, 0, res_reg, &res_size); | 1089 rc = send_cmd(sc, CMD_SPIN_UP, 0, 0, res_reg, &res_size); |
1132 if (rc != 0) { | 1090 if (rc != 0) { |
1133 XDEBUG(2, ("scd%d: CMD_SPIN_UP error 0x%x\n", unit, rc)); | 1091 XDEBUG(sc, 2, "CMD_SPIN_UP error 0x%x\n", rc); |
1134 return rc; 1135 } 1136 | 1092 return rc; 1093 } 1094 |
1137 if (!(scd_data[unit].flags & SCDTOC)) { 1138 rc = send_cmd(unit, CMD_READ_TOC, 0); | 1095 if (!(sc->data.flags & SCDTOC)) { 1096 rc = send_cmd(sc, CMD_READ_TOC, 0); |
1139 if (rc == ERR_NOT_SPINNING) { 1140 if (loop_count++ < 3) 1141 goto again; 1142 return rc; 1143 } 1144 if (rc != 0) 1145 return rc; 1146 } 1147 | 1097 if (rc == ERR_NOT_SPINNING) { 1098 if (loop_count++ < 3) 1099 goto again; 1100 return rc; 1101 } 1102 if (rc != 0) 1103 return rc; 1104 } 1105 |
1148 scd_data[unit].flags |= SCDSPINNING; | 1106 sc->data.flags |= SCDSPINNING; |
1149 1150 return 0; 1151} 1152 1153static struct sony_tracklist * 1154get_tl(struct sony_toc *toc, int size) 1155{ 1156 struct sony_tracklist *tl = &toc->tracks[0]; --- 15 unchanged lines hidden (view full) --- 1172 (char *)tl += 9; 1173 if (tl->track != 0xc0) 1174 return tl; 1175 (char *)tl += 9; 1176 return tl; 1177} 1178 1179static int | 1107 1108 return 0; 1109} 1110 1111static struct sony_tracklist * 1112get_tl(struct sony_toc *toc, int size) 1113{ 1114 struct sony_tracklist *tl = &toc->tracks[0]; --- 15 unchanged lines hidden (view full) --- 1130 (char *)tl += 9; 1131 if (tl->track != 0xc0) 1132 return tl; 1133 (char *)tl += 9; 1134 return tl; 1135} 1136 1137static int |
1180read_toc(unsigned unit) | 1138read_toc(struct scd_softc *sc) |
1181{ 1182 struct scd_data *cd; 1183 unsigned part = 0; /* For now ... */ 1184 struct sony_toc toc; 1185 struct sony_tracklist *tl; 1186 int rc, i, j; 1187 u_long first, last; 1188 | 1139{ 1140 struct scd_data *cd; 1141 unsigned part = 0; /* For now ... */ 1142 struct sony_toc toc; 1143 struct sony_tracklist *tl; 1144 int rc, i, j; 1145 u_long first, last; 1146 |
1189 cd = scd_data + unit; | 1147 cd = &sc->data; |
1190 | 1148 |
1191 rc = send_cmd(unit, CMD_GET_TOC, 1, part+1); | 1149 rc = send_cmd(sc, CMD_GET_TOC, 1, part+1); |
1192 if (rc < 0) 1193 return rc; 1194 if (rc > sizeof(toc)) { | 1150 if (rc < 0) 1151 return rc; 1152 if (rc > sizeof(toc)) { |
1195 printf("scd%d: program error: toc too large (%d)\n", unit, rc); | 1153 device_printf(sc->dev, "program error: toc too large (%d)\n", rc); |
1196 return EIO; 1197 } | 1154 return EIO; 1155 } |
1198 if (get_result(unit, rc, (u_char *)&toc) != 0) | 1156 if (get_result(sc, rc, (u_char *)&toc) != 0) |
1199 return EIO; 1200 | 1157 return EIO; 1158 |
1201 XDEBUG(1, ("scd%d: toc read. len = %d, sizeof(toc) = %d\n", unit, rc, sizeof(toc))); | 1159 XDEBUG(sc, 1, "toc read. len = %d, sizeof(toc) = %d\n", rc, sizeof(toc)); |
1202 1203 tl = get_tl(&toc, rc); 1204 first = msf2hsg(tl->start_msf); 1205 last = msf2hsg(toc.lead_out_start_msf); 1206 cd->blksize = SCDBLKSIZE; 1207 cd->disksize = last*cd->blksize/DEV_BSIZE; 1208 | 1160 1161 tl = get_tl(&toc, rc); 1162 first = msf2hsg(tl->start_msf); 1163 last = msf2hsg(toc.lead_out_start_msf); 1164 cd->blksize = SCDBLKSIZE; 1165 cd->disksize = last*cd->blksize/DEV_BSIZE; 1166 |
1209 XDEBUG(1, ("scd%d: firstsector = %ld, lastsector = %ld", unit, 1210 first, last)); | 1167 XDEBUG(sc, 1, "firstsector = %ld, lastsector = %ld", first, last); |
1211 1212 cd->first_track = bcd2bin(toc.first_track); 1213 cd->last_track = bcd2bin(toc.last_track); 1214 if (cd->last_track > (MAX_TRACKS-2)) 1215 cd->last_track = MAX_TRACKS-2; 1216 for (j = 0, i = cd->first_track; i <= cd->last_track; i++, j++) { 1217 cd->toc[i].adr = tl[j].adr; 1218 cd->toc[i].ctl = tl[j].ctl; /* for xcdplayer */ 1219 bcopy(tl[j].start_msf, cd->toc[i].start_msf, 3); 1220#ifdef SCD_DEBUG 1221 if (scd_debuglevel > 0) { | 1168 1169 cd->first_track = bcd2bin(toc.first_track); 1170 cd->last_track = bcd2bin(toc.last_track); 1171 if (cd->last_track > (MAX_TRACKS-2)) 1172 cd->last_track = MAX_TRACKS-2; 1173 for (j = 0, i = cd->first_track; i <= cd->last_track; i++, j++) { 1174 cd->toc[i].adr = tl[j].adr; 1175 cd->toc[i].ctl = tl[j].ctl; /* for xcdplayer */ 1176 bcopy(tl[j].start_msf, cd->toc[i].start_msf, 3); 1177#ifdef SCD_DEBUG 1178 if (scd_debuglevel > 0) { |
1222 if ((j % 3) == 0) 1223 printf("\nscd%d: tracks ", unit); | 1179 if ((j % 3) == 0) { 1180 printf("\n"); 1181 device_printf(sc->dev, "tracks "); 1182 } |
1224 printf("[%03d: %2d %2d %2d] ", i, 1225 bcd2bin(cd->toc[i].start_msf[0]), 1226 bcd2bin(cd->toc[i].start_msf[1]), 1227 bcd2bin(cd->toc[i].start_msf[2])); 1228 } 1229#endif 1230 } 1231 bcopy(toc.lead_out_start_msf, cd->toc[cd->last_track+1].start_msf, 3); --- 33 unchanged lines hidden (view full) --- 1265 cd->dlabel.d_checksum = dkcksum(&cd->dlabel); 1266 1267 cd->flags |= SCDTOC; 1268 1269 return 0; 1270} 1271 1272static void | 1183 printf("[%03d: %2d %2d %2d] ", i, 1184 bcd2bin(cd->toc[i].start_msf[0]), 1185 bcd2bin(cd->toc[i].start_msf[1]), 1186 bcd2bin(cd->toc[i].start_msf[2])); 1187 } 1188#endif 1189 } 1190 bcopy(toc.lead_out_start_msf, cd->toc[cd->last_track+1].start_msf, 3); --- 33 unchanged lines hidden (view full) --- 1224 cd->dlabel.d_checksum = dkcksum(&cd->dlabel); 1225 1226 cd->flags |= SCDTOC; 1227 1228 return 0; 1229} 1230 1231static void |
1273init_drive(unsigned unit) | 1232init_drive(struct scd_softc *sc) |
1274{ 1275 int rc; 1276 | 1233{ 1234 int rc; 1235 |
1277 rc = send_cmd(unit, CMD_SET_DRIVE_PARAM, 2, 1278 0x05, 0x03 | ((scd_data[unit].double_speed) ? 0x04: 0)); | 1236 rc = send_cmd(sc, CMD_SET_DRIVE_PARAM, 2, 1237 0x05, 0x03 | ((sc->data.double_speed) ? 0x04: 0)); |
1279 if (rc != 0) | 1238 if (rc != 0) |
1280 printf("scd%d: Unable to set parameters. Errcode = 0x%x\n", unit, rc); | 1239 device_printf(sc->dev, "Unable to set parameters. Errcode = 0x%x\n", rc); |
1281} 1282 1283/* Returns 0 or errno */ 1284static int | 1240} 1241 1242/* Returns 0 or errno */ 1243static int |
1285get_result(u_int unit, int result_len, u_char *result) | 1244get_result(struct scd_softc *sc, int result_len, u_char *result) |
1286{ | 1245{ |
1287 unsigned int port = scd_data[unit].iobase; 1288 unsigned int res_reg = port + IREG_RESULT; | |
1289 int loop_index = 2; /* send_cmd() reads two bytes ... */ 1290 | 1246 int loop_index = 2; /* send_cmd() reads two bytes ... */ 1247 |
1291 XDEBUG(1, ("scd%d: DEBUG: get_result: bytes=%d\n", unit, result_len)); | 1248 XDEBUG(sc, 1, "DEBUG: get_result: bytes=%d\n", result_len); |
1292 1293 while (result_len-- > 0) { 1294 if (loop_index++ >= 10) { 1295 loop_index = 1; | 1249 1250 while (result_len-- > 0) { 1251 if (loop_index++ >= 10) { 1252 loop_index = 1; |
1296 if (waitfor_status_bits(unit, SBIT_RESULT_READY, 0)) | 1253 if (waitfor_status_bits(sc, SBIT_RESULT_READY, 0)) |
1297 return EIO; | 1254 return EIO; |
1298 write_control(port, CBIT_RESULT_READY_CLEAR); | 1255 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); |
1299 } 1300 if (result) | 1256 } 1257 if (result) |
1301 *result++ = inb(res_reg); | 1258 *result++ = SCD_READ(sc, IREG_RESULT); |
1302 else | 1259 else |
1303 (void)inb(res_reg); | 1260 (void)SCD_READ(sc, IREG_RESULT); |
1304 } 1305 return 0; 1306} 1307 1308/* Returns -0x100 for timeout, -(drive error code) OR number of result bytes */ 1309static int | 1261 } 1262 return 0; 1263} 1264 1265/* Returns -0x100 for timeout, -(drive error code) OR number of result bytes */ 1266static int |
1310send_cmd(u_int unit, u_char cmd, u_int nargs, ...) | 1267send_cmd(struct scd_softc *sc, u_char cmd, u_int nargs, ...) |
1311{ 1312 va_list ap; | 1268{ 1269 va_list ap; |
1313 u_int port = scd_data[unit].iobase; 1314 u_int reg; | |
1315 u_char c; 1316 int rc; 1317 int i; 1318 | 1270 u_char c; 1271 int rc; 1272 int i; 1273 |
1319 if (waitfor_status_bits(unit, 0, SBIT_BUSY)) { 1320 printf("scd%d: drive busy\n", unit); | 1274 if (waitfor_status_bits(sc, 0, SBIT_BUSY)) { 1275 device_printf(sc->dev, "drive busy\n"); |
1321 return -0x100; 1322 } 1323 | 1276 return -0x100; 1277 } 1278 |
1324 XDEBUG(1,("scd%d: DEBUG: send_cmd: cmd=0x%x nargs=%d", unit, cmd, nargs)); | 1279 XDEBUG(sc, 1, "DEBUG: send_cmd: cmd=0x%x nargs=%d", cmd, nargs); |
1325 | 1280 |
1326 write_control(port, CBIT_RESULT_READY_CLEAR); 1327 write_control(port, CBIT_RPARAM_CLEAR); | 1281 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); 1282 SCD_WRITE(sc, OREG_CONTROL, CBIT_RPARAM_CLEAR); |
1328 1329 for (i = 0; i < 100; i++) | 1283 1284 for (i = 0; i < 100; i++) |
1330 if (FSTATUS_BIT(port, FBIT_WPARAM_READY)) | 1285 if (FSTATUS_BIT(sc, FBIT_WPARAM_READY)) |
1331 break; | 1286 break; |
1332 if (!FSTATUS_BIT(port, FBIT_WPARAM_READY)) { 1333 XDEBUG(1, ("\nscd%d: wparam timeout\n", unit)); | 1287 if (!FSTATUS_BIT(sc, FBIT_WPARAM_READY)) { 1288 XDEBUG(sc, 1, "\nwparam timeout\n"); |
1334 return -EIO; 1335 } 1336 1337 va_start(ap, nargs); | 1289 return -EIO; 1290 } 1291 1292 va_start(ap, nargs); |
1338 reg = port + OREG_WPARAMS; | |
1339 for (i = 0; i < nargs; i++) { 1340 c = (u_char)va_arg(ap, int); | 1293 for (i = 0; i < nargs; i++) { 1294 c = (u_char)va_arg(ap, int); |
1341 outb(reg, c); 1342 XDEBUG(1, (",{0x%x}", c)); | 1295 SCD_WRITE(sc, OREG_WPARAMS, c); 1296 XDEBUG(sc, 1, ",{0x%x}", c); |
1343 } 1344 va_end(ap); | 1297 } 1298 va_end(ap); |
1345 XDEBUG(1, ("\n")); | 1299 XDEBUG(sc, 1, "\n"); |
1346 | 1300 |
1347 outb(port+OREG_COMMAND, cmd); | 1301 SCD_WRITE(sc, OREG_COMMAND, cmd); |
1348 | 1302 |
1349 rc = waitfor_status_bits(unit, SBIT_RESULT_READY, SBIT_BUSY); | 1303 rc = waitfor_status_bits(sc, SBIT_RESULT_READY, SBIT_BUSY); |
1350 if (rc) 1351 return -0x100; 1352 | 1304 if (rc) 1305 return -0x100; 1306 |
1353 reg = port + IREG_RESULT; 1354 write_control(port, CBIT_RESULT_READY_CLEAR); 1355 switch ((rc = inb(reg)) & 0xf0) { | 1307 SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); 1308 switch ((rc = SCD_READ(sc, IREG_RESULT)) & 0xf0) { |
1356 case 0x20: | 1309 case 0x20: |
1357 rc = inb(reg); | 1310 rc = SCD_READ(sc, IREG_RESULT); |
1358 /* FALLTHROUGH */ 1359 case 0x50: | 1311 /* FALLTHROUGH */ 1312 case 0x50: |
1360 XDEBUG(1, ("scd%d: DEBUG: send_cmd: drive_error=0x%x\n", unit, rc)); | 1313 XDEBUG(sc, 1, "DEBUG: send_cmd: drive_error=0x%x\n", rc); |
1361 return -rc; 1362 case 0x00: 1363 default: | 1314 return -rc; 1315 case 0x00: 1316 default: |
1364 rc = inb(reg); 1365 XDEBUG(1, ("scd%d: DEBUG: send_cmd: result_len=%d\n", unit, rc)); | 1317 rc = SCD_READ(sc, IREG_RESULT); 1318 XDEBUG(sc, 1, "DEBUG: send_cmd: result_len=%d\n", rc); |
1366 return rc; 1367 } 1368} 1369 1370static void | 1319 return rc; 1320 } 1321} 1322 1323static void |
1371print_error(int unit, int errcode) | 1324print_error(struct scd_softc *sc, int errcode) |
1372{ 1373 switch (errcode) { 1374 case -ERR_CD_NOT_LOADED: | 1325{ 1326 switch (errcode) { 1327 case -ERR_CD_NOT_LOADED: |
1375 printf("scd%d: door is open\n", unit); | 1328 device_printf(sc->dev, "door is open\n"); |
1376 break; 1377 case -ERR_NO_CD_INSIDE: | 1329 break; 1330 case -ERR_NO_CD_INSIDE: |
1378 printf("scd%d: no cd inside\n", unit); | 1331 device_printf(sc->dev, "no cd inside\n"); |
1379 break; 1380 default: 1381 if (errcode == -0x100 || errcode > 0) | 1332 break; 1333 default: 1334 if (errcode == -0x100 || errcode > 0) |
1382 printf("scd%d: device timeout\n", unit); | 1335 device_printf(sc->dev, "device timeout\n"); |
1383 else | 1336 else |
1384 printf("scd%d: unexpected error 0x%x\n", unit, -errcode); | 1337 device_printf(sc->dev, "unexpected error 0x%x\n", -errcode); |
1385 break; 1386 } 1387} 1388 1389/* Returns 0 or errno value */ 1390static int | 1338 break; 1339 } 1340} 1341 1342/* Returns 0 or errno value */ 1343static int |
1391waitfor_status_bits(int unit, int bits_set, int bits_clear) | 1344waitfor_status_bits(struct scd_softc *sc, int bits_set, int bits_clear) |
1392{ | 1345{ |
1393 u_int port = scd_data[unit].iobase; 1394 u_int flags = scd_data[unit].flags; 1395 u_int reg = port + IREG_STATUS; | 1346 u_int flags = sc->data.flags; |
1396 u_int max_loop; 1397 u_char c = 0; 1398 1399 if (flags & SCDPROBING) { 1400 max_loop = 0; 1401 while (max_loop++ < 1000) { | 1347 u_int max_loop; 1348 u_char c = 0; 1349 1350 if (flags & SCDPROBING) { 1351 max_loop = 0; 1352 while (max_loop++ < 1000) { |
1402 c = inb(reg); | 1353 c = SCD_READ(sc, IREG_STATUS); |
1403 if (c == 0xff) 1404 return EIO; 1405 if (c & SBIT_ATTENTION) { | 1354 if (c == 0xff) 1355 return EIO; 1356 if (c & SBIT_ATTENTION) { |
1406 process_attention(unit); | 1357 process_attention(sc); |
1407 continue; 1408 } 1409 if ((c & bits_set) == bits_set && 1410 (c & bits_clear) == 0) 1411 { 1412 break; 1413 } 1414 DELAY(10000); 1415 } 1416 } else { 1417 max_loop = 100; 1418 while (max_loop-- > 0) { | 1358 continue; 1359 } 1360 if ((c & bits_set) == bits_set && 1361 (c & bits_clear) == 0) 1362 { 1363 break; 1364 } 1365 DELAY(10000); 1366 } 1367 } else { 1368 max_loop = 100; 1369 while (max_loop-- > 0) { |
1419 c = inb(reg); | 1370 c = SCD_READ(sc, IREG_STATUS); |
1420 if (c & SBIT_ATTENTION) { | 1371 if (c & SBIT_ATTENTION) { |
1421 process_attention(unit); | 1372 process_attention(sc); |
1422 continue; 1423 } 1424 if ((c & bits_set) == bits_set && 1425 (c & bits_clear) == 0) 1426 { 1427 break; 1428 } 1429 tsleep(waitfor_status_bits, PZERO - 1, "waitfor", hz/10); 1430 } 1431 } 1432 if ((c & bits_set) == bits_set && 1433 (c & bits_clear) == 0) 1434 { 1435 return 0; 1436 } 1437#ifdef SCD_DEBUG 1438 if (scd_debuglevel > 0) | 1373 continue; 1374 } 1375 if ((c & bits_set) == bits_set && 1376 (c & bits_clear) == 0) 1377 { 1378 break; 1379 } 1380 tsleep(waitfor_status_bits, PZERO - 1, "waitfor", hz/10); 1381 } 1382 } 1383 if ((c & bits_set) == bits_set && 1384 (c & bits_clear) == 0) 1385 { 1386 return 0; 1387 } 1388#ifdef SCD_DEBUG 1389 if (scd_debuglevel > 0) |
1439 printf("scd%d: DEBUG: waitfor: TIMEOUT (0x%x,(0x%x,0x%x))\n", unit, c, bits_set, bits_clear); | 1390 device_printf(sc->dev, "DEBUG: waitfor: TIMEOUT (0x%x,(0x%x,0x%x))\n", c, bits_set, bits_clear); |
1440 else 1441#endif | 1391 else 1392#endif |
1442 printf("scd%d: timeout.\n", unit); | 1393 device_printf(sc->dev, "timeout.\n"); |
1443 return EIO; 1444} 1445 1446/* these two routines for xcdplayer - "borrowed" from mcd.c */ 1447static int | 1394 return EIO; 1395} 1396 1397/* these two routines for xcdplayer - "borrowed" from mcd.c */ 1398static int |
1448scd_toc_header (int unit, struct ioc_toc_header* th) | 1399scd_toc_header (struct scd_softc *sc, struct ioc_toc_header* th) |
1449{ | 1400{ |
1450 struct scd_data *cd = scd_data + unit; | 1401 struct scd_data *cd = &sc->data; |
1451 int rc; 1452 | 1402 int rc; 1403 |
1453 if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { 1454 print_error(unit, rc); | 1404 if (!(cd->flags & SCDTOC) && (rc = read_toc(sc)) != 0) { 1405 print_error(sc, rc); |
1455 return EIO; 1456 } 1457 1458 th->starting_track = cd->first_track; 1459 th->ending_track = cd->last_track; 1460 th->len = 0; /* not used */ 1461 1462 return 0; 1463} 1464 1465static int | 1406 return EIO; 1407 } 1408 1409 th->starting_track = cd->first_track; 1410 th->ending_track = cd->last_track; 1411 th->len = 0; /* not used */ 1412 1413 return 0; 1414} 1415 1416static int |
1466scd_toc_entrys (int unit, struct ioc_read_toc_entry *te) | 1417scd_toc_entrys (struct scd_softc *sc, struct ioc_read_toc_entry *te) |
1467{ | 1418{ |
1468 struct scd_data *cd = scd_data + unit; | 1419 struct scd_data *cd = &sc->data; |
1469 struct cd_toc_entry toc_entry; 1470 int rc, i, len = te->data_len; 1471 | 1420 struct cd_toc_entry toc_entry; 1421 int rc, i, len = te->data_len; 1422 |
1472 if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { 1473 print_error(unit, rc); | 1423 if (!(cd->flags & SCDTOC) && (rc = read_toc(sc)) != 0) { 1424 print_error(sc, rc); |
1474 return EIO; 1475 } 1476 1477 /* find the toc to copy*/ 1478 i = te->starting_track; 1479 if (i == SCD_LASTPLUS1) 1480 i = cd->last_track + 1; 1481 --- 21 unchanged lines hidden (view full) --- 1503 if (copyout(&toc_entry, te->data, sizeof(struct cd_toc_entry)) != 0) 1504 return EFAULT; 1505 1506 return 0; 1507} 1508 1509 1510static int | 1425 return EIO; 1426 } 1427 1428 /* find the toc to copy*/ 1429 i = te->starting_track; 1430 if (i == SCD_LASTPLUS1) 1431 i = cd->last_track + 1; 1432 --- 21 unchanged lines hidden (view full) --- 1454 if (copyout(&toc_entry, te->data, sizeof(struct cd_toc_entry)) != 0) 1455 return EFAULT; 1456 1457 return 0; 1458} 1459 1460 1461static int |
1511scd_toc_entry (int unit, struct ioc_read_toc_single_entry *te) | 1462scd_toc_entry (struct scd_softc *sc, struct ioc_read_toc_single_entry *te) |
1512{ | 1463{ |
1513 struct scd_data *cd = scd_data + unit; | 1464 struct scd_data *cd = &sc->data; |
1514 struct cd_toc_entry toc_entry; 1515 int rc, i; 1516 | 1465 struct cd_toc_entry toc_entry; 1466 int rc, i; 1467 |
1517 if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { 1518 print_error(unit, rc); | 1468 if (!(cd->flags & SCDTOC) && (rc = read_toc(sc)) != 0) { 1469 print_error(sc, rc); |
1519 return EIO; 1520 } 1521 1522 /* find the toc to copy*/ 1523 i = te->track; 1524 if (i == SCD_LASTPLUS1) 1525 i = cd->last_track + 1; 1526 --- 21 unchanged lines hidden --- | 1470 return EIO; 1471 } 1472 1473 /* find the toc to copy*/ 1474 i = te->track; 1475 if (i == SCD_LASTPLUS1) 1476 i = cd->last_track + 1; 1477 --- 21 unchanged lines hidden --- |