diff -u --recursive --new-file v1.1.22/linux/Makefile linux/Makefile --- v1.1.22/linux/Makefile Mon Jun 27 16:46:57 1994 +++ linux/Makefile Mon Jun 27 00:03:30 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 22 +SUBLEVEL = 23 all: Version zImage diff -u --recursive --new-file v1.1.22/linux/boot/head.S linux/boot/head.S --- v1.1.22/linux/boot/head.S Thu Feb 3 12:37:44 1994 +++ linux/boot/head.S Sun Jun 26 23:52:53 1994 @@ -289,7 +289,7 @@ * data (18*2*512 bytes). */ _floppy_track_buffer: - .fill 512*2*18,1,0 + .fill 512*2*36,1,0 /* This is the default interrupt "handler" :-) */ int_msg: diff -u --recursive --new-file v1.1.22/linux/drivers/block/README.sbpcd linux/drivers/block/README.sbpcd --- v1.1.22/linux/drivers/block/README.sbpcd Thu Jun 9 18:56:09 1994 +++ linux/drivers/block/README.sbpcd Mon Jun 27 16:35:34 1994 @@ -1,11 +1,11 @@ -This README belongs to release 1.6 of the SoundBlaster Pro (Matsushita, +This README belongs to release 2.0 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 Matsushita/Kotobuki/Panasonic drives (the "double speed" versions like CR-562 and CR-563, too), and it will work with the soundcard interfaces (SB Pro, SB 16, Galaxy, SoundFX, ...) and/or with the "no-sound" cards (Panasonic -CI-101P, LaserMate, Aztech, ...). +CI-101P, LaserMate, WDH-7001C, Aztech, ...). It should work too now with the "configurable" interface "Sequoia S-1000", which is found on the Spea Media FX sound card. The interface type has to get configured in /usr/include/linux/sbpcd.h, @@ -16,7 +16,10 @@ (which count the releases around 0.75 or 1.00). Up to 4 drives are supported. CR-52x ("old") and CR-56x ("new") drives can be -mixed, but the CR-521 ones are hard-wired to drive ID 0. +mixed, but the CR-521 ones are hard-wired to drive ID 0. The drives have to +use different drive IDs, and each drive has to get a unique minor number +(0...3), corresponding to it's drive ID. The drive IDs may be selected freely +from 0 to 3 - they must not be in consecutive order. As Don Carroll, don@ds9.us.dell.com or FIDO 1:382/14, told me, it is possible to change old drives to any ID, too. He writes in this sense: @@ -35,17 +38,20 @@ did not work with other values. If the values are not good, ID 3 behaves like ID 0." -The drives have to use different drive IDs, but the same controller (it will -be a little bit harder to support up to four interface cards - but I plan to -do it the day somebody wishes to connect a fifth drive). -Each drive has to get a unique minor number (0...3), corresponding to it's -drive ID. The drive IDs may be selected freely from 0 to 3 - they must not be -in consecutive order. +To use more than 4 drives (now that the single-speed CR-521's are as cheap as +50$), you have to "duplicate" the driver. Just copy sbpcd.c into sbpcd2.c and +change SBPCD_ISSUE accordingly. The driver supports reading of data from the CD and playing of audio tracks. The audio part should run with WorkMan, xcdplayer, with the "non-X11" products CDplayer and WorkBone - tell me if it is not compatible with other software. +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 +one frame of 2352 bytes at a time. The transfer rate is as slow as 32 kB/sec. +This will get better, and the software interface may change. We have to +standardize it the day the SCSI driver supports it too. + MultiSession is supported (even my "old" CR-521 can handle it), "ManySession" (not recommended, see below) alternatively. Photo CDs work, too. At ftp.gwdg.de:/pub/linux/hpcdtoppm/ is Hadmut Danisch's @@ -106,6 +112,10 @@ So, if the DOS driver tells you have drive id #3, you have to mknod /dev/ b 25 3 + For a second interface board, you have to make nodes like + mknod /dev/sbpcd4 b 26 0 + and so on. Use the MAJORs 26, 27, 28. + If you further make a link like ln -s sbpcd /dev/cdrom you can use the name /dev/cdrom, too. @@ -142,7 +152,12 @@ If you enable this feature, it is impossible to read true multisession CDs. The driver uses the "variable BLOCK_SIZE" feature. To use it, you have to -specify "block=2048" as a mount option. +specify "block=2048" as a mount option. Doing this will disable the direct +execution of a binary from the CD; you have to copy it to a device with the +standard BLOCK_SIZE (1024) before. So, do not use this if your system is +directly "running from the CDROM" (like some of YGGDRASIL's installation +variants). There are CDs on the market (like the german "unifix" Linux +distribution) which MUST get handled with a block_size of 1024. Auto-probing at boot time: @@ -199,6 +214,133 @@ them without the need of supplying parameters. +Copying audio tracks: +--------------------- + +The following little program will copy track 2 of an audio CD into the file +"track02": + +/*=================== begin program ========================================*/ +/* + * read an audio track from a CD + * + * (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. + * + * This example program further is missing to obtain the SubChannel data + * which belong to each frame. + */ +#include +#include +#include + +static struct cdrom_tochdr hdr; +static struct cdrom_tocentry entry[100]; +static struct cdrom_read_audio arg; +static u_char buffer[CD_FRAMESIZE_RAW]; +static int datafile, drive; +static int i, j, limit, track, err; +static char filename[32]; + +main(int argc, char *argv[]) +{ +/* + * open /dev/cdrom + */ + drive=open("/dev/cdrom", 0); + if (drive<0) + { + fprintf(stderr, "can't open drive.\n"); + exit (-1); + } +/* + * get TocHeader + */ + fprintf(stdout, "getting TocHeader...\n"); + err=ioctl(drive, CDROMREADTOCHDR, &hdr); + if (err!=0) + { + fprintf(stderr, "can't get TocHeader (error %d).\n", err); + exit (-1); + } + else + fprintf(stdout, "TocHeader: %d %d\n", hdr.cdth_trk0, hdr.cdth_trk1); +/* + * get and display all TocEntries + */ + fprintf(stdout, "getting TocEntries...\n"); + for (i=1;i<=hdr.cdth_trk1;i++) + { + entry[i].cdte_track = i; + entry[i].cdte_format = CDROM_LBA; + err=ioctl(drive, CDROMREADTOCENTRY, &entry[i]); + if (err!=0) + { + fprintf(stderr, "can't get TocEntry #%d (error %d).\n", i, err); + exit (-1); + } + else + { + fprintf(stdout, "TocEntry #%d: %1X %1X %06X %02X\n", + entry[i].cdte_track, + entry[i].cdte_adr, + entry[i].cdte_ctrl, + entry[i].cdte_addr.lba, + entry[i].cdte_datamode); + } + } + fprintf(stdout, "got all TocEntries.\n"); +/* + * ask for track number (not implemented here) + */ +track=2; +#if 0 /* just read a little piece */ +entry[track].cdte_addr.lba=170; +entry[track+1].cdte_addr.lba=190; +#endif +/* + * read track into file + */ + sprintf(filename, "track%02d\0", track); + datafile=creat(filename, 0755); + if (datafile<0) + { + fprintf(stderr, "can't open datafile %s.\n", filename); + exit (-1); + } + arg.addr.lba=entry[track].cdte_addr.lba; + arg.addr_format=CDROM_LBA; /* CDROM_MSF is still buggy, I know that */ + arg.nframes=1; + arg.buf=&buffer[0]; + limit=entry[track+1].cdte_addr.lba; + for (i=arg.addr.lba;i #include @@ -77,6 +83,7 @@ #include #include +#include #include #include #include @@ -110,13 +117,14 @@ * Maximum disk size (in kilobytes). This default is used whenever the * current disk size is unknown. */ -#define MAX_DISK_SIZE 1440 +#define MAX_DISK_SIZE 2880 /* was 1440 -bb */ /* * Maximum number of sectors in a track buffer. Track buffering is disabled * if tracks are bigger. */ -#define MAX_BUFFER_SECTORS 18 +#define MAX_BUFFER_SECTORS 36 /* was 18 -bb */ + /* * The DMA channel used by the floppy controller cannot access data at @@ -154,6 +162,8 @@ { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,NULL }, /* 360kB in 1.2MB drive */ { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,NULL }, /* 720kB in 1.2MB drive */ { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }, /* 1.44MB diskette */ + { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,NULL }, /* 2.88MB diskette */ + { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,NULL }, /* 2.88MB diskette */ }; /* @@ -170,6 +180,10 @@ { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k" }, /* 3.5" 720kB diskette */ { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M" }, /* 1.44MB diskette */ { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k/AT" }, /* 3.5" 720kB diskette */ + { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"2.88M-AMI" }, /* DUMMY */ + { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M-AMI" }, /* Dummy */ + { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"2.88M" }, /* 2.88MB diskette */ + { 2880,18,2,80,0,0x1B,0x40,0xCF,0x6C,"1.44MX" }, /* 1.44MB diskette */ }; /* Auto-detection: Disk type used until the next media change occurs. */ @@ -186,13 +200,14 @@ static int floppy_sizes[] ={ MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE, - 360, 360 ,360, 360, + 360, 360, 360, 360, 1200,1200,1200,1200, 360, 360, 360, 360, 720, 720, 720, 720, 360, 360, 360, 360, 720, 720, 720, 720, - 1440,1440,1440,1440 + 1440,1440,1440,1440, + 2880,2880,2880,2880 /* -bb */ }; /* @@ -269,6 +284,11 @@ extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS]; static void redo_fd_request(void); +static void floppy_ready(void); +static void recalibrate_floppy(void); + +static int floppy_grab_irq_and_dma(void); +static void floppy_release_irq_and_dma(void); /* * These are global variables, as that's the easiest way to give @@ -290,10 +310,8 @@ static unsigned char seek_track = 0; static unsigned char current_track = NO_TRACK; static unsigned char command = 0; -static unsigned char fdc_version = FDC_TYPE_STD; /* FDC version code */ +static unsigned char fdc_version = 0x90; /* FDC version code */ -static void floppy_ready(void); - static void select_callback(unsigned long unused) { floppy_ready(); @@ -794,8 +812,6 @@ * Special case - used after a unexpected interrupt (or reset) */ -static void recalibrate_floppy(void); - static void recal_interrupt(void) { output_byte(FD_SENSEI); @@ -1237,7 +1253,7 @@ { struct floppy_struct *base; - if (code > 0 && code < 5) { + if (code > 0 && code < 7) { /* -bb*/ base = &floppy_types[(code-1)*2]; printk("fd%d is %s",drive,base->name); return base; @@ -1273,6 +1289,9 @@ int drive; int old_dev; + if (floppy_grab_irq_and_dma()) { + return -EBUSY; + } drive = inode->i_rdev & 3; old_dev = fd_device[drive]; if (fd_ref[drive]) @@ -1295,6 +1314,7 @@ printk("floppy_release with fd_ref == 0"); fd_ref[inode->i_rdev & 3] = 0; } + floppy_release_irq_and_dma(); } static struct file_operations floppy_fops = { @@ -1360,10 +1380,6 @@ timer_table[FLOPPY_TIMER].fn = floppy_shutdown; timer_active &= ~(1 << FLOPPY_TIMER); config_types(); - if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) - printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ); - if (request_dma(FLOPPY_DMA)) - printk("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA); /* Try to determine the floppy controller type */ DEVICE_INTR = ignore_interrupt; /* don't ask ... */ output_byte(FD_VERSION); /* get FDC version code */ @@ -1382,9 +1398,31 @@ * properly, so force a reset for the standard FDC clones, * to avoid interrupt garbage. */ - if (fdc_version == FDC_TYPE_STD) { initial_reset_flag = 1; reset_floppy(); } +} + +static int floppy_grab_irq_and_dma(void) +{ + if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) { + printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ); + return -1; + } + if (request_dma(FLOPPY_DMA)) { + printk("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA); + free_irq(FLOPPY_IRQ); + return -1; + } + enable_irq(FLOPPY_IRQ); + return 0; +} + +static void floppy_release_irq_and_dma(void) +{ + disable_dma(FLOPPY_DMA); + free_dma(FLOPPY_DMA); + disable_irq(FLOPPY_IRQ); + free_irq(FLOPPY_IRQ); } diff -u --recursive --new-file v1.1.22/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c --- v1.1.22/linux/drivers/block/sbpcd.c Thu Jun 9 18:56:11 1994 +++ linux/drivers/block/sbpcd.c Mon Jun 27 16:35:36 1994 @@ -5,7 +5,7 @@ * and for "no-sound" interfaces like Lasermate and the * Panasonic CI-101P. * - * NOTE: This is release 1.6. + * NOTE: This is release 2.0. * 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. @@ -92,6 +92,20 @@ * called as it should I fear it must get synchronized for not to * disturb the normal driver's activity. * + * 2.0 Version number bumped - two reasons: + * - reading audio tracks as data works now with CR-562 and CR-563. We + * currently do it by an IOCTL (yet has to get standardized), one frame + * at a time; that is pretty slow. But it works. + * - we are maintaining now up to 4 interfaces (each up to 4 drives): + * did it the easy way - a different MAJOR (25, 26, ...) and a different + * copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only + * distinguished by the value of SBPCD_ISSUE and the driver's name), + * and a common sbpcd.h file. + * Bettered the "ReadCapacity error" problem with old CR-52x drives (the + * drives sometimes need a manual "eject/insert" before work): just + * reset the drive and do again. Needs lots of resets here and sometimes + * that does not cure, so this can't be the solution. + * * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine * elaborated speed-up experiments (and the fabulous results!), for * the "push" towards load-free wait loops, and for the extensive mail @@ -123,6 +137,8 @@ * */ +#define SBPCD_ISSUE 1 /* change to 2, 3, 4 for multiple interface boards */ + #include #include @@ -133,18 +149,30 @@ #include #include #include +#include #include #include -#include #include #include #include #include +#if !(SBPCD_ISSUE-1) #define MAJOR_NR MATSUSHITA_CDROM_MAJOR +#endif +#if !(SBPCD_ISSUE-2) +#define MAJOR_NR MATSUSHITA_CDROM2_MAJOR /* second driver issue */ +#endif +#if !(SBPCD_ISSUE-3) +#define MAJOR_NR MATSUSHITA_CDROM3_MAJOR /* third driver issue */ +#endif +#if !(SBPCD_ISSUE-4) +#define MAJOR_NR MATSUSHITA_CDROM4_MAJOR /* fourth driver issue */ +#endif + #include "blk.h" -#define VERSION "1.6 Eberhard Moenkeberg " +#define VERSION "2.0 Eberhard Moenkeberg " #define SBPCD_DEBUG @@ -170,11 +198,64 @@ #define XA_TEST2 #define TEST_UPC 0 -#define READ_AUDIO 0 /* does not work today (the drives won't read audio) */ - -/*==========================================================================*/ +#define READ_AUDIO 1 +#define SPEA_TEST 0 +#define PRINTK_BUG 0 +#define TEST_STI 0 +/*==========================================================================*/ +/* + * provisions for more than 1 driver issues + * currently up to 4 drivers, expandable + */ +#if !(SBPCD_ISSUE-1) +#define SBPCD_IOCTL_F sbpcd_ioctl +#define SBPCD_IOCTL(a,b,c,d) sbpcd_ioctl(a,b,c,d) +#define DO_SBPCD_REQUEST(a) do_sbpcd_request(a) +#define SBPCD_OPEN_F sbpcd_open +#define SBPCD_OPEN(a,b) sbpcd_open(a,b) +#define SBPCD_RELEASE_F sbpcd_release +#define SBPCD_RELEASE(a,b) sbpcd_release(a,b) +#define SBPCD_SETUP(a,b) sbpcd_setup(a,b) +#define SBPCD_INIT(a,b) sbpcd_init(a,b) +#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd_media_change(a,b) +#endif +#if !(SBPCD_ISSUE-2) +#define SBPCD_IOCTL_F sbpcd2_ioctl +#define SBPCD_IOCTL(a,b,c,d) sbpcd2_ioctl(a,b,c,d) +#define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a) +#define SBPCD_OPEN_F sbpcd2_open +#define SBPCD_OPEN(a,b) sbpcd2_open(a,b) +#define SBPCD_RELEASE_F sbpcd2_release +#define SBPCD_RELEASE(a,b) sbpcd2_release(a,b) +#define SBPCD_SETUP(a,b) sbpcd2_setup(a,b) +#define SBPCD_INIT(a,b) sbpcd2_init(a,b) +#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd2_media_change(a,b) +#endif +#if !(SBPCD_ISSUE-3) +#define SBPCD_IOCTL_F sbpcd3_ioctl +#define SBPCD_IOCTL(a,b,c,d) sbpcd3_ioctl(a,b,c,d) +#define DO_SBPCD_REQUEST(a) do_sbpcd3_request(a) +#define SBPCD_OPEN_F sbpcd3_open +#define SBPCD_OPEN(a,b) sbpcd3_open(a,b) +#define SBPCD_RELEASE_F sbpcd3_release +#define SBPCD_RELEASE(a,b) sbpcd3_release(a,b) +#define SBPCD_SETUP(a,b) sbpcd3_setup(a,b) +#define SBPCD_INIT(a,b) sbpcd3_init(a,b) +#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd3_media_change(a,b) +#endif +#if !(SBPCD_ISSUE-4) +#define SBPCD_IOCTL_F sbpcd4_ioctl +#define SBPCD_IOCTL(a,b,c,d) sbpcd4_ioctl(a,b,c,d) +#define DO_SBPCD_REQUEST(a) do_sbpcd4_request(a) +#define SBPCD_OPEN_F sbpcd4_open +#define SBPCD_OPEN(a,b) sbpcd4_open(a,b) +#define SBPCD_RELEASE_F sbpcd4_release +#define SBPCD_RELEASE(a,b) sbpcd4_release(a,b) +#define SBPCD_SETUP(a,b) sbpcd4_setup(a,b) +#define SBPCD_INIT(a,b) sbpcd4_init(a,b) +#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd4_media_change(a,b) +#endif /*==========================================================================*/ - #if MANY_SESSION #undef LONG_TIMING #define LONG_TIMING 1 @@ -215,8 +296,6 @@ 0x340, 0, /* Lasermate, CI-101P */ 0x360, 0, /* Lasermate, CI-101P */ 0x270, 1, /* Soundblaster 16 */ - 0x630, 0, /* "sound card #9" (default) */ - 0x650, 0, /* "sound card #9" */ 0x670, 0, /* "sound card #9" */ 0x690, 0, /* "sound card #9" */ 0x330, 2, /* SPEA Media FX (default) */ @@ -230,6 +309,9 @@ 0x370, 0, /* Lasermate, CI-101P */ 0x290, 1, /* Soundblaster 16 */ 0x310, 0, /* Lasermate, CI-101P */ +/* excluded due to incomplete address decoding of the SbPro card */ + 0x630, 0, /* "sound card #9" (default) */ + 0x650, 0, /* "sound card #9" */ #endif }; @@ -242,6 +324,7 @@ */ static void sbp_read_cmd(void); static int sbp_data(void); +static int cmd_out(void); /*==========================================================================*/ @@ -273,22 +356,28 @@ * (1<=0) break; + DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadCapacity #%d returns %d\n", j, i)); + i=DriveReset(); } + if (j==LOOP_COUNT) return (-2); /* give up */ + i=xx_ReadTocDescr(); if (i<0) { @@ -2220,8 +2320,8 @@ /* * ioctl support, adopted from scsi/sr_ioctl.c and mcd.c */ -static int sbpcd_ioctl(struct inode *inode,struct file *file, - u_int cmd, u_long arg) +static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, + u_long arg) { int i, st; @@ -2472,7 +2572,7 @@ DriveStruct[d].mode=READ_M1; return (0); - case CDROMREADMODE2: + case CDROMREADMODE2: /* not useable at the moment */ DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE2 requested.\n")); xx_ModeSelect(CD_FRAMESIZE_XA); xx_ModeSense(); @@ -2482,214 +2582,188 @@ #if READ_AUDIO case CDROMREADAUDIO: { /* start of CDROMREADAUDIO */ - - int i=0, j=0, frame, block; - u_int try=0; - u_long timeout; - u_char *p; - u_int data_tries = 0; - u_int data_waits = 0; - u_int data_retrying = 0; - int status_tries; - int error_flag; - struct cdrom_aud aud_arg; - - error_flag=0; - -#if 0 -#define AUD_FRM_SIZ CD_FRAMESIZE_RAW -#else -#define AUD_FRM_SIZ CD_FRAMESIZE_XA -#endif - - DPRINTF((DBG_IOC,"SBPCD: read_audio: ioctl: CDROMREADAUDIO requested.\n")); - - i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_aud)); - if (i) return (i); - memcpy_fromfs(&aud_arg, (void *) arg, sizeof(struct cdrom_aud)); - i=verify_area(VERIFY_WRITE, aud_arg.buf, AUD_FRM_SIZ); - if (i) return (i); - DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, buffer: %08X\n", aud_arg.lba, aud_arg.buf)); - - DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n")); - for (data_tries=5; data_tries>0; data_tries--) - { - DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries)); - DriveStruct[d].mode=READ_AU; - xx_ModeSelect(AUD_FRM_SIZ); - xx_ModeSense(); - - - for (status_tries=3; status_tries > 0; status_tries--) - { - flags_cmd_out |= f_respo3; - xx_ReadStatus(); - if (sbp_status() != 0) break; - sbp_sleep(1); /* wait a bit, try again */ - } - if (status_tries == 0) - { - DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: failed after 3 tries.\n")); - continue; - } - DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: ok.\n")); - - - block=aud_arg.lba; - flags_cmd_out = f_putcmd | - f_respo2 | - f_ResponseStatus | - f_obey_p_check; - - - - - if (!new_drive) - { - flags_cmd_out |= f_lopsta | f_getsta | f_bit1; - cmd_type=READ_M2; - drvcmd[0]=0x03; /* "read XA frames" command for old drives */ - drvcmd[1]=(block>>16)&0x000000ff; - drvcmd[2]=(block>>8)&0x000000ff; - drvcmd[3]=block&0x000000ff; - drvcmd[4]=0; - drvcmd[5]=1; /* # of frames */ - drvcmd[6]=0; - } - else /* if new_drive */ - { - drvcmd[0]=0x10; /* "read frames" command for new drives */ - lba2msf(block,&drvcmd[1]); /* msf-bin format required */ - drvcmd[4]=0; - drvcmd[5]=0; - drvcmd[6]=1; /* # of frames */ - } - - - - DPRINTF((DBG_AUD,"SBPCD: read_audio: before giving \"read\" command.\n")); - for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]); - - sbp_sleep(0); - - DPRINTF((DBG_AUD,"SBPCD: read_audio: after giving \"read\" command.\n")); - for (frame=1;frame<2 && !error_flag; frame++) - { - try=maxtim_data; - for (timeout=jiffies+900; ; ) - { - for ( ; try!=0;try--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) break; - if (!(j&s_not_result_ready)) break; - if (!new_drive) if (j&s_attention) break; - } - if (try != 0 || timeout <= jiffies) break; - if (data_retrying == 0) data_waits++; - data_retrying = 1; - sbp_sleep(1); - try = 1; - } - if (try==0) - { - DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status timeout.\n")); - error_flag++; - break; - } - DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status ok.\n")); - - if (j&s_not_data_ready) - { - printk("SBPCD: read_audio: sbp_data: DATA_READY timeout.\n"); - error_flag++; - break; - } - - DPRINTF((DBG_AUD,"SBPCD: read_audio: before reading data.\n")); - CLEAR_TIMER; - error_flag=0; - p = DriveStruct[d].aud_buf; - if (sbpro_type==1) OUT(CDo_sel_d_i,0x01); - READ_DATA(CDi_data, p, AUD_FRM_SIZ); - if (sbpro_type==1) OUT(CDo_sel_d_i,0x00); - data_retrying = 0; - } - DPRINTF((DBG_AUD,"SBPCD: read_audio: after reading data.\n")); - if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */ - { - DPRINTF((DBG_AUD,"SBPCD: read_audio: read aborted by drive\n")); + int i=0, j=0, frame, block; + u_int try=0; + u_long timeout; + u_char *p; + u_int data_tries = 0; + u_int data_waits = 0; + u_int data_retrying = 0; + int status_tries; + int error_flag; + + error_flag=0; + + DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n")); + + i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio)); + if (i) return (i); + memcpy_fromfs(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio)); + i=verify_area(VERIFY_WRITE, read_audio.buf, CD_FRAMESIZE_RAW); + if (i) return (i); + + if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */ + block=msf2blk(read_audio.addr.lba); + else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */ + block=read_audio.addr.lba; + else return (-EINVAL); + if (read_audio.nframes!=1) return (-EINVAL); + DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, msf: %06X\n", + block, blk2msf(block))); + DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n")); + for (data_tries=5; data_tries>0; data_tries--) + { + DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries)); + DriveStruct[d].mode=READ_AU; + xx_ModeSelect(CD_FRAMESIZE_RAW); + xx_ModeSense(); + for (status_tries=3; status_tries > 0; status_tries--) + { + flags_cmd_out |= f_respo3; + xx_ReadStatus(); + if (sbp_status() != 0) break; + sbp_sleep(1); /* wait a bit, try again */ + } + if (status_tries == 0) + { + DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: failed after 3 tries.\n")); + continue; + } + DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: ok.\n")); + + flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; + if (!new_drive) + { + flags_cmd_out |= f_lopsta | f_getsta | f_bit1; + cmd_type=READ_M2; + drvcmd[0]=0x03; /* "read XA frames" command for old drives */ + drvcmd[1]=(block>>16)&0x000000ff; + drvcmd[2]=(block>>8)&0x000000ff; + drvcmd[3]=block&0x000000ff; + drvcmd[4]=0; + drvcmd[5]=1; /* # of frames */ + drvcmd[6]=0; + } + else /* if new_drive */ + { + drvcmd[0]=0x10; /* "read frames" command for new drives */ + lba2msf(block,&drvcmd[1]); /* msf-bin format required */ + drvcmd[4]=0; + drvcmd[5]=0; + drvcmd[6]=1; /* # of frames */ + } + DPRINTF((DBG_AUD,"SBPCD: read_audio: before giving \"read\" command.\n")); + for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]); + sbp_sleep(0); + DPRINTF((DBG_AUD,"SBPCD: read_audio: after giving \"read\" command.\n")); + for (frame=1;frame<2 && !error_flag; frame++) + { + try=maxtim_data; + for (timeout=jiffies+900; ; ) + { + for ( ; try!=0;try--) + { + j=inb(CDi_status); + if (!(j&s_not_data_ready)) break; + if (!(j&s_not_result_ready)) break; + if (!new_drive) if (j&s_attention) break; + } + if (try != 0 || timeout <= jiffies) break; + if (data_retrying == 0) data_waits++; + data_retrying = 1; + sbp_sleep(1); + try = 1; + } + if (try==0) + { + DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status timeout.\n")); + error_flag++; + break; + } + DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: CDi_status ok.\n")); + if (j&s_not_data_ready) + { + printk("SBPCD: read_audio: sbp_data: DATA_READY timeout.\n"); + error_flag++; + break; + } + DPRINTF((DBG_AUD,"SBPCD: read_audio: before reading data.\n")); + CLEAR_TIMER; + error_flag=0; + p = DriveStruct[d].aud_buf; + if (sbpro_type==1) OUT(CDo_sel_d_i,0x01); + READ_DATA(CDi_data, p, CD_FRAMESIZE_RAW); + if (sbpro_type==1) OUT(CDo_sel_d_i,0x00); + data_retrying = 0; + } + DPRINTF((DBG_AUD,"SBPCD: read_audio: after reading data.\n")); + if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */ + { + DPRINTF((DBG_AUD,"SBPCD: read_audio: read aborted by drive\n")); #if 0000 - i=DriveReset(); /* ugly fix to prevent a hang */ + i=DriveReset(); /* ugly fix to prevent a hang */ #endif 0000 - continue; - } - - if (!new_drive) - { - i=maxtim_data; - for (timeout=jiffies+900; timeout > jiffies; timeout--) - { - for ( ;i!=0;i--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) break; - if (!(j&s_not_result_ready)) break; - if (j&s_attention) break; - } - if (i != 0 || timeout <= jiffies) break; - sbp_sleep(0); - i = 1; - } - if (i==0) { DPRINTF((DBG_AUD,"SBPCD: read_audio: STATUS TIMEOUT AFTER READ")); } - if (!(j&s_attention)) - { - DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n")); - i=DriveReset(); /* ugly fix to prevent a hang */ + continue; + } + if (!new_drive) + { + i=maxtim_data; + for (timeout=jiffies+900; timeout > jiffies; timeout--) + { + for ( ;i!=0;i--) + { + j=inb(CDi_status); + if (!(j&s_not_data_ready)) break; + if (!(j&s_not_result_ready)) break; + if (j&s_attention) break; + } + if (i != 0 || timeout <= jiffies) break; + sbp_sleep(0); + i = 1; + } + if (i==0) { DPRINTF((DBG_AUD,"SBPCD: read_audio: STATUS TIMEOUT AFTER READ")); } + if (!(j&s_attention)) + { + DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n")); + i=DriveReset(); /* ugly fix to prevent a hang */ continue; - } - } - - do - { - if (!new_drive) xx_ReadStatus(); - i=ResponseStatus(); /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */ - if (i<0) { DPRINTF((DBG_AUD, - "SBPCD: read_audio: xx_ReadStatus error after read: %02X\n", - DriveStruct[d].status_byte)); - continue; /* FIXME */ - } - } - while ((!new_drive)&&(!st_check)&&(!(i&p_success_old))); - if (st_check) - { - i=xx_ReadError(); - DPRINTF((DBG_AUD,"SBPCD: read_audio: xx_ReadError was necessary after read: %02X\n",i)); - continue; - } - memcpy_tofs((u_char *) aud_arg.buf, - (u_char *) DriveStruct[d].aud_buf, AUD_FRM_SIZ); - DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n")); - break; - } - xx_ModeSelect(CD_FRAMESIZE); - xx_ModeSense(); - DriveStruct[d].mode=READ_M1; - - - if (data_tries == 0) - { - DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n")); - return (-8); - } - DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n")); - return (0); - } /* end of CDROMREADAUDIO */ + } + } + do + { + if (!new_drive) xx_ReadStatus(); + i=ResponseStatus(); /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */ + if (i<0) { DPRINTF((DBG_AUD, + "SBPCD: read_audio: xx_ReadStatus error after read: %02X\n", + DriveStruct[d].status_byte)); + continue; /* FIXME */ + } + } + while ((!new_drive)&&(!st_check)&&(!(i&p_success_old))); + if (st_check) + { + i=xx_ReadError(); + DPRINTF((DBG_AUD,"SBPCD: read_audio: xx_ReadError was necessary after read: %02X\n",i)); + continue; + } + memcpy_tofs((u_char *) read_audio.buf, + (u_char *) DriveStruct[d].aud_buf, CD_FRAMESIZE_RAW); + DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n")); + break; + } + xx_ModeSelect(CD_FRAMESIZE); + xx_ModeSense(); + DriveStruct[d].mode=READ_M1; + if (data_tries == 0) + { + DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n")); + return (-8); + } + DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n")); + return (0); + } /* end of CDROMREADAUDIO */ #endif READ_AUDIO - - - case BLKRASET: if(!suser()) return -EACCES; if(!inode->i_rdev) return -EINVAL; @@ -2726,7 +2800,7 @@ /* * I/O request routine, called from Linux kernel. */ -static void do_sbpcd_request(void) +static void DO_SBPCD_REQUEST(void) { u_int block; int dev; @@ -2836,7 +2910,7 @@ block=DriveStruct[d].lba_multi+block; } #else - if ( (block==166) && (DriveStruct[d].f_multisession) && (multisession_valid) ) + if ( (block==CD_BLOCK_OFFSET+16) && (DriveStruct[d].f_multisession) && (multisession_valid) ) { DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n", blk2msf(DriveStruct[d].lba_multi+16), @@ -3064,7 +3138,7 @@ /* * Open the device special file. Check that a disk is in. Read TOC. */ -int sbpcd_open(struct inode *ip, struct file *fp) +int SBPCD_OPEN(struct inode *ip, struct file *fp) { int i; @@ -3100,8 +3174,12 @@ */ DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n", DriveStruct[d].open_count,DriveStruct[d].open_count+1)); - if (++DriveStruct[d].open_count==1) yy_LockDoor(1); - + if (++DriveStruct[d].open_count==1) + { + do + i=yy_LockDoor(1); + while (i!=0); + } if (!st_spinning) xx_SpinUp(); i=DiskInfo(); @@ -3113,7 +3191,7 @@ /* * On close, we flush all sbp blocks from the buffer cache. */ -static void sbpcd_release(struct inode * ip, struct file * file) +static void SBPCD_RELEASE(struct inode * ip, struct file * file) { int i; @@ -3153,10 +3231,10 @@ block_write, /* write - general block-dev write */ NULL, /* readdir - bad */ NULL, /* select */ - sbpcd_ioctl, /* ioctl */ + SBPCD_IOCTL_F, /* ioctl */ NULL, /* mmap */ - sbpcd_open, /* open */ - sbpcd_release, /* release */ + SBPCD_OPEN_F, /* open */ + SBPCD_RELEASE_F, /* release */ NULL, /* fsync */ NULL /* fasync */ }; @@ -3178,7 +3256,7 @@ * not the soundcard base address. * */ -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; @@ -3208,7 +3286,7 @@ * -> interface type "Matsushita/Panasonic" (not Sony or Mitsumi) * -> I/O base address (0x320, 0x330, 0x340, 0x350) */ -int config_spea(void) +static int config_spea(void) { int n_ports=0x10; /* 2:0x00, 8:0x10, 16:0x20, 32:0x30 */ int irq_number=0; /* 2:0x01, 7:0x03, 12:0x05, 15:0x07, OFF:0x00 */ @@ -3225,7 +3303,7 @@ i=inb(SPEA_REG_1); if (i!=0x0F) { - DPRINTF((DBG_INF,"SBPCD: no SPEA interface at %04X present.\n", + DPRINTF((DBG_SEQ,"SBPCD: no SPEA interface at %04X present.\n", sbpcd_ioaddr)); return (-1); /* no interface found */ } @@ -3249,18 +3327,22 @@ OUT(SPEA_REG_2,i); sbpro_type = 0; /* acts like a LaserMate interface now */ + DPRINTF((DBG_SEQ,"SBPCD: found SPEA interface at %04X.\n", + sbpcd_ioaddr)); return (0); } /*==========================================================================*/ /* * Test for presence of drive and initialize it. Called at boot time. */ -u_long sbpcd_init(u_long mem_start, u_long mem_end) +unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end) { int i=0, j=0; int addr[2]={1, CDROM_PORT}; int port_index; + sti(); /* necessary, has consequences for other drivers' init routines */ + DPRINTF((DBG_INF,"SBPCD version %s\n", VERSION)); DPRINTF((DBG_INF,"SBPCD: Looking for a SoundBlaster/Matsushita CD-ROM drive\n")); @@ -3279,7 +3361,6 @@ DPRINTF((DBG_WRN,"SBPCD: with your REAL address.\n")); DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = END of WARNING = = = = = = = = = =\n")); DPRINTF((DBG_WRN,"SBPCD: \n")); - sti(); /* to avoid possible "printk" bug */ autoprobe[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */ autoprobe[1]=sbpro_type; /* possibly changed by kernel command line */ @@ -3288,48 +3369,54 @@ { addr[1]=autoprobe[port_index]; if (check_region(addr[1],4)) continue; - DPRINTF((DBG_INI,"SBPCD: check_region done.\n")); + DPRINTF((DBG_INI,"SBPCD: check_region: free.\n")); 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)); DPRINTF((DBG_INF,"SBPCD: - ")); - sti(); /* to avoid possible "printk" bug */ if (autoprobe[port_index+1]==2) { i=config_spea(); - if (i<0) continue; + if (i<0) + { + DPRINTF((DBG_INF,"\n")); + continue; + } } i=check_drives(); DPRINTF((DBG_INI,"SBPCD: check_drives done.\n")); - sti(); /* to avoid possible "printk" bug */ if (i>=0) break; /* drive found */ DPRINTF((DBG_INF,"\n")); - sti(); /* to avoid possible "printk" bug */ } /* end of cycling through the set of possible I/O port addresses */ if (ndrives==0) { printk("SBPCD: No drive found.\n"); - sti(); +#if PRINTK_BUG + sti(); /* to avoid possible "printk" bug */ +#endif return (mem_start); } if (port_index>0) { printk("SBPCD: You should configure sbpcd.h for your hardware.\n"); - sti(); +#if PRINTK_BUG + sti(); /* to avoid possible "printk" bug */ +#endif } printk("SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n", ndrives, type, CDo_command); +#if PRINTK_BUG sti(); /* to avoid possible "printk" bug */ +#endif check_datarate(); DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n")); - sti(); /* to avoid possible "printk" bug */ for (j=0;jread_wait) - tty->minimum_to_wake = MIN_CHAR(tty) ? - MIN_CHAR(tty) : 1; + if (!tty->read_wait) { + if (MIN_CHAR(tty) && !TIME_CHAR(tty)) + tty->minimum_to_wake = MIN_CHAR(tty); + else + tty->minimum_to_wake = 1; + } select_wait(&tty->read_wait, wait); return 0; case SEL_OUT: diff -u --recursive --new-file v1.1.22/linux/fs/exec.c linux/fs/exec.c --- v1.1.22/linux/fs/exec.c Tue Jun 21 14:16:23 1994 +++ linux/fs/exec.c Sun Jun 26 22:36:51 1994 @@ -255,13 +255,13 @@ dump_start = dump.u_tsize << 12; dump_size = dump.u_dsize << 12; DUMP_WRITE(dump_start,dump_size); - }; + } /* Now prepare to dump the stack area */ if (dump.u_ssize != 0) { dump_start = dump.start_stack; dump_size = dump.u_ssize << 12; DUMP_WRITE(dump_start,dump_size); - }; + } /* Finally dump the task struct. Not be used by gdb, but could be useful */ set_fs(KERNEL_DS); DUMP_WRITE(current,sizeof(*current)); @@ -854,8 +854,8 @@ if (error != N_TXTADDR(ex)) { sys_close(fd); send_sig(SIGSEGV, current, 0); - return 0; - }; + return -EINVAL; + } } error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data, @@ -864,8 +864,8 @@ sys_close(fd); if (error != N_TXTADDR(ex) + ex.a_text) { send_sig(SIGSEGV, current, 0); - return 0; - }; + return -EINVAL; + } current->executable = bprm->inode; bprm->inode->i_count++; } diff -u --recursive --new-file v1.1.22/linux/fs/msdos/misc.c linux/fs/msdos/misc.c --- v1.1.22/linux/fs/msdos/misc.c Tue Apr 19 10:53:24 1994 +++ linux/fs/msdos/misc.c Sun Jun 26 23:50:58 1994 @@ -18,6 +18,7 @@ "EXECOMBINAPPSYSDRVOVLOVROBJLIBDLLPIF" /* program code */ "ARCZIPLHALZHZOOTARZ ARJ" /* common archivers */ "TZ TAZTZPTPZ" /* abbreviations of tar.Z and tar.zip */ + "GZ TGZDEB" /* .gz, .tar.gz and Debian packages */ "GIFBMPTIFGL JPGPCX" /* graphics */ "TFMVF GF PK PXLDVI"; /* TeX */ diff -u --recursive --new-file v1.1.22/linux/fs/proc/array.c linux/fs/proc/array.c --- v1.1.22/linux/fs/proc/array.c Tue May 24 00:34:54 1994 +++ linux/fs/proc/array.c Mon Jun 27 14:57:46 1994 @@ -466,6 +466,7 @@ extern int get_module_list(char *); extern int get_device_list(char *); extern int get_filesystem_list(char *); +extern int get_ksyms_list(char *); static int array_read(struct inode * inode, struct file * file,char * buf, int count) { @@ -528,6 +529,9 @@ break; case 19: length = get_filesystem_list(page); + break; + case 20: + length = get_ksyms_list(page); break; default: free_page((unsigned long) page); diff -u --recursive --new-file v1.1.22/linux/fs/proc/root.c linux/fs/proc/root.c --- v1.1.22/linux/fs/proc/root.c Sat May 7 14:54:10 1994 +++ linux/fs/proc/root.c Mon Jun 27 14:57:45 1994 @@ -69,6 +69,7 @@ {17,4,"stat" }, {18,7,"devices" }, {19,11,"filesystems" }, + {20,5,"ksyms" }, }; #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0]))) diff -u --recursive --new-file v1.1.22/linux/include/linux/cdrom.h linux/include/linux/cdrom.h --- v1.1.22/linux/include/linux/cdrom.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/cdrom.h Mon Jun 27 16:35:36 1994 @@ -1,7 +1,8 @@ /**************************************************************************************** * * - * SCSI header library for linux * + * general (not only SCSI) header library for linux CDROM drivers * * (C) 1992 David Giller rafetmad@oxy.edu * + * 1994 Eberhard Moenkeberg emoenke@gwdg.de ("read audio" and some other stuff) * * * * -- CD-ROM IOCTLs and structs * * * @@ -11,6 +12,20 @@ #define _LINUX_CDROM_H /* + * some fix numbers + */ +#define CD_MINS 75 /* minutes per CD */ +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ +#define CD_FRAMESIZE 2048 /* bytes per frame, cooked 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 */ +#define CD_BLOCK_OFFSET 150 /* offset of first logical frame */ +#define CD_XA_HEAD 12 /* header size of XA frame */ +#define CD_XA_TAIL 280 /* tail size of XA frame */ + +/* * * For IOCTL calls, we will commandeer byte 0x53, or 'S'. * @@ -295,6 +310,28 @@ int cdread_buflen; }; +/* + * preliminary extensions for transfering audio frames + * currently used by sbpcd.c + * (still may change if other drivers will use it, too): + */ +struct cdrom_read_audio + { + union + { + struct + { + u_char minute; + u_char second; + u_char frame; + } msf; + int lba; + } addr; /* frame address */ + u_char addr_format; /* CDROM_LBA or CDROM_MSF */ + int nframes; /* number of 2352-byte-frames to read at once, currently only 1 allowed */ + u_char *buf; /* frame buffer (size: nframes*2352 bytes) */ + }; + #ifdef FIVETWELVE #define CDROM_MODE1_SIZE 512 #else @@ -309,7 +346,7 @@ #define CDROMPAUSE 0x5301 /* pause */ #define CDROMRESUME 0x5302 /* resume */ -#define CDROMPLAYMSF 0x5303 /* (stuct cdrom_msf) */ +#define CDROMPLAYMSF 0x5303 /* (struct cdrom_msf) */ /* SCMD_PLAY_AUDIO_MSF */ #define CDROMPLAYTRKIND 0x5304 /* (struct cdrom_ti) */ @@ -336,5 +373,12 @@ #define CDROMREADMODE1 0x530d /* (struct cdrom_read) */ /* read type-1 data */ +/* + * preliminary extension for transfering audio frames + * currently used by sbpcd.c + * (still may change if other drivers will use it, too): + */ +#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */ #endif _LINUX_CDROM_H + diff -u --recursive --new-file v1.1.22/linux/include/linux/module.h linux/include/linux/module.h --- v1.1.22/linux/include/linux/module.h Sun Dec 12 13:48:27 1993 +++ linux/include/linux/module.h Mon Jun 27 14:56:58 1994 @@ -1,5 +1,7 @@ /* * Dynamic loading of modules into the kernel. + * + * Modified by Bjorn Ekwall */ #ifndef _LINUX_MODULE_H @@ -16,9 +18,36 @@ /* maximum length of symbol name */ #define SYM_MAX_NAME 60 +struct kernel_sym { /* sent to "insmod" */ + unsigned long value; /* value of symbol */ + char name[SYM_MAX_NAME]; /* name of symbol */ +}; + +struct module_ref { + struct module *module; + struct module_ref *next; +}; + +struct internal_symbol { + void *addr; + char *name; + }; + +struct symbol_table { /* received from "insmod" */ + int size; /* total, including string table!!! */ + int n_symbols; + int n_refs; + struct internal_symbol symbol[0]; /* actual size defined by n_symbols */ + struct module_ref ref[0]; /* actual size defined by n_refs */ +}; +/* + * Note: The string table follows immediately after the symbol table in memory! + */ struct module { struct module *next; + struct module_ref *ref; /* the list of modules that refer to me */ + struct symbol_table *symtab; char *name; int size; /* size of module in pages */ void* addr; /* address of module */ @@ -26,19 +55,13 @@ void (*cleanup)(void); /* cleanup routine */ }; - struct mod_routines { int (*init)(void); /* initialization routine */ void (*cleanup)(void); /* cleanup routine */ }; - -struct kernel_sym { - unsigned long value; /* value of symbol */ - char name[SYM_MAX_NAME]; /* name of symbol */ -}; - -extern struct module *module_list; +/* rename_module_symbol(old_name, new_name) WOW! */ +extern int rename_module_symbol(char *, char *); /* diff -u --recursive --new-file v1.1.22/linux/include/linux/sbpcd.h linux/include/linux/sbpcd.h --- v1.1.22/linux/include/linux/sbpcd.h Thu Jun 9 18:56:12 1994 +++ linux/include/linux/sbpcd.h Mon Jun 27 16:35:36 1994 @@ -10,11 +10,25 @@ * sbpcd=0x300,LaserMate * or * sbpcd=0x330,SPEA - * these strings are case sensitive !!! + * + * and, if you have a second CDROM controller board, + * sbpcd2=0x310,LaserMate + * and so on. + * + * These strings are case sensitive !!! */ -/* - * change this to select the type of your interface board: +/* + * put your CDROM port base address into CDROM_PORT + * and specify the type of your interface in SBPRO. + * + * SBPRO addresses typically are 0x0230 (=0x220+0x10), 0x0250, ... + * LASERMATE (CI-101P) adresses typically are 0x0300, 0x0310, ... + * SPEA addresses are 0x320, 0x330, 0x340, 0x350 + * there are some soundcards on the market with 0x0630, 0x0650, ... + * + * example: if your SBPRO audio address is 0x220, specify 0x230. + * * * set SBPRO to 1 for "true" SoundBlaster card * set SBPRO to 0 for "poor" (no sound) interface cards @@ -30,26 +44,65 @@ * (currently I do not know any "compatible" with SBPRO 1) * then I can include better information with the next release. */ +#if !(SBPCD_ISSUE-1) /* first (or if you have only one) interface board: */ +#define CDROM_PORT 0x0230 #define SBPRO 1 +#endif +/* ignore the rest if you have only one interface board & driver */ + +#if !(SBPCD_ISSUE-2) /* second interface board: */ +#define CDROM_PORT 0x0370 +#define SBPRO 0 +#endif +#if !(SBPCD_ISSUE-3) /* third interface board: */ +#define CDROM_PORT 0x0330 +#define SBPRO 0 +#endif +#if !(SBPCD_ISSUE-4) /* fourth interface board: */ +#define CDROM_PORT 0x0340 +#define SBPRO 0 +#endif + +/*==========================================================================*/ +/*==========================================================================*/ /* - * put your CDROM port base address here: - * SBPRO addresses typically are 0x0230 (=0x220+0x10), 0x0250, ... - * LASERMATE (CI-101P) adresses typically are 0x0300, 0x0310, ... - * SPEA addresses are 0x320, 0x330, 0x340, 0x350 - * there are some soundcards on the market with 0x0630, 0x0650, ... - * - * example: if your SBPRO audio address is 0x220, specify 0x230. - * + * nothing to change below here if you are not experimenting */ -#define CDROM_PORT 0x0230 +#ifndef _LINUX_SBPCD_H +#define _LINUX_SBPCD_H /*==========================================================================*/ /*==========================================================================*/ /* - * nothing to change below here if you are not experimenting + * to fork and execute a function after some elapsed time: + * one "jifs" unit is 10 msec. */ +#undef MY_TIMER +#undef SET_TIMER +#undef CLEAR_TIMER + +#if !(SBPCD_ISSUE-1) +#define MY_TIMER SBPCD_TIMER +#endif +#if !(SBPCD_ISSUE-2) +#define MY_TIMER SBPCD2_TIMER +#endif +#if !(SBPCD_ISSUE-3) +#define MY_TIMER SBPCD3_TIMER +#endif +#if !(SBPCD_ISSUE-4) +#define MY_TIMER SBPCD4_TIMER +#endif + +#define SET_TIMER(func, jifs) \ + ((timer_table[MY_TIMER].expires = jiffies + jifs), \ + (timer_table[MY_TIMER].fn = func), \ + (timer_active |= 1< */ #include @@ -16,12 +19,16 @@ #include #include #include +#include #ifdef CONFIG_INET #include #endif + +#include extern void *sys_call_table; +/* must match struct internal_symbol !!! */ #define X(name) { (void *) &name, "_" #name } #ifdef CONFIG_FTAPE @@ -53,12 +60,14 @@ extern int dev_rint(unsigned char *, long, int, struct device *); extern void dev_tint(struct device *); extern struct device *irq2dev_map[]; +extern void dev_kfree_skb(struct sk_buff *, int); #endif -struct { - void *addr; - const char *name; -} symbol_table[] = { +struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */ + { + /* stackable module support */ + X(rename_module_symbol), + /* system info variables */ X(EISA_bus), X(wp_works_ok), @@ -109,6 +118,8 @@ X(irqaction), X(request_irq), X(free_irq), + X(enable_irq), + X(disable_irq), X(bh_active), X(bh_mask), @@ -164,7 +175,18 @@ X(dev_rint), X(dev_tint), X(irq2dev_map), + X(dev_kfree_skb), #endif + + /******************************************************** + * Do not add anything below this line, + * as the stacked modules depend on this! + */ + { NULL, NULL } /* mark end of table */ + }, + { NULL, NULL } /* no module refs */ }; +/* int symbol_table_size = sizeof (symbol_table) / sizeof (symbol_table[0]); +*/ diff -u --recursive --new-file v1.1.22/linux/kernel/module.c linux/kernel/module.c --- v1.1.22/linux/kernel/module.c Wed Jun 22 14:57:10 1994 +++ linux/kernel/module.c Mon Jun 27 14:56:45 1994 @@ -6,13 +6,109 @@ #include #include #include +/* + * Heavily modified by Bjorn Ekwall May 1994 (C) + * This source is covered by the GNU GPL, the same as all kernel sources. + * + * Features: + * - Supports stacked modules (removeable only of there are no dependants). + * - Supports table of symbols defined by the modules. + * - Supports /proc/ksyms, showing value, name and owner of all + * the symbols defined by all modules (in stack order). + * - Added module dependencies information into /proc/modules + * - Supports redefines of all symbols, for streams-like behaviour. + * - Compatible with older versions of insmod. + * + */ + +#ifdef DEBUG_MODULE +#define PRINTK(a) printk a +#else +#define PRINTK(a) /* */ +#endif + +static struct module kernel_module; +static struct module *module_list = &kernel_module; + +static int freeing_modules; /* true if some modules are marked for deletion */ + +static struct module *find_module( const char *name); +static int get_mod_name( char *user_name, char *buf); +static int free_modules( void); + + +/* + * Called at boot time + */ +void init_modules(void) { + extern struct symbol_table symbol_table; /* in kernel/ksyms.c */ + struct internal_symbol *sym; + int i; + + for (i = 0, sym = symbol_table.symbol; sym->name; ++sym, ++i) + ; + symbol_table.n_symbols = i; + + kernel_module.symtab = &symbol_table; + kernel_module.state = MOD_RUNNING; /* Hah! */ + kernel_module.name = ""; +} -struct module *module_list = NULL; -int freeing_modules; /* true if some modules are marked for deletion */ +int +rename_module_symbol(char *old_name, char *new_name) +{ + struct internal_symbol *sym; + int i = 0; /* keep gcc silent */ + + if (module_list->symtab) { + sym = module_list->symtab->symbol; + for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) { + if (strcmp(sym->name, old_name) == 0) { /* found it! */ + sym->name = new_name; /* done! */ + PRINTK(("renamed %s to %s\n", old_name, new_name)); + return 1; /* it worked! */ + } + } + } + printk("rename %s to %s failed!\n", old_name, new_name); + return 0; /* not there... */ -struct module *find_module( const char *name); -int get_mod_name( char *user_name, char *buf); -int free_modules( void); + /* + * This one will change the name of the first matching symbol! + * + * With this function, you can replace the name of a symbol defined + * in the current module with a new name, e.g. when you want to insert + * your own function instead of a previously defined function + * with the same name. + * + * "Normal" usage: + * + * bogus_function(int params) + * { + * do something "smart"; + * return real_function(params); + * } + * + * ... + * + * init_module() + * { + * if (rename_module_symbol("_bogus_function", "_real_function")) + * printk("yep!\n"); + * else + * printk("no way!\n"); + * ... + * } + * + * When loading this module, real_function will be resolved + * to the real function address. + * All later loaded modules that refer to "real_function()" will + * then really call "bogus_function()" instead!!! + * + * This feature will give you ample opportunities to get to know + * the taste of your foot when you stuff it into your mouth!!! + */ +} /* * Allocate space for a module. @@ -20,13 +116,12 @@ asmlinkage int sys_create_module(char *module_name, unsigned long size) { - int npages; - void* addr; - int len; - char name[MOD_MAX_NAME]; - char *savename; struct module *mp; + void* addr; int error; + int npages; + int sspace = sizeof(struct module) + MOD_MAX_NAME; + char name[MOD_MAX_NAME]; if (!suser()) return -EPERM; @@ -37,30 +132,32 @@ if (find_module(name) != NULL) { return -EEXIST; } - len = strlen(name) + 1; - if ((savename = (char*) kmalloc(len, GFP_KERNEL)) == NULL) - return -ENOMEM; - memcpy(savename, name, len); - if ((mp = (struct module*) kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) { - kfree(savename); + + if ((mp = (struct module*) kmalloc(sspace, GFP_KERNEL)) == NULL) { return -ENOMEM; } + strcpy((char *)(mp + 1), name); /* why not? */ + npages = (size + sizeof (int) + 4095) / 4096; if ((addr = vmalloc(npages * 4096)) == 0) { - kfree_s(mp, sizeof *mp); - kfree(savename); + kfree_s(mp, sspace); return -ENOMEM; } - mp->name = savename; + + mp->next = module_list; + mp->ref = NULL; + mp->symtab = NULL; + mp->name = (char *)(mp + 1); mp->size = npages; mp->addr = addr; mp->state = MOD_UNINITIALIZED; - * (int *) addr = 0; /* set use count to zero */ mp->cleanup = NULL; - mp->next = module_list; - module_list = mp; - printk("module `%s' (%lu pages @ 0x%08lx) created\n", - mp->name, (unsigned long) mp->size, (unsigned long) mp->addr); + + * (int *) addr = 0; /* set use count to zero */ + module_list = mp; /* link it in */ + + PRINTK(("module `%s' (%lu pages @ 0x%08lx) created\n", + mp->name, (unsigned long) mp->size, (unsigned long) mp->addr)); return (int) addr; } @@ -69,15 +166,24 @@ */ asmlinkage int sys_init_module(char *module_name, char *code, unsigned codesize, - struct mod_routines *routines) + struct mod_routines *routines, + struct symbol_table *symtab) { struct module *mp; + struct symbol_table *newtab; char name[MOD_MAX_NAME]; int error; struct mod_routines rt; if (!suser()) return -EPERM; + + /* A little bit of protection... we "know" where the user stack is... */ + if (symtab && ((unsigned long)symtab > 0xb0000000)) { + printk("warning: you are using an old insmod, no symbols will be inserted!\n"); + symtab = NULL; + } + /* * First reclaim any memory from dead modules that where not * freed when deleted. Should I think be done by timers when @@ -87,8 +193,8 @@ if ((error = get_mod_name(module_name, name)) != 0) return error; - printk( "initializing module `%s', %d (0x%x) bytes\n", - name, codesize, codesize); + PRINTK(("initializing module `%s', %d (0x%x) bytes\n", + name, codesize, codesize)); memcpy_fromfs(&rt, routines, sizeof rt); if ((mp = find_module(name)) == NULL) return -ENOENT; @@ -97,12 +203,53 @@ memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize); memset((char *)mp->addr + sizeof (int) + codesize, 0, mp->size * 4096 - (codesize + sizeof (int))); - printk( " init entry @ 0x%08lx, cleanup entry @ 0x%08lx\n", - (unsigned long) rt.init, (unsigned long) rt.cleanup); + PRINTK(( "module init entry = 0x%08lx, cleanup entry = 0x%08lx\n", + (unsigned long) rt.init, (unsigned long) rt.cleanup)); mp->cleanup = rt.cleanup; + + /* update kernel symbol table */ + if (symtab) { /* symtab == NULL means no new entries to handle */ + struct internal_symbol *sym; + struct module_ref *ref; + int size; + int i; + + if ((error = verify_area(VERIFY_READ, symtab, sizeof(int)))) + return error; + memcpy_fromfs((char *)(&(size)), symtab, sizeof(int)); + + if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) { + return -ENOMEM; + } + + if ((error = verify_area(VERIFY_READ, symtab, size))) + return error; + memcpy_fromfs((char *)(newtab), symtab, size); + + /* relocate name pointers, index referred from start of table */ + for (sym = &(newtab->symbol[0]), i = 0; + i < newtab->n_symbols; ++sym, ++i) { + sym->name += (long)newtab; + } + mp->symtab = newtab; + + /* Update module references. + * On entry, from "insmod", ref->module points to + * the referenced module! + * Also, "sym" from above, points to the first ref entry!!! + */ + for (ref = (struct module_ref *)sym, i = 0; + i < newtab->n_refs; ++ref, ++i) { + ref->next = ref->module->ref; + ref->module->ref = ref; + ref->module = mp; + } + } + if ((*rt.init)() != 0) return -EBUSY; mp->state = MOD_RUNNING; + return 0; } @@ -115,12 +262,13 @@ if (!suser()) return -EPERM; + /* else */ if (module_name != NULL) { if ((error = get_mod_name(module_name, name)) != 0) return error; if ((mp = find_module(name)) == NULL) return -ENOENT; - if (GET_USE_COUNT(mp) != 0) + if ((mp->ref != NULL) || (GET_USE_COUNT(mp) != 0)) return -EBUSY; if (mp->state == MOD_RUNNING) (*mp->cleanup)(); @@ -130,38 +278,74 @@ return 0; } + /* * Copy the kernel symbol table to user space. If the argument is null, * just return the size of the table. + * + * Note that the transient module symbols are copied _first_, + * in lifo order!!! + * + * The symbols to "insmod" are according to the "old" format: struct kernel_sym, + * which is actually quite handy for this purpose. + * Note that insmod inserts a struct symbol_table later on... + * (as that format is quite handy for the kernel...) + * + * For every module, the first (pseudo)symbol copied is the module name + * and the adress of the module struct. + * This lets "insmod" keep track of references, and build the array of + * struct module_refs in the symbol table. + * The format of the module name is "#module", so that "insmod" can easily + * notice when a module name comes along. Also, this will make it possible + * to use old versions of "insmod", albeit with reduced functionality... + * The "kernel" module has an empty name. */ asmlinkage int sys_get_kernel_syms(struct kernel_sym *table) { - struct symbol { - unsigned long addr; - char *name; - }; - extern int symbol_table_size; - extern struct symbol symbol_table[]; - int i; - struct symbol *from; + struct internal_symbol *from; + struct kernel_sym isym; struct kernel_sym *to; - struct kernel_sym sym; + struct module *mp = module_list; + int i; + int nmodsyms = 0; + + for (mp = module_list; mp; mp = mp->next) { + if (mp->symtab && mp->symtab->n_symbols) { + /* include the count for the module name! */ + nmodsyms += mp->symtab->n_symbols + 1; + } + } if (table != NULL) { - from = symbol_table; to = table; - i = verify_area(VERIFY_WRITE, to, symbol_table_size * sizeof *table); - if (i) + + if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table)))) return i; - for (i = symbol_table_size ; --i >= 0 ; ) { - sym.value = from->addr; - strncpy(sym.name, from->name, sizeof sym.name); - memcpy_tofs(to, &sym, sizeof sym); - from++, to++; + + /* copy all module symbols first (always LIFO order) */ + for (mp = module_list; mp; mp = mp->next) { + if ((mp->state == MOD_RUNNING) && + (mp->symtab != NULL) && (mp->symtab->n_symbols > 0)) { + /* magic: write module info as a pseudo symbol */ + isym.value = (unsigned long)mp; + sprintf(isym.name, "#%s", mp->name); + memcpy_tofs(to, &isym, sizeof isym); + ++to; + + for (i = mp->symtab->n_symbols, + from = mp->symtab->symbol; + i > 0; --i, ++from, ++to) { + + isym.value = (unsigned long)from->addr; + strncpy(isym.name, from->name, sizeof isym.name); + memcpy_tofs(to, &isym, sizeof isym); + } + } } } - return symbol_table_size; + + return nmodsyms; } @@ -199,6 +383,27 @@ return mp; } +static void +drop_refs(struct module *mp) +{ + struct module *step; + struct module_ref *prev; + struct module_ref *ref; + + for (step = module_list; step; step = step->next) { + for (prev = ref = step->ref; ref; ref = prev->next) { + if (ref->module == mp) { + if (ref == step->ref) + step->ref = ref->next; + else + prev->next = ref->next; + break; /* every module only references once! */ + } + else + prev = ref; + } + } +} /* * Try to free modules which have been marked for deletion. Returns nonzero @@ -217,15 +422,22 @@ while ((mp = *mpp) != NULL) { if (mp->state != MOD_DELETED) { mpp = &mp->next; - } else if (GET_USE_COUNT(mp) != 0) { - freeing_modules = 1; - mpp = &mp->next; - } else { /* delete it */ - *mpp = mp->next; - vfree(mp->addr); - kfree(mp->name); - kfree_s(mp, sizeof *mp); - did_deletion = 1; + } else { + if (GET_USE_COUNT(mp) != 0) { + freeing_modules = 1; + mpp = &mp->next; + } else { /* delete it */ + *mpp = mp->next; + if (mp->symtab) { + if (mp->symtab->n_refs) + drop_refs(mp); + if (mp->symtab->size) + kfree_s(mp->symtab, mp->symtab->size); + } + vfree(mp->addr); + kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME); + did_deletion = 1; + } } } return did_deletion; @@ -241,10 +453,12 @@ char *q; int i; struct module *mp; + struct module_ref *ref; char size[32]; p = buf; - for (mp = module_list ; mp ; mp = mp->next) { + /* Do not show the kernel pseudo module */ + for (mp = module_list ; mp && mp->next; mp = mp->next) { if (p - buf > 4096 - 100) break; /* avoid overflowing buffer */ q = mp->name; @@ -272,7 +486,60 @@ q = " (bad state)"; while (*q) *p++ = *q++; + + if ((ref = mp->ref) != NULL) { + *p++ = '\t'; + *p++ = '['; + for (; ref; ref = ref->next) { + q = ref->module->name; + while (*q) + *p++ = *q++; + if (ref->next) + *p++ = ' '; + } + *p++ = ']'; + } *p++ = '\n'; } + return p - buf; +} + + +/* + * Called by the /proc file system to return a current list of ksyms. + */ +int get_ksyms_list(char *buf) +{ + struct module *mp; + struct internal_symbol *sym; + int i; + char *p = buf; + + for (mp = module_list; mp; mp = mp->next) { + if ((mp->state == MOD_RUNNING) && + (mp->symtab != NULL) && (mp->symtab->n_symbols > 0)) { + for (i = mp->symtab->n_symbols, + sym = mp->symtab->symbol; + i > 0; --i, ++sym) { + + if (p - buf > 4096 - 100) { + strcat(p, "...\n"); + p += strlen(p); + return p - buf; /* avoid overflowing buffer */ + } + + if (mp->name[0]) { + sprintf(p, "%08lx %s\t[%s]\n", + (long)sym->addr, sym->name, mp->name); + } + else { + sprintf(p, "%08lx %s\n", + (long)sym->addr, sym->name); + } + p += strlen(p); + } + } + } + return p - buf; } diff -u --recursive --new-file v1.1.22/linux/net/inet/tcp.c linux/net/inet/tcp.c --- v1.1.22/linux/net/inet/tcp.c Mon Jun 27 16:47:04 1994 +++ linux/net/inet/tcp.c Mon Jun 27 17:32:02 1994 @@ -2030,9 +2030,9 @@ rt=ip_rt_route(saddr, NULL,NULL); if(rt!=NULL && (rt->rt_flags&RTF_WINDOW)) - sk->window_clamp=rt->rt_window; + newsk->window_clamp = rt->rt_window; else - sk->window_clamp=0; + newsk->window_clamp = 0; if (sk->user_mss) newsk->mtu = sk->user_mss;