diff -u --recursive v1.1.28/linux/Makefile linux/Makefile --- v1.1.28/linux/Makefile Thu Jul 14 00:48:20 1994 +++ linux/Makefile Thu Jul 14 10:55:24 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 28 +SUBLEVEL = 29 all: Version zImage diff -u --recursive v1.1.28/linux/drivers/block/README.sbpcd linux/drivers/block/README.sbpcd --- v1.1.28/linux/drivers/block/README.sbpcd Sat Jul 9 16:30:45 1994 +++ linux/drivers/block/README.sbpcd Wed Jul 13 21:42:32 1994 @@ -1,4 +1,4 @@ -This README belongs to release 2.2 of the SoundBlaster Pro (Matsushita, +This README belongs to release 2.3 of the SoundBlaster Pro (Matsushita, Kotobuki, Panasonic, CreativeLabs) CD-ROM driver for Linux. The driver is able to drive the whole family of IDE-style @@ -48,12 +48,16 @@ With the "new" drive family CR-562 and CR-563, the reading of audio frames is possible. This is currently implemented by an IOCTL function which reads only -up to 4 frames of 2352 bytes at once. Reading more than 1 frame at once gives -very poor quality. Reading the same frame a second time gives different data; -it seems that the drive is out-of-sync at the beginning. See the program -example below. This lack has to get corrected by higher level software. +up to 4 frames of 2352 bytes at once. Reading more than 1 frame at once misses +some chunks at each frame boundary. Reading the same frame a second time gives +different data; the frame data start at a different position. But all read +bytes are valid, and we always read 98 consecutive chunks (of 24 Bytes) as a +frame. This lack has to get corrected by higher level software which reads the +same frame again and tries to find and eliminate overlapping chunks +(24-byte-pieces). + The transfer rate with reading audio (1-frame-pieces) is as slow as 32 kB/sec. -This could be better reading bigger chunks, but the out-of-sync parts occur at +This could be better reading bigger chunks, but the "missing" chunks occur at the beginning of each single frame. The software interface possibly may change a bit the day the SCSI driver supports it too. @@ -234,15 +238,20 @@ * (c) 1994 Eberhard Moenkeberg * may be used & enhanced freely * - * Due to non-existent sync bytes at the beginning of each audio frame, - * it is currently a kind of fortune if two consecutive frames fit together. - * Usually, they overlap, or a little piece is missing. This has to get - * fixed by higher-level software (reading until an overlap occurs, and then - * eliminate the overlapping bytes). Possibly the first read bytes of each - * frame must get discarded because they are read before we got synchronized. - * + * Due to non-existent sync bytes at the beginning of each audio frame (or due + * to a firmware bug within all known drives?), it is currently a kind of + * fortune if two consecutive frames fit together. + * Usually, they overlap, or a little piece is missing. This happens in units + * of 24-byte chunks. It has to get fixed by higher-level software (reading + * until an overlap occurs, and then eliminate the overlapping chunks). + * ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz holds an example of + * such an algorithm. * This example program further is missing to obtain the SubChannel data * which belong to each frame. + * + * This is only an example of the low-level access routine. The read data are + * pure 16-bit CDDA values; they have to get converted to make sound out of + * them. */ #include #include @@ -283,9 +292,10 @@ * get and display all TocEntries */ fprintf(stdout, "getting TocEntries...\n"); - for (i=1;i<=hdr.cdth_trk1;i++) + for (i=1;i<=hdr.cdth_trk1+1;i++) { - entry[i].cdte_track = i; + if (i!=hdr.cdth_trk1+1) entry[i].cdte_track = i; + else entry[i].cdte_track = CDROM_LEADOUT; entry[i].cdte_format = CDROM_LBA; err=ioctl(drive, CDROMREADTOCENTRY, &entry[i]); if (err!=0) @@ -323,7 +333,7 @@ exit (-1); } arg.addr.lba=entry[track].cdte_addr.lba; - arg.addr_format=CDROM_LBA; /* CDROM_MSF is still buggy, I know that */ + arg.addr_format=CDROM_LBA; /* CDROM_MSF would be possible here, too. */ arg.nframes=1; arg.buf=&buffer[0]; limit=entry[track+1].cdte_addr.lba; @@ -347,7 +357,7 @@ } /*===================== end program ========================================*/ -At ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.tar.gz is an adapted version of +At ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz is an adapted version of Heiko Eissfeldt's digital-audio to .WAV converter (the original is there, too). This is preliminary, as Heiko himself will care about it. @@ -355,11 +365,7 @@ Known problems: --------------- -Currently, the detection of disk change or removal does not work as good as it -should. - -The "door (un)lock" commands get done at every "(u)mount" (only the "new" -drives support it), but after an unlock, locking again does not work properly. +Currently, the detection of disk change or removal is actively disabled. All attempts to read the UPC/EAN code result in a stream of zeroes. All my drives are telling there is no UPC/EAN code on disk or there is, but it is an diff -u --recursive v1.1.28/linux/drivers/block/blk.h linux/drivers/block/blk.h --- v1.1.28/linux/drivers/block/blk.h Sat Jul 9 16:30:45 1994 +++ linux/drivers/block/blk.h Thu Jul 14 10:50:29 1994 @@ -304,6 +304,7 @@ CURRENT = req->next; if ((p = req->waiting) != NULL) { req->waiting = NULL; + p->swapping = 0; p->state = TASK_RUNNING; if (p->counter > current->counter) need_resched = 1; diff -u --recursive v1.1.28/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v1.1.28/linux/drivers/block/hd.c Mon Jun 27 16:46:58 1994 +++ linux/drivers/block/hd.c Wed Jul 13 23:59:00 1994 @@ -184,8 +184,11 @@ { unsigned short port; - if (drive>1 || head>15) - panic("Trying to write bad sector"); + if (drive>1 || head>15) { + printk("bad drive mapping, trying to access drive=%d, cyl=%d, head=%d, sect=%d\n", + drive, cyl, head, sect); + panic("harddisk driver problem"); + } #if (HD_DELAY > 0) while (read_timer() - last_req < HD_DELAY) /* nothing */; diff -u --recursive v1.1.28/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v1.1.28/linux/drivers/block/ll_rw_blk.c Thu Jun 9 18:56:09 1994 +++ linux/drivers/block/ll_rw_blk.c Thu Jul 14 10:50:29 1994 @@ -327,8 +327,12 @@ req->waiting = current; req->bh = NULL; req->next = NULL; + current->swapping = 1; current->state = TASK_SWAPPING; add_request(major+blk_dev,req); + /* The I/O may have inadvertently chagned the task state. + Make sure we really wait until the I/O is done */ + if (current->swapping) current->state = TASK_SWAPPING; schedule(); } @@ -462,8 +466,12 @@ req->waiting = current; req->bh = NULL; req->next = NULL; + current->swapping = 1; current->state = TASK_UNINTERRUPTIBLE; add_request(major+blk_dev,req); + /* The I/O may have inadvertently chagned the task state. + Make sure we really wait until the I/O is done */ + if (current->swapping) current->state = TASK_UNINTERRUPTIBLE; schedule(); } } diff -u --recursive v1.1.28/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c --- v1.1.28/linux/drivers/block/sbpcd.c Sat Jul 9 16:30:45 1994 +++ linux/drivers/block/sbpcd.c Wed Jul 13 21:42:33 1994 @@ -5,7 +5,7 @@ * and for "no-sound" interfaces like Lasermate and the * Panasonic CI-101P. * - * NOTE: This is release 2.2. + * NOTE: This is release 2.3. * It works with my SbPro & drive CR-521 V2.11 from 2/92 * and with the new CR-562-B V0.75 on a "naked" Panasonic * CI-101P interface. And vice versa. @@ -108,11 +108,15 @@ * * 2.1 Found bug with multisession CDs (accessing frame 16). * "read audio" works now with address type CDROM_MSF, too. - * Bigger audio frame buffer: allows reading max. 4 frames at time; but - * reading more than one frame at once gives poor quality. + * Bigger audio frame buffer: allows reading max. 4 frames at time; this + * gives a significant speedup, but reading more than one frame at once + * gives missing chunks at each single frame boundary. * - * 2.2 + * 2.2 Kernel interface cleanups: timers, init, setup, media check. * + * 2.3 Let "door lock" and "eject" live together. + * Implemented "close tray" (done automatically during open). + * * TODO * * disk change detection @@ -188,7 +192,7 @@ #include "blk.h" -#define VERSION "2.2 Eberhard Moenkeberg " +#define VERSION "2.3 Eberhard Moenkeberg " #define SBPCD_DEBUG @@ -224,22 +228,18 @@ */ #if !(SBPCD_ISSUE-1) #define DO_SBPCD_REQUEST(a) do_sbpcd_request(a) -#define SBPCD_SETUP(a,b) sbpcd_setup(a,b) #define SBPCD_INIT(a,b) sbpcd_init(a,b) #endif #if !(SBPCD_ISSUE-2) #define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a) -#define SBPCD_SETUP(a,b) sbpcd2_setup(a,b) #define SBPCD_INIT(a,b) sbpcd2_init(a,b) #endif #if !(SBPCD_ISSUE-3) #define DO_SBPCD_REQUEST(a) do_sbpcd3_request(a) -#define SBPCD_SETUP(a,b) sbpcd3_setup(a,b) #define SBPCD_INIT(a,b) sbpcd3_init(a,b) #endif #if !(SBPCD_ISSUE-4) #define DO_SBPCD_REQUEST(a) do_sbpcd4_request(a) -#define SBPCD_SETUP(a,b) sbpcd4_setup(a,b) #define SBPCD_INIT(a,b) sbpcd4_init(a,b) #endif /*==========================================================================*/ @@ -1269,9 +1269,14 @@ if (!st_caddy_in) break; } while (!st_diskok); +#if 000 DriveStruct[d].CD_changed=1; - i=DiskInfo(); - if (i<0) return (-2); +#endif + if ((st_door_closed) && (st_caddy_in)) + { + i=DiskInfo(); + if (i<0) return (-2); + } return (0); } /*==========================================================================*/ @@ -1311,6 +1316,21 @@ return (i); } /*==========================================================================*/ +static int yy_CloseTray(void) +{ + int i; + + if (!new_drive) return (0); + DPRINTF((DBG_LCK,"SBPCD: yy_CloseTray (drive %d)\n", d)); + + clr_cmdbuf(); + drvcmd[0]=0x07; + flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; + response_count=0; + i=cmd_out(); + return (i); +} +/*==========================================================================*/ static int xx_ReadSubQ(void) { int i,j; @@ -1608,10 +1628,12 @@ DriveStruct[d].TocEnt_format=infobuf[3]; if (new_drive) i=4; else i=5; - DriveStruct[d].TocEnt_address=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); + DriveStruct[d].TocEnt_address=make32(make16(0,infobuf[i]), + make16(infobuf[i+1],infobuf[i+2])); DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n", - DriveStruct[d].TocEnt_nixbyte,DriveStruct[d].TocEnt_ctl_adr,DriveStruct[d].TocEnt_number, - DriveStruct[d].TocEnt_format,DriveStruct[d].TocEnt_address)); + DriveStruct[d].TocEnt_nixbyte, DriveStruct[d].TocEnt_ctl_adr, + DriveStruct[d].TocEnt_number, DriveStruct[d].TocEnt_format, + DriveStruct[d].TocEnt_address)); return (0); } /*==========================================================================*/ @@ -2527,7 +2549,11 @@ DriveStruct[d].CD_changed=0xFF; DriveStruct[d].diskstate_flags=0; #endif WORKMAN + do i=yy_LockDoor(0); + while (i!=0); + DriveStruct[d].open_count=0; /* to get it locked next time again */ i=yy_SpinDown(); + DPRINTF((DBG_IOX,"SBPCD: ioctl: yy_SpinDown returned %d.\n", i)); if (i<0) return (-EIO); DriveStruct[d].audio_state=0; return (0); @@ -3193,6 +3219,10 @@ } switch_drive(i); + flags_cmd_out |= f_respo2; + xx_ReadStatus(); /* command: give 1-byte status */ + i=ResponseStatus(); + if (!st_door_closed) yy_CloseTray(); if (!st_spinning) xx_SpinUp(); flags_cmd_out |= f_respo2; @@ -3207,7 +3237,7 @@ if (!st_door_closed||!st_caddy_in) { printk("SBPCD: sbpcd_open: no disk in drive\n"); - return (-EIO); + return (-ENXIO); } /* @@ -3245,7 +3275,7 @@ switch_drive(i); DriveStruct[d].sbp_first_frame=DriveStruct[d].sbp_last_frame=-1; - fsync_dev(ip->i_rdev); /* nonsense if read only device? */ + sync_dev(ip->i_rdev); /* nonsense if read only device? */ invalidate_buffers(ip->i_rdev); DriveStruct[d].diskstate_flags &= ~cd_size_bit; @@ -3254,11 +3284,14 @@ */ DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n", DriveStruct[d].open_count,DriveStruct[d].open_count-1)); - if (--DriveStruct[d].open_count==0) + if (DriveStruct[d].open_count!=0) /* CDROMEJECT may have been done */ { - do - i=yy_LockDoor(0); - while (i!=0); + if (--DriveStruct[d].open_count==0) + { + do + i=yy_LockDoor(0); + while (i!=0); + } } } /*==========================================================================*/ @@ -3305,7 +3338,7 @@ #if (SBPCD_ISSUE-1) static #endif -void SBPCD_SETUP(char *s, int *p) +void sbpcd_setup(char *s, int *p) { DPRINTF((DBG_INI,"SBPCD: sbpcd_setup called with %04X,%s\n",p[1], s)); sbpro_type=0; @@ -3422,7 +3455,7 @@ if (autoprobe[port_index+1]==0) type=str_lm; else if (autoprobe[port_index+1]==1) type=str_sb; else type=str_sp; - SBPCD_SETUP(type, addr); + sbpcd_setup(type, addr); DPRINTF((DBG_INF,"SBPCD: Trying to detect a %s CD-ROM drive at 0x%X.\n", type, CDo_command)); diff -u --recursive v1.1.28/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v1.1.28/linux/drivers/scsi/scsi.c Thu Jul 14 00:48:24 1994 +++ linux/drivers/scsi/scsi.c Thu Jul 14 10:51:42 1994 @@ -220,7 +220,7 @@ int dev, lun, type; unsigned char scsi_cmd [12]; unsigned char scsi_result [256]; - Scsi_Device * SDpnt; + Scsi_Device * SDpnt, *SDtail; Scsi_Cmnd SCmd; ++in_scan; @@ -229,6 +229,10 @@ SCmd.next = NULL; SCmd.prev = NULL; SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device)); + SDtail = scsi_devices; + if(scsi_devices) { + while(SDtail->next) SDtail = SDtail->next; + } shpnt->host_queue = &SCmd; /* We need this so that commands can time out */ @@ -465,8 +469,13 @@ while (SCmd.request.dev != 0xfffe); }; - SDpnt->next = scsi_devices; - scsi_devices = SDpnt; + /* Add this device to the linked list at the end */ + if(SDtail) + SDtail->next = SDpnt; + else + scsi_devices = SDpnt; + SDtail = SDpnt; + ++NR_SCSI_DEVICES; SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device)); /* Some scsi devices cannot be polled for lun != 0 diff -u --recursive v1.1.28/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v1.1.28/linux/drivers/scsi/scsi.h Thu Jul 14 00:48:24 1994 +++ linux/drivers/scsi/scsi.h Thu Jul 14 10:50:29 1994 @@ -556,6 +556,7 @@ DEVICE_OFF(req->dev); if ((p = req->waiting) != NULL) { req->waiting = NULL; + p->swapping = 0; p->state = TASK_RUNNING; if (p->counter > current->counter) need_resched = 1; @@ -585,20 +586,17 @@ #endif #define SCSI_SLEEP(QUEUE, CONDITION) { \ - long old_state; \ if (CONDITION) { \ struct wait_queue wait = { current, NULL}; \ add_wait_queue(QUEUE, &wait); \ sleep_repeat: \ - old_state = current->state; \ current->state = TASK_UNINTERRUPTIBLE; \ if (CONDITION) { \ schedule(); \ goto sleep_repeat; \ } \ remove_wait_queue(QUEUE, &wait); \ - if (current->state == TASK_UNINTERRUPTIBLE) \ - current->state = old_state; \ + current->state = TASK_RUNNING; \ }; } #endif diff -u --recursive v1.1.28/linux/include/linux/cdrom.h linux/include/linux/cdrom.h --- v1.1.28/linux/include/linux/cdrom.h Thu Jul 7 21:37:13 1994 +++ linux/include/linux/cdrom.h Wed Jul 13 21:42:33 1994 @@ -17,7 +17,10 @@ #define CD_MINS 74 /* max. minutes per CD */ #define CD_SECS 60 /* seconds per minute */ #define CD_FRAMES 75 /* frames per second */ +#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */ +#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */ #define CD_FRAMESIZE 2048 /* bytes per frame, cooked mode */ +#define CD_FRAMESIZE_RAW0 2336 /* bytes per frame, "raw" mode */ #define CD_FRAMESIZE_XA 2340 /* bytes per frame, "xa" mode */ #define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */ #define CD_FRAMESIZE_SUB 96 /* subchannel data size */ diff -u --recursive v1.1.28/linux/include/linux/sched.h linux/include/linux/sched.h --- v1.1.28/linux/include/linux/sched.h Tue Jun 21 14:16:25 1994 +++ linux/include/linux/sched.h Thu Jul 14 10:50:29 1994 @@ -264,6 +264,7 @@ unsigned long personality; int dumpable:1; int did_exec:1; + volatile int swapping:1; int pid,pgrp,session,leader; int groups[NGROUPS]; /* @@ -331,7 +332,7 @@ /* schedlink */ &init_task,&init_task, \ /* signals */ {{ 0, },}, \ /* stack */ 0,(unsigned long) &init_kernel_stack, \ -/* ec,brk... */ 0,0,0,0,0, \ +/* ec,brk... */ 0,0,0,0,0,0, \ /* pid etc.. */ 0,0,0,0, \ /* suppl grps*/ {NOGROUP,}, \ /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ diff -u --recursive v1.1.28/linux/kernel/fork.c linux/kernel/fork.c --- v1.1.28/linux/kernel/fork.c Sat Jul 9 16:30:47 1994 +++ linux/kernel/fork.c Thu Jul 14 10:50:29 1994 @@ -188,6 +188,7 @@ (*p->binfmt->use_count)++; p->did_exec = 0; + p->swapping = 0; p->kernel_stack_page = 0; p->state = TASK_UNINTERRUPTIBLE; p->flags &= ~(PF_PTRACED|PF_TRACESYS);