-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Sun, 3 Sep 2000, Mohammad A. Haque wrote: > Ok, looking better. I havent been able to forcibly corrupt my mailboxes > like I did before. Yet anyways. I left my machine for about 10 mins and > came back and noticed this... > > Sep 3 16:46:29 viper kernel: attempt to access beyond end of device > Sep 3 16:46:29 viper kernel: 21:01: rw=0, want=1070936764, > limit=30015184 > Sep 3 16:46:29 viper kernel: attempt to access beyond end of device > Sep 3 16:46:29 viper kernel: 21:01: rw=0, want=1422438616, > limit=30015184 > ........ Talk to Jens Axboe regarding this. He gave me a patch when I experienced the same problems with a DVD the other day. Attached is the patch if you would like to try. It is against test8-pre1 /Richard -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.2 (GNU/Linux) Comment: Made with pgp4pine 1.75 iD8DBQE5sr5MUSLExYo23RsRAqqLAJ9UF+dav+R3jkIL5ykzTXDRidPtPgCgvFt/ ggV9L3Vh5yeddF36QfUrMzU= =1MFr -----END PGP SIGNATURE-----
diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.0-test8-pre1/MAINTAINERS linux/MAINTAINERS --- /opt/kernel/linux-2.4.0-test8-pre1/MAINTAINERS Thu Aug 24 05:12:54 2000 +++ linux/MAINTAINERS Thu Aug 31 01:04:34 2000 @@ -540,7 +540,7 @@ IDE/ATAPI CDROM DRIVER P: Jens Axboe -M: [EMAIL PROTECTED] +M: [EMAIL PROTECTED] L: [EMAIL PROTECTED] W: http://www.kernel.dk S: Maintained @@ -986,7 +986,7 @@ SCSI CDROM DRIVER P: Jens Axboe -M: [EMAIL PROTECTED] +M: [EMAIL PROTECTED] L: [EMAIL PROTECTED] W: http://www.kernel.dk S: Maintained @@ -1174,7 +1174,7 @@ UNIFORM CDROM DRIVER P: Jens Axboe -M: [EMAIL PROTECTED] +M: [EMAIL PROTECTED] L: [EMAIL PROTECTED] W: http://www.kernel.dk S: Maintained diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.0-test8-pre1/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- /opt/kernel/linux-2.4.0-test8-pre1/drivers/cdrom/cdrom.c Fri Jun 30 03:25:50 2000 +++ linux/drivers/cdrom/cdrom.c Sun Aug 27 03:26:40 2000 @@ -784,6 +784,8 @@ if (!CDROM_CAN(CDC_SELECT_DISC)) return -EDRIVE_CANT_DO_THIS; + (void) cdi->ops->media_changed(cdi, slot); + if (slot == CDSL_NONE) { /* set media changed bits, on both queues */ cdi->mc_flags = 0x3; @@ -851,8 +853,8 @@ if (cdi == NULL || cdi->ops->media_changed == NULL) return 0; if (!CDROM_CAN(CDC_MEDIA_CHANGED)) - return 0; - return (media_changed(cdi, 0)); + return 0; + return media_changed(cdi, 0); } /* badly broken, I know. Is due for a fixup anytime. */ @@ -872,8 +874,7 @@ return; } /* Grab the TOC header so we can see how many tracks there are */ - ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header); - if (ret) { + if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header))) { if (ret == -ENOMEDIUM) tracks->error = CDS_NO_DISC; else @@ -1516,12 +1517,13 @@ cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n"); if (!CDROM_CAN(CDC_MEDIA_CHANGED)) return -ENOSYS; + + /* cannot select disc or select current disc */ if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT) - /* cannot select disc or select current disc */ return media_changed(cdi, 1); - if ((unsigned int)arg >= cdi->capacity) { + + if ((unsigned int)arg >= cdi->capacity) return -EINVAL; - } if ((ret = cdrom_read_mech_status(cdi, &info))) return ret; @@ -1570,10 +1572,10 @@ if (!CDROM_CAN(CDC_SELECT_DISC)) return -ENOSYS; - if ((arg != CDSL_CURRENT) && (arg != CDSL_NONE)) { - if ((int)arg >= cdi->capacity) - return -EINVAL; - } + if ((arg != CDSL_CURRENT) && (arg != CDSL_NONE)) + if ((int)arg >= cdi->capacity) + return -EINVAL; + /* cdo->select_disc is a hook to allow a driver-specific * way of seleting disc. However, since there is no * equiv hook for cdrom_slot_status this may not @@ -1834,7 +1836,6 @@ struct cdrom_device_ops *cdo = cdi->ops; struct cdrom_generic_command cgc; struct modesel_head mh; - int ret; memset(&mh, 0, sizeof(mh)); mh.block_desc_length = 0x08; @@ -1852,14 +1853,7 @@ mh.block_length_med = (size >> 8) & 0xff; mh.block_length_lo = size & 0xff; - ret = cdo->generic_packet(cdi, &cgc); - if (ret) { - printk("switch_blocksize failed, ret %x ", ret); - if (cgc.sense) - printk("sense %02x.%02x.%02x", cgc.sense->sense_key, cgc.sense->asc, cgc.sense->ascq); - printk("\n"); - } - return ret; + return cdo->generic_packet(cdi, &cgc); } static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, @@ -1916,16 +1910,10 @@ } cgc.sense = NULL; ret = cdrom_read_cd(cdi, &cgc, lba, blocksize, 1); - if (ret) { - printk("read_cd failed, ret %x ", ret); - if (cgc.sense) - printk("sense %02x.%02x.%02x", cgc.sense->sense_key, cgc.sense->asc, cgc.sense->ascq); - printk("\n"); - } ret |= cdrom_switch_blocksize(cdi, blocksize); } if (!ret && copy_to_user((char *)arg, cgc.buffer, blocksize)) - ret = -EFAULT; + ret = -EFAULT; kfree(cgc.buffer); return ret; } diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.0-test8-pre1/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c --- /opt/kernel/linux-2.4.0-test8-pre1/drivers/cdrom/sbpcd.c Thu Aug 3 23:41:01 2000 +++ linux/drivers/cdrom/sbpcd.c Thu Aug 10 02:39:56 2000 @@ -1,3 +1,5 @@ + + /* * sbpcd.c CD-ROM device driver for the whole family of traditional, * non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives. @@ -13,7 +15,7 @@ * labelled E2550UA or MK4015 or 2800F). */ -#define VERSION "v4.61 Eberhard Moenkeberg <[EMAIL PROTECTED]>" +#define VERSION "v4.63 Andrew J. Kroll <[EMAIL PROTECTED]> Wed Jul 26 +04:24:10 EDT 2000" /* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg <[EMAIL PROTECTED]> * @@ -46,7 +48,7 @@ * * 0.1 initial release, April/May 93, after mcd.c (Martin Harriss) * - * 0.2 the "repeat:"-loop in do_sbpcd_request did not check for + * 0.2 thek "repeat:"-loop in do_sbpcd_request did not check for * end-of-request_queue (resulting in kernel panic). * Flow control seems stable, but throughput is not better. * @@ -312,9 +314,20 @@ * module_init & module_exit. * Torben Mathiasen <[EMAIL PROTECTED]> * + * 4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer. + * Annoying things fixed: + * TOC reread on automated disk changes + * TOC reread on manual cd changes + * Play IOCTL tries to play CD before it's actually ready... sometimes. + * CD_AUDIO_COMPLETED state so workman (and other playes) can repeat +play. + * Andrew J. Kroll <[EMAIL PROTECTED]> Wed Jul 26 04:24:10 EDT +2000 + * * * TODO * implement "read all subchannel data" (96 bytes per frame) + * remove alot of the virtual status bits and deal with hardware status + * move the change of cd for audio to a better place + * add debug levels to insmod parameters (trivial) * * special thanks to Kai Makisara ([EMAIL PROTECTED]) for his fine * elaborated speed-up experiments (and the fabulous results!), for @@ -637,9 +650,9 @@ static u_int maxtim_data= 3000; #endif LONG_TIMING #if DISTRIBUTION -static int n_retries=3; +static int n_retries=6; #else -static int n_retries=1; +static int n_retries=6; #endif /*==========================================================================*/ @@ -2046,7 +2059,9 @@ do { i=GetStatus(); - if ((i<0)&&(i!=-ERR_DISKCHANGE)) return (-2); /* from sta2err */ + if ((i<0)&&(i!=-ERR_DISKCHANGE)) { + return (-2); /* from sta2err */ + } if (!st_caddy_in) break; sbp_sleep(1); } @@ -2343,16 +2358,21 @@ static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position) { - int i; - i = MINOR(cdi->dev); - - switch_drive(i); - if (position == 1) { - cc_SpinDown(); - } else { - return cc_CloseTray(); - } - return 0; + int i; + int retval=0; + i = MINOR(cdi->dev); + switch_drive(i); + /* DUH! --AJK */ + if(D_S[d].CD_changed != 0xFF) { + D_S[d].CD_changed=0xFF; + D_S[d].diskstate_flags &= ~cd_size_bit; + } + if (position == 1) { + cc_SpinDown(); + } else { + retval=cc_CloseTray(); + } + return retval; } /*==========================================================================*/ @@ -4023,6 +4043,7 @@ msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok); msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning); msg(DBG_000,"Drive Status: busy =%d.\n", st_busy); + #if 0 if (!(D_S[MINOR(cdi->dev)].status_bits & p_door_closed)) return CDS_TRAY_OPEN; if (D_S[MINOR(cdi->dev)].status_bits & p_disk_ok) return CDS_DISC_OK; @@ -4031,8 +4052,11 @@ return CDS_NO_DISC; #else if (D_S[MINOR(cdi->dev)].status_bits & p_spinning) return CDS_DISC_OK; - return CDS_TRAY_OPEN; +/* return CDS_TRAY_OPEN; */ + return CDS_NO_DISC; + #endif + } @@ -4500,7 +4524,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, void * arg) { - int i, st; + int i, st, j; msg(DBG_IO2,"ioctl(%d, 0x%08lX, 0x%08p)\n", MINOR(cdi->dev), cmd, arg); @@ -4696,19 +4720,68 @@ case CDROMSUBCHNL: /* Get subchannel info */ msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n"); + /* Bogus, I can do better than this! --AJK if ((st_spinning)||(!subq_valid)) { i=cc_ReadSubQ(); if (i<0) RETURN_UP(-EIO); } + */ + i=cc_ReadSubQ(); + if (i<0) { + j=cc_ReadError(); /* clear out error status from drive */ + D_S[d].audio_state=CDROM_AUDIO_NO_STATUS; + /* get and set the disk state here, + probably not the right place, but who cares! + It makes it work properly! --AJK */ + if (D_S[d].CD_changed==0xFF) { + msg(DBG_000,"Disk changed detect\n"); + D_S[d].diskstate_flags &= ~cd_size_bit; + } + RETURN_UP(-EIO); + } + if (D_S[d].CD_changed==0xFF) { + /* reread the TOC because the disk has changed! --AJK */ + msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n"); + i=DiskInfo(); + if(i==0) { + D_S[d].CD_changed=0x00; /* cd has changed, procede, */ + RETURN_UP(-EIO); /* and get TOC, etc on next try! +--AJK */ + } else { + RETURN_UP(-EIO); /* we weren't ready yet! --AJK */ + } + } memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl)); + /* + This virtual crap is very bogus! + It doesn't detect when the cd is done playing audio! + Lets do this right with proper hardware register reading! + */ + cc_ReadStatus(); + i=ResponseStatus(); + msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked); + msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed); + msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in); + msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok); + msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning); + msg(DBG_000,"Drive Status: busy =%d.\n", st_busy); + /* st_busy indicates if it's _ACTUALLY_ playing audio */ switch (D_S[d].audio_state) { case audio_playing: - SC.cdsc_audiostatus=CDROM_AUDIO_PLAY; + if(st_busy==0) { + /* CD has stopped playing audio --AJK */ + D_S[d].audio_state=audio_completed; + SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED; + } else { + SC.cdsc_audiostatus=CDROM_AUDIO_PLAY; + } break; case audio_pausing: SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED; break; + case audio_completed: + SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED; + break; default: SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS; break; @@ -5883,6 +5956,14 @@ { D_S[i].CD_changed=0; msg(DBG_CHK,"medium changed (drive %d)\n", i); + /* BUG! Should invalidate buffers! --AJK */ + invalidate_buffers(full_dev); + D_S[d].diskstate_flags &= ~toc_bit; + D_S[d].diskstate_flags &= ~cd_size_bit; +#if SAFE_MIXED + D_S[d].has_data=0; +#endif SAFE_MIXED + return (1); } else diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.0-test8-pre1/drivers/cdrom/sbpcd.h linux/drivers/cdrom/sbpcd.h --- /opt/kernel/linux-2.4.0-test8-pre1/drivers/cdrom/sbpcd.h Mon Jan 5 09:06:26 1998 +++ linux/drivers/cdrom/sbpcd.h Thu Aug 10 02:39:56 2000 @@ -412,6 +412,7 @@ /* * audio states: */ +#define audio_completed 3 /* Forgot this one! --AJK */ #define audio_playing 2 #define audio_pausing 1 diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.0-test8-pre1/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c --- /opt/kernel/linux-2.4.0-test8-pre1/drivers/ide/ide-cd.c Thu Aug 3 23:41:01 2000 +++ linux/drivers/ide/ide-cd.c Tue Aug 15 04:21:16 2000 @@ -285,9 +285,13 @@ * 4.58 May 1, 2000 - Clean up ACER50 stuff. * - Fix small problem with ide_cdrom_capacity * + * 4.59 Aug 11, 2000 - Fix changer problem in cdrom_read_toc, we weren't + * correctly sensing a disc change. + * - Rearranged some code + * *************************************************************************/ -#define IDECD_VERSION "4.58" +#define IDECD_VERSION "4.59" #include <linux/config.h> #include <linux/module.h> @@ -542,11 +546,11 @@ /* Returns 0 if the request should be continued. Returns 1 if the request was ended. */ -static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, int good_stat, - int *stat_ret) +static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, + int good_stat, int *stat_ret) { struct request *rq = HWGROUP(drive)->rq; - int stat, cmd, err, sense_key; + int stat, err, sense_key; struct packet_command *pc; /* Check for errors. */ @@ -560,103 +564,99 @@ err = GET_ERR(); sense_key = err >> 4; - if (rq == NULL) - printk ("%s: missing request in cdrom_decode_status\n", - drive->name); - else { - cmd = rq->cmd; - - if (cmd == REQUEST_SENSE_COMMAND) { - /* We got an error trying to get sense info - from the drive (probably while trying - to recover from a former error). Just give up. */ - - pc = (struct packet_command *) rq->buffer; - pc->stat = 1; - cdrom_end_request (1, drive); - *startstop = ide_error (drive, "request sense failure", stat); - return 1; - - } else if (cmd == PACKET_COMMAND) { - /* All other functions, except for READ. */ + if (rq == NULL) { + printk("%s: missing rq in cdrom_decode_status\n", drive->name); + *startstop = ide_stopped; + return 1; + } - struct semaphore *sem = NULL; - pc = (struct packet_command *) rq->buffer; + if (rq->cmd == REQUEST_SENSE_COMMAND) { + /* We got an error trying to get sense info + from the drive (probably while trying + to recover from a former error). Just give up. */ - /* Check for tray open. */ - if (sense_key == NOT_READY) { - cdrom_saw_media_change (drive); - } else if (sense_key == UNIT_ATTENTION) { - /* Check for media change. */ - cdrom_saw_media_change (drive); - /*printk("%s: media changed\n",drive->name);*/ - return 0; - } else { - /* Otherwise, print an error. */ - ide_dump_status (drive, "packet command error", - stat); - } - - /* Set the error flag and complete the request. - Then, if we have a CHECK CONDITION status, - queue a request sense command. We must be careful, - though: we don't want the thread in - cdrom_queue_packet_command to wake up until - the request sense has completed. We do this - by transferring the semaphore from the packet - command request to the request sense request. */ - - if ((stat & ERR_STAT) != 0) { - sem = rq->sem; - rq->sem = NULL; - } - - pc->stat = 1; - cdrom_end_request (1, drive); + pc = (struct packet_command *) rq->buffer; + pc->stat = 1; + cdrom_end_request (1, drive); + *startstop = ide_error (drive, "request sense failure", stat); + return 1; - if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense(drive, sem, pc->sense, - pc); + } else if (rq->cmd == PACKET_COMMAND) { + /* All other functions, except for READ. */ + struct semaphore *sem = NULL; + pc = (struct packet_command *) rq->buffer; + + /* Check for tray open. */ + if (sense_key == NOT_READY) { + cdrom_saw_media_change (drive); + } else if (sense_key == UNIT_ATTENTION) { + /* Check for media change. */ + cdrom_saw_media_change (drive); + /*printk("%s: media changed\n",drive->name);*/ + return 0; } else { - /* Handle errors from READ requests. */ + /* Otherwise, print an error. */ + ide_dump_status(drive, "packet command error", stat); + } + + /* Set the error flag and complete the request. + Then, if we have a CHECK CONDITION status, + queue a request sense command. We must be careful, + though: we don't want the thread in + cdrom_queue_packet_command to wake up until + the request sense has completed. We do this + by transferring the semaphore from the packet + command request to the request sense request. */ + + if ((stat & ERR_STAT) != 0) { + sem = rq->sem; + rq->sem = NULL; + } - if (sense_key == NOT_READY) { - /* Tray open. */ - cdrom_saw_media_change (drive); + pc->stat = 1; + cdrom_end_request (1, drive); - /* Fail the request. */ - printk ("%s: tray open\n", drive->name); - cdrom_end_request (0, drive); - } else if (sense_key == UNIT_ATTENTION) { - /* Media change. */ - cdrom_saw_media_change (drive); + if ((stat & ERR_STAT) != 0) + cdrom_queue_request_sense(drive, sem, pc->sense, pc); + } else { + /* Handle errors from READ requests. */ - /* Arrange to retry the request. - But be sure to give up if we've retried - too many times. */ - if (++rq->errors > ERROR_MAX) - cdrom_end_request (0, drive); - } else if (sense_key == ILLEGAL_REQUEST || - sense_key == DATA_PROTECT) { - /* No point in retrying after an illegal - request or data protect error.*/ - ide_dump_status (drive, "command error", stat); - cdrom_end_request (0, drive); - } else if ((err & ~ABRT_ERR) != 0) { - /* Go to the default handler - for other errors. */ - *startstop = ide_error (drive, "cdrom_decode_status", stat); - return 1; - } else if ((++rq->errors > ERROR_MAX)) { - /* We've racked up too many retries. Abort. */ - cdrom_end_request (0, drive); - } + if (sense_key == NOT_READY) { + /* Tray open. */ + cdrom_saw_media_change (drive); - /* If we got a CHECK_CONDITION status, - queue a request sense command. */ - if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense(drive, NULL, NULL, NULL); + /* Fail the request. */ + printk ("%s: tray open\n", drive->name); + cdrom_end_request (0, drive); + } else if (sense_key == UNIT_ATTENTION) { + /* Media change. */ + cdrom_saw_media_change (drive); + + /* Arrange to retry the request. + But be sure to give up if we've retried + too many times. */ + if (++rq->errors > ERROR_MAX) + cdrom_end_request (0, drive); + } else if (sense_key == ILLEGAL_REQUEST || + sense_key == DATA_PROTECT) { + /* No point in retrying after an illegal + request or data protect error.*/ + ide_dump_status (drive, "command error", stat); + cdrom_end_request (0, drive); + } else if ((err & ~ABRT_ERR) != 0) { + /* Go to the default handler + for other errors. */ + *startstop = ide_error (drive, "cdrom_decode_status", stat); + return 1; + } else if ((++rq->errors > ERROR_MAX)) { + /* We've racked up too many retries. Abort. */ + cdrom_end_request (0, drive); } + + /* If we got a CHECK_CONDITION status, + queue a request sense command. */ + if ((stat & ERR_STAT) != 0) + cdrom_queue_request_sense(drive, NULL, NULL, NULL); } /* Retry, or handle the next request. */ @@ -686,8 +686,9 @@ called when the interrupt from the drive arrives. Otherwise, HANDLER will be called immediately after the drive is prepared for the transfer. */ -static ide_startstop_t cdrom_start_packet_command (ide_drive_t *drive, int xferlen, - ide_handler_t *handler) +static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, + int xferlen, + ide_handler_t *handler) { ide_startstop_t startstop; struct cdrom_info *info = drive->driver_data; @@ -783,7 +784,7 @@ /* If we couldn't get a buffer, don't try to buffer anything... */ if (info->buffer == NULL) - sectors_to_buffer = 0; + sectors_to_buffer = 0; /* If this is the first sector in the buffer, remember its number. */ if (info->nsectors_buffered == 0) @@ -1657,10 +1658,10 @@ /* Check to see if the existing data is still valid. If it is, just return. */ - if (CDROM_STATE_FLAGS (drive)->toc_valid) - (void) cdrom_check_status(drive, sense); + (void) cdrom_check_status(drive, sense); - if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0; + if (CDROM_STATE_FLAGS(drive)->toc_valid) + return 0; /* First read just the header, so we know how long the TOC is. */ stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr, @@ -1717,10 +1718,10 @@ toc->hdr.first_track = CDROM_LEADOUT; toc->hdr.last_track = CDROM_LEADOUT; } - } else if (stat) { - return stat; } - if (stat) return stat; + + if (stat) + return stat; toc->hdr.toc_length = ntohs (toc->hdr.toc_length); @@ -1843,6 +1844,12 @@ struct cdrom_info *info = drive->driver_data; struct atapi_toc *toc = info->toc; int ntracks; + + /* + * don't serve cached data, if the toc isn't valid + */ + if (!CDROM_STATE_FLAGS(drive)->toc_valid) + return -EINVAL; /* Check validity of requested track number. */ ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.0-test8-pre1/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- /opt/kernel/linux-2.4.0-test8-pre1/drivers/scsi/sr.c Thu Aug 3 23:41:01 2000 +++ linux/drivers/scsi/sr.c Tue Aug 29 00:06:26 2000 @@ -28,6 +28,9 @@ * Modified by Jens Axboe <[EMAIL PROTECTED]> - support DVD-RAM * transparently and loose the GHOST hack * + * Modified by Arnaldo Carvalho de Melo <[EMAIL PROTECTED]> + * check resource allocation in sr_init and some cleanups + * */ #include <linux/module.h> @@ -82,11 +85,11 @@ init_command:sr_init_command }; -Scsi_CD *scsi_CDs = NULL; -static int *sr_sizes = NULL; +Scsi_CD *scsi_CDs; +static int *sr_sizes; -static int *sr_blocksizes = NULL; -static int *sr_hardsizes = NULL; +static int *sr_blocksizes; +static int *sr_hardsizes; static int sr_open(struct cdrom_device_info *, int); void get_sectorsize(int); @@ -710,30 +713,45 @@ } if (scsi_CDs) return 0; - sr_template.dev_max = - sr_template.dev_noticed + SR_EXTRA_DEVS; - scsi_CDs = (Scsi_CD *) kmalloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC); + + sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS; + scsi_CDs = kmalloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC); + if (!scsi_CDs) + goto cleanup_devfs; memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD)); - sr_sizes = (int *) kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC); + sr_sizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC); + if (!sr_sizes) + goto cleanup_cds; memset(sr_sizes, 0, sr_template.dev_max * sizeof(int)); - sr_blocksizes = (int *) kmalloc(sr_template.dev_max * - sizeof(int), GFP_ATOMIC); - - sr_hardsizes = (int *) kmalloc(sr_template.dev_max * - sizeof(int), GFP_ATOMIC); + sr_blocksizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC); + if (!sr_blocksizes) + goto cleanup_sizes; + + sr_hardsizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC); + if (!sr_hardsizes) + goto cleanup_blocksizes; /* * These are good guesses for the time being. */ - for (i = 0; i < sr_template.dev_max; i++) - { + for (i = 0; i < sr_template.dev_max; i++) { sr_blocksizes[i] = 2048; sr_hardsizes[i] = 2048; } blksize_size[MAJOR_NR] = sr_blocksizes; hardsect_size[MAJOR_NR] = sr_hardsizes; return 0; +cleanup_blocksizes: + kfree(sr_blocksizes); +cleanup_sizes: + kfree(sr_sizes); +cleanup_cds: + kfree(scsi_CDs); +cleanup_devfs: + devfs_unregister_blkdev(MAJOR_NR, "sr"); + sr_registered--; + return 1; } void sr_finish() @@ -830,29 +848,26 @@ return; } - -#ifdef MODULE - -int init_module(void) +int init_sr(void) { sr_template.module = &__this_module; return scsi_register_module(MODULE_SCSI_DEV, &sr_template); } -void cleanup_module(void) +void exit_sr(void) { scsi_unregister_module(MODULE_SCSI_DEV, &sr_template); devfs_unregister_blkdev(MAJOR_NR, "sr"); sr_registered--; if (scsi_CDs != NULL) { - kfree((char *) scsi_CDs); + kfree(scsi_CDs); - kfree((char *) sr_sizes); + kfree(sr_sizes); sr_sizes = NULL; - kfree((char *) sr_blocksizes); + kfree(sr_blocksizes); sr_blocksizes = NULL; - kfree((char *) sr_hardsizes); + kfree(sr_hardsizes); sr_hardsizes = NULL; } blksize_size[MAJOR_NR] = NULL; @@ -863,23 +878,5 @@ sr_template.dev_max = 0; } -#endif /* MODULE */ - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ +module_init(init_sr); +module_exit(exit_sr);