mcd.c (7780) | mcd.c (8375) |
---|---|
1/* 2 * Copyright 1993 by Holger Veit (data part) 3 * Copyright 1993 by Brian Moore (audio part) 4 * Changes Copyright 1993 by Gary Clark II 5 * Changes Copyright (C) 1994-1995 by Andrey A. Chernov, Moscow, Russia 6 * 7 * Rewrote probe routine to work on newer Mitsumi drives. 8 * Additional changes (C) 1994 by Jordan K. Hubbard --- 26 unchanged lines hidden (view full) --- 35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 36 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 38 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * | 1/* 2 * Copyright 1993 by Holger Veit (data part) 3 * Copyright 1993 by Brian Moore (audio part) 4 * Changes Copyright 1993 by Gary Clark II 5 * Changes Copyright (C) 1994-1995 by Andrey A. Chernov, Moscow, Russia 6 * 7 * Rewrote probe routine to work on newer Mitsumi drives. 8 * Additional changes (C) 1994 by Jordan K. Hubbard --- 26 unchanged lines hidden (view full) --- 35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 36 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 38 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * |
43 * $Id: mcd.c,v 1.40 1995/03/28 07:55:42 bde Exp $ | 43 * $Id: mcd.c,v 1.41 1995/04/12 20:47:58 wollman Exp $ |
44 */ 45static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; 46 47#include "mcd.h" 48#if NMCD > 0 49#include <sys/types.h> 50#include <sys/param.h> 51#include <sys/systm.h> --- 13 unchanged lines hidden (view full) --- 65#include <machine/clock.h> 66 67#include <i386/i386/cons.h> 68 69#include <i386/isa/isa.h> 70#include <i386/isa/isa_device.h> 71#include <i386/isa/mcdreg.h> 72 | 44 */ 45static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; 46 47#include "mcd.h" 48#if NMCD > 0 49#include <sys/types.h> 50#include <sys/param.h> 51#include <sys/systm.h> --- 13 unchanged lines hidden (view full) --- 65#include <machine/clock.h> 66 67#include <i386/i386/cons.h> 68 69#include <i386/isa/isa.h> 70#include <i386/isa/isa_device.h> 71#include <i386/isa/mcdreg.h> 72 |
73#define MCD_TRACE(fmt,a,b,c,d) {if (mcd_data[unit].debug) {printf("mcd%d: status=0x%02x: ",unit,mcd_data[unit].status); printf(fmt,a,b,c,d);}} | 73#define MCD_TRACE(format, args...) \ 74{ \ 75 if (mcd_data[unit].debug) { \ 76 printf("mcd%d: status=0x%02x: ", \ 77 unit, mcd_data[unit].status); \ 78 printf(format, ## args); \ 79 } \ 80} |
74 75#define mcd_part(dev) ((minor(dev)) & 7) 76#define mcd_unit(dev) (((minor(dev)) & 0x38) >> 3) 77#define mcd_phys(dev) (((minor(dev)) & 0x40) >> 6) 78#define RAW_PART 2 79 80/* flags */ 81#define MCDOPEN 0x0001 /* device opened */ --- 206 unchanged lines hidden (view full) --- 288 (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsns", hz/WAIT_FRAC); 289 if ((r = mcd_getstat(unit,1)) == -1) 290 return EIO; 291 if (r != -2) 292 break; 293 } 294 295 if (cd->status & MCDDOOROPEN) { | 81 82#define mcd_part(dev) ((minor(dev)) & 7) 83#define mcd_unit(dev) (((minor(dev)) & 0x38) >> 3) 84#define mcd_phys(dev) (((minor(dev)) & 0x40) >> 6) 85#define RAW_PART 2 86 87/* flags */ 88#define MCDOPEN 0x0001 /* device opened */ --- 206 unchanged lines hidden (view full) --- 295 (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsns", hz/WAIT_FRAC); 296 if ((r = mcd_getstat(unit,1)) == -1) 297 return EIO; 298 if (r != -2) 299 break; 300 } 301 302 if (cd->status & MCDDOOROPEN) { |
296 printf("mcd%d: door is open\n"); | 303 printf("mcd%d: door is open\n", unit); |
297 return ENXIO; 298 } 299 if (!(cd->status & MCDDSKIN)) { | 304 return ENXIO; 305 } 306 if (!(cd->status & MCDDSKIN)) { |
300 printf("mcd%d: no CD inside\n"); | 307 printf("mcd%d: no CD inside\n", unit); |
301 return ENXIO; 302 } 303 if (cd->status & MCDDSKCHNG) { | 308 return ENXIO; 309 } 310 if (cd->status & MCDDSKCHNG) { |
304 printf("mcd%d: CD not sensed\n"); | 311 printf("mcd%d: CD not sensed\n", unit); |
305 return ENXIO; 306 } 307 308 if (mcdsize(dev) < 0) { 309 printf("mcd%d: failed to get disk size\n",unit); 310 return ENXIO; 311 } else 312 cd->flags |= MCDVALID; 313 314 /* XXX get a default disklabel */ 315 mcd_getdisklabel(unit); 316 | 312 return ENXIO; 313 } 314 315 if (mcdsize(dev) < 0) { 316 printf("mcd%d: failed to get disk size\n",unit); 317 return ENXIO; 318 } else 319 cd->flags |= MCDVALID; 320 321 /* XXX get a default disklabel */ 322 mcd_getdisklabel(unit); 323 |
317MCD_TRACE("open: partition=%d, disksize = %d, blksize=%d\n", 318 part,cd->disksize,cd->blksize,0); | 324MCD_TRACE("open: partition=%d, disksize = %ld, blksize=%d\n", 325 part, cd->disksize, cd->blksize); |
319 320 if (part == RAW_PART || 321 (part < cd->dlabel.d_npartitions && 322 cd->dlabel.d_partitions[part].p_fstype != FS_UNUSED)) { 323 cd->partflags[part] |= MCDOPEN; 324 cd->openflags |= (1<<part); 325 if (part == RAW_PART && phys != 0) 326 cd->partflags[part] |= MCDREADRAW; --- 27 unchanged lines hidden (view full) --- 354 (void) mcd_lock_door(unit, MCD_LK_UNLOCK); 355 356 if (!(cd->flags & MCDVALID)) 357 return 0; 358 359 /* close channel */ 360 cd->partflags[part] &= ~(MCDOPEN|MCDREADRAW); 361 cd->openflags &= ~(1<<part); | 326 327 if (part == RAW_PART || 328 (part < cd->dlabel.d_npartitions && 329 cd->dlabel.d_partitions[part].p_fstype != FS_UNUSED)) { 330 cd->partflags[part] |= MCDOPEN; 331 cd->openflags |= (1<<part); 332 if (part == RAW_PART && phys != 0) 333 cd->partflags[part] |= MCDREADRAW; --- 27 unchanged lines hidden (view full) --- 361 (void) mcd_lock_door(unit, MCD_LK_UNLOCK); 362 363 if (!(cd->flags & MCDVALID)) 364 return 0; 365 366 /* close channel */ 367 cd->partflags[part] &= ~(MCDOPEN|MCDREADRAW); 368 cd->openflags &= ~(1<<part); |
362 MCD_TRACE("close: partition=%d\n",part,0,0,0); | 369 MCD_TRACE("close: partition=%d\n", part); |
363 364 return 0; 365} 366 367void 368mcdstrategy(struct buf *bp) 369{ 370 struct mcd_data *cd; 371 struct buf *qp; 372 int s; 373 374 int unit = mcd_unit(bp->b_dev); 375 376 cd = mcd_data + unit; 377 378 /* test validity */ 379/*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n", 380 bp,unit,bp->b_blkno,bp->b_bcount);*/ 381 if (unit >= NMCD || bp->b_blkno < 0) { | 370 371 return 0; 372} 373 374void 375mcdstrategy(struct buf *bp) 376{ 377 struct mcd_data *cd; 378 struct buf *qp; 379 int s; 380 381 int unit = mcd_unit(bp->b_dev); 382 383 cd = mcd_data + unit; 384 385 /* test validity */ 386/*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n", 387 bp,unit,bp->b_blkno,bp->b_bcount);*/ 388 if (unit >= NMCD || bp->b_blkno < 0) { |
382 printf("mcdstrategy: unit = %d, blkno = %d, bcount = %d\n", | 389 printf("mcdstrategy: unit = %d, blkno = %ld, bcount = %ld\n", |
383 unit, bp->b_blkno, bp->b_bcount); 384 pg("mcd: mcdstratregy failure"); 385 bp->b_error = EINVAL; 386 bp->b_flags |= B_ERROR; 387 goto bad; 388 } 389 390 /* if device invalidated (e.g. media change, door open), error */ 391 if (!(cd->flags & MCDVALID)) { | 390 unit, bp->b_blkno, bp->b_bcount); 391 pg("mcd: mcdstratregy failure"); 392 bp->b_error = EINVAL; 393 bp->b_flags |= B_ERROR; 394 goto bad; 395 } 396 397 /* if device invalidated (e.g. media change, door open), error */ 398 if (!(cd->flags & MCDVALID)) { |
392MCD_TRACE("strategy: drive not valid\n",0,0,0,0); | 399MCD_TRACE("strategy: drive not valid\n"); |
393 bp->b_error = EIO; 394 goto bad; 395 } 396 397 /* read only */ 398 if (!(bp->b_flags & B_READ)) { 399 bp->b_error = EROFS; 400 goto bad; --- 57 unchanged lines hidden (view full) --- 458 } else { 459 /* nothing to do */ 460 splx(s); 461 return; 462 } 463 464 /* changed media? */ 465 if (!(cd->flags & MCDVALID)) { | 400 bp->b_error = EIO; 401 goto bad; 402 } 403 404 /* read only */ 405 if (!(bp->b_flags & B_READ)) { 406 bp->b_error = EROFS; 407 goto bad; --- 57 unchanged lines hidden (view full) --- 465 } else { 466 /* nothing to do */ 467 splx(s); 468 return; 469 } 470 471 /* changed media? */ 472 if (!(cd->flags & MCDVALID)) { |
466 MCD_TRACE("mcd_start: drive not valid\n",0,0,0,0); | 473 MCD_TRACE("mcd_start: drive not valid\n"); |
467 return; 468 } 469 470 p = cd->dlabel.d_partitions + mcd_part(bp->b_dev); 471 472 cd->flags |= MCDMBXBSY; 473 if (cd->partflags[mcd_part(bp->b_dev)] & MCDREADRAW) 474 cd->flags |= MCDREADRAW; --- 15 unchanged lines hidden (view full) --- 490 int unit,part; 491 492 unit = mcd_unit(dev); 493 part = mcd_part(dev); 494 cd = mcd_data + unit; 495 496 if (mcd_getstat(unit, 1) == -1) /* detect disk change too */ 497 return EIO; | 474 return; 475 } 476 477 p = cd->dlabel.d_partitions + mcd_part(bp->b_dev); 478 479 cd->flags |= MCDMBXBSY; 480 if (cd->partflags[mcd_part(bp->b_dev)] & MCDREADRAW) 481 cd->flags |= MCDREADRAW; --- 15 unchanged lines hidden (view full) --- 497 int unit,part; 498 499 unit = mcd_unit(dev); 500 part = mcd_part(dev); 501 cd = mcd_data + unit; 502 503 if (mcd_getstat(unit, 1) == -1) /* detect disk change too */ 504 return EIO; |
498MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); | 505MCD_TRACE("ioctl called 0x%x\n", cmd); |
499 500 switch (cmd) { 501 case DIOCSBAD: 502 if (!(cd->flags & MCDVALID)) 503 return ENXIO; 504 return EINVAL; 505 case DIOCGDINFO: 506 if (!(cd->flags & MCDVALID)) --- 320 unchanged lines hidden (view full) --- 827} 828 829static int 830mcd_setflags(int unit, struct mcd_data *cd) 831{ 832 /* check flags */ 833 if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) 834 || !(cd->status & MCDDSKIN)) { | 506 507 switch (cmd) { 508 case DIOCSBAD: 509 if (!(cd->flags & MCDVALID)) 510 return ENXIO; 511 return EINVAL; 512 case DIOCGDINFO: 513 if (!(cd->flags & MCDVALID)) --- 320 unchanged lines hidden (view full) --- 834} 835 836static int 837mcd_setflags(int unit, struct mcd_data *cd) 838{ 839 /* check flags */ 840 if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) 841 || !(cd->status & MCDDSKIN)) { |
835 MCD_TRACE("setflags: sensed DSKCHNG or DOOROPEN or !DSKIN\n",0,0,0,0); | 842 MCD_TRACE("setflags: sensed DSKCHNG or DOOROPEN or !DSKIN\n"); |
836 mcd_soft_reset(unit); 837 return -1; 838 } 839 840 if (cd->status & MCDAUDIOBSY) 841 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 842 else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) 843 cd->audio_status = CD_AS_PLAY_COMPLETED; --- 101 unchanged lines hidden (view full) --- 945 946 return EINVAL; 947} 948 949void 950mcdintr(unit) 951 int unit; 952{ | 843 mcd_soft_reset(unit); 844 return -1; 845 } 846 847 if (cd->status & MCDAUDIOBSY) 848 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 849 else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) 850 cd->audio_status = CD_AS_PLAY_COMPLETED; --- 101 unchanged lines hidden (view full) --- 952 953 return EINVAL; 954} 955 956void 957mcdintr(unit) 958 int unit; 959{ |
953 MCD_TRACE("stray interrupt\n",0,0,0,0); | 960 MCD_TRACE("stray interrupt\n"); |
954} 955 956/* state machine to process read requests 957 * initialize with MCD_S_BEGIN: calculate sizes, and read status 958 * MCD_S_WAITSTAT: wait for status reply, set mode 959 * MCD_S_WAITMODE: waits for status reply from set mode, set read command 960 * MCD_S_WAITREAD: wait for read ready, read data 961 */ --- 37 unchanged lines hidden (view full) --- 999 return; 1000 } 1001 cd->status = inb(port+mcd_status) & 0xFF; 1002 if (cd->status & MCD_ST_CMDCHECK) 1003 goto retry_status; 1004 if (mcd_setflags(unit,cd) < 0) 1005 goto changed; 1006 MCD_TRACE("got WAITSTAT delay=%d\n", | 961} 962 963/* state machine to process read requests 964 * initialize with MCD_S_BEGIN: calculate sizes, and read status 965 * MCD_S_WAITSTAT: wait for status reply, set mode 966 * MCD_S_WAITMODE: waits for status reply from set mode, set read command 967 * MCD_S_WAITREAD: wait for read ready, read data 968 */ --- 37 unchanged lines hidden (view full) --- 1006 return; 1007 } 1008 cd->status = inb(port+mcd_status) & 0xFF; 1009 if (cd->status & MCD_ST_CMDCHECK) 1010 goto retry_status; 1011 if (mcd_setflags(unit,cd) < 0) 1012 goto changed; 1013 MCD_TRACE("got WAITSTAT delay=%d\n", |
1007 RDELAY_WAITSTAT-mbx->count,0,0,0); | 1014 RDELAY_WAITSTAT-mbx->count); |
1008 /* reject, if audio active */ 1009 if (cd->status & MCDAUDIOBSY) { 1010 printf("mcd%d: audio is active\n",unit); 1011 goto readerr; 1012 } 1013 1014retry_mode: 1015 /* to check for raw/cooked mode */ --- 37 unchanged lines hidden (view full) --- 1053 if (cd->status & MCD_ST_CMDCHECK) { 1054 cd->curr_mode = MCD_MD_UNKNOWN; 1055 goto retry_mode; 1056 } 1057 if (mcd_setflags(unit,cd) < 0) 1058 goto changed; 1059 cd->curr_mode = mbx->mode; 1060 MCD_TRACE("got WAITMODE delay=%d\n", | 1015 /* reject, if audio active */ 1016 if (cd->status & MCDAUDIOBSY) { 1017 printf("mcd%d: audio is active\n",unit); 1018 goto readerr; 1019 } 1020 1021retry_mode: 1022 /* to check for raw/cooked mode */ --- 37 unchanged lines hidden (view full) --- 1060 if (cd->status & MCD_ST_CMDCHECK) { 1061 cd->curr_mode = MCD_MD_UNKNOWN; 1062 goto retry_mode; 1063 } 1064 if (mcd_setflags(unit,cd) < 0) 1065 goto changed; 1066 cd->curr_mode = mbx->mode; 1067 MCD_TRACE("got WAITMODE delay=%d\n", |
1061 RDELAY_WAITMODE-mbx->count,0,0,0); | 1068 RDELAY_WAITMODE-mbx->count); |
1062modedone: 1063 /* for first block */ 1064 mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; 1065 mbx->skip = 0; 1066 1067nextblock: 1068 blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) 1069 + mbx->p_offset + mbx->skip/mbx->sz; 1070 1071 MCD_TRACE("mcd_doread: read blknum=%d for bp=0x%x\n", | 1069modedone: 1070 /* for first block */ 1071 mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; 1072 mbx->skip = 0; 1073 1074nextblock: 1075 blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) 1076 + mbx->p_offset + mbx->skip/mbx->sz; 1077 1078 MCD_TRACE("mcd_doread: read blknum=%d for bp=0x%x\n", |
1072 blknum,bp,0,0); | 1079 blknum, bp); |
1073 1074 /* build parameter block */ 1075 hsg2msf(blknum,rbuf.start_msf); 1076retry_read: 1077 /* send the read command */ 1078 disable_intr(); 1079 mcd_put(com_port,cd->read_command); 1080 mcd_put(com_port,rbuf.start_msf[0]); --- 17 unchanged lines hidden (view full) --- 1098 (caddr_t)MCD_S_WAITREAD,hz/100); /* XXX */ 1099 return; 1100 case MCD_S_WAITREAD: 1101 untimeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITREAD); 1102 if (mbx->count-- > 0) { 1103 k = inb(port+MCD_FLAGS); 1104 if (!(k & MFL_DATA_NOT_AVAIL)) { /* XXX */ 1105 MCD_TRACE("got data delay=%d\n", | 1080 1081 /* build parameter block */ 1082 hsg2msf(blknum,rbuf.start_msf); 1083retry_read: 1084 /* send the read command */ 1085 disable_intr(); 1086 mcd_put(com_port,cd->read_command); 1087 mcd_put(com_port,rbuf.start_msf[0]); --- 17 unchanged lines hidden (view full) --- 1105 (caddr_t)MCD_S_WAITREAD,hz/100); /* XXX */ 1106 return; 1107 case MCD_S_WAITREAD: 1108 untimeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITREAD); 1109 if (mbx->count-- > 0) { 1110 k = inb(port+MCD_FLAGS); 1111 if (!(k & MFL_DATA_NOT_AVAIL)) { /* XXX */ 1112 MCD_TRACE("got data delay=%d\n", |
1106 RDELAY_WAITREAD-mbx->count,0,0,0); | 1113 RDELAY_WAITREAD-mbx->count); |
1107 got_it: 1108 /* data is ready */ 1109 addr = bp->b_un.b_addr + mbx->skip; 1110 1111 outb(port+mcd_ctl2,0x04); /* XXX */ 1112 for (i=0; i<mbx->sz; i++) 1113 *addr++ = inb(data_port); 1114 outb(port+mcd_ctl2,0x0c); /* XXX */ --- 549 unchanged lines hidden --- | 1114 got_it: 1115 /* data is ready */ 1116 addr = bp->b_un.b_addr + mbx->skip; 1117 1118 outb(port+mcd_ctl2,0x04); /* XXX */ 1119 for (i=0; i<mbx->sz; i++) 1120 *addr++ = inb(data_port); 1121 outb(port+mcd_ctl2,0x0c); /* XXX */ --- 549 unchanged lines hidden --- |