lkml.org 
[lkml]   [2000]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: test8-pre2 fs corruption?
-----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: axboe@image.dk
+M: axboe@suse.de
L: linux-kernel@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
@@ -986,7 +986,7 @@

SCSI CDROM DRIVER
P: Jens Axboe
-M: axboe@image.dk
+M: axboe@suse.de
L: linux-scsi@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
@@ -1174,7 +1174,7 @@

UNIFORM CDROM DRIVER
P: Jens Axboe
-M: axboe@image.dk
+M: axboe@suse.de
L: linux-kernel@vger.kernel.org
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 <emoenke@gwdg.de>"
+#define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"

/* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg <emoenke@gwdg.de>
*
@@ -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 <tmm@image.dk>
*
+ * 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 <ag784@freenet.buffalo.edu> 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 (kai.makisara@vtt.fi) 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 <axboe@suse.de> - support DVD-RAM
* transparently and loose the GHOST hack
*
+ * Modified by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * 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);
\
 
 \ /
  Last update: 2005-03-22 12:38    [W:0.092 / U:49.212 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site