patch-1.3.10 linux/drivers/block/cdu31a.c
Next file: linux/drivers/block/genhd.c
Previous file: linux/arch/i386/config.in
Back to the patch index
Back to the overall index
- Lines: 355
- Date:
Wed Jul 12 07:07:32 1995
- Orig file:
v1.3.9/linux/drivers/block/cdu31a.c
- Orig date:
Wed Apr 5 13:07:22 1995
diff -u --recursive --new-file v1.3.9/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c
@@ -185,7 +185,7 @@
#define DEBUG 0
-#define CDU31A_READAHEAD 64 /* 64 sector, 32kB, 16 reads read-ahead */
+#define CDU31A_READAHEAD 128 /* 128 sector, 64kB, 32 reads read-ahead */
#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
/* Define the following if you have data corruption problems. */
@@ -380,6 +380,8 @@
static inline void
sony_sleep(void)
{
+ unsigned long flags;
+
if (irq_used <= 0)
{
current->state = TASK_INTERRUPTIBLE;
@@ -388,10 +390,11 @@
}
else /* Interrupt driven */
{
+ save_flags(flags);
cli();
enable_interrupts();
interruptible_sleep_on(&cdu31a_irq_wait);
- sti();
+ restore_flags(flags);
}
}
@@ -516,6 +519,18 @@
unsigned char params[3];
+ params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
+ params[1] = 0x00; /* Never spin down the drive. */
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params,
+ 2,
+ res_reg,
+ &res_size);
+ if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
+ {
+ printk(" Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
+ }
+
params[0] = SONY_SD_MECH_CONTROL;
params[1] = 0x03; /* Set auto spin up and auto eject */
if (is_double_speed)
@@ -753,8 +768,10 @@
unsigned int retry_count;
int num_retries;
int recursive_call;
+ unsigned long flags;
+ save_flags(flags);
cli();
if (current != has_cd_task) /* Allow recursive calls to this routine */
{
@@ -777,7 +794,7 @@
{
recursive_call = 1;
}
- sti();
+ restore_flags(flags);
num_retries = 0;
retry_cd_operation:
@@ -1356,24 +1373,31 @@
unsigned char res_reg[12];
unsigned int res_size;
int num_retries;
+ unsigned long flags;
/*
* Make sure no one else is using the driver; wait for them
* to finish if it is so.
*/
+ save_flags(flags);
cli();
while (sony_inuse)
{
interruptible_sleep_on(&sony_wait);
if (current->signal & ~current->blocked)
{
+ restore_flags(flags);
+ if (CURRENT && (CURRENT->dev > 0))
+ {
+ end_request(0);
+ }
return;
}
}
sony_inuse = 1;
has_cd_task = current;
- sti();
+ restore_flags(flags);
/* Get drive status before doing anything. */
while (handle_sony_cd_attention())
@@ -1507,6 +1531,7 @@
}
if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
{
+ printk("CDU31a: start request failed\n");
end_request(0);
goto cdu31a_request_startover;
}
@@ -1991,11 +2016,13 @@
unsigned char res_reg[12];
unsigned int res_size;
unsigned int cframe;
+ unsigned long flags;
/*
* Make sure no one else is using the driver; wait for them
* to finish if it is so.
*/
+ save_flags(flags);
cli();
while (sony_inuse)
{
@@ -2007,7 +2034,7 @@
}
sony_inuse = 1;
has_cd_task = current;
- sti();
+ restore_flags(flags);
if (!sony_spun_up)
{
@@ -2167,8 +2194,20 @@
/*
* The big ugly ioctl handler.
*/
-static int
-scd_ioctl(struct inode *inode,
+
+static int do_sony_cd_cmd_chk(char *name, unsigned char cmd, unsigned char *params, unsigned int num_params,
+ unsigned char *result_buffer, unsigned int *result_size)
+{
+ do_sony_cd_cmd(cmd, params, num_params, result_buffer, result_size);
+ if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20))
+ {
+ printk("Sony CDROM error 0x%2.2x (CDROM%s)\n", result_buffer[1], name);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int scd_ioctl(struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
@@ -2187,12 +2226,7 @@
switch (cmd)
{
case CDROMSTART: /* Spin up the drive */
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMSTART)\n", res_reg[1]);
- return -EIO;
- }
+ return do_sony_cd_cmd_chk("START",SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
return 0;
break;
@@ -2204,25 +2238,11 @@
* already not spinning.
*/
sony_audio_status = CDROM_AUDIO_NO_STATUS;
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
- if ( ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- && (res_reg[1] != SONY_NOT_SPIN_ERR))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMSTOP)\n", res_reg[1]);
- return -EIO;
- }
-
- return 0;
- break;
+ return do_sony_cd_cmd_chk("STOP",SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
case CDROMPAUSE: /* Pause the drive */
- do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMPAUSE)\n", res_reg[1]);
- return -EIO;
- }
-
+ if(do_sony_cd_cmd_chk("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size))
+ return -EIO;
/* Get the current position and save it for resuming */
if (read_subcode() < 0)
{
@@ -2251,18 +2271,15 @@
params[5] = final_pos_msf[1];
params[6] = final_pos_msf[2];
params[0] = 0x03;
- do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMRESUME)\n", res_reg[1]);
- return -EIO;
- }
+ if(do_sony_cd_cmd_chk("RESUME",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
+ return -EIO;
sony_audio_status = CDROM_AUDIO_PLAY;
return 0;
- break;
case CDROMPLAYMSF: /* Play starting at the given MSF address. */
- verify_area(VERIFY_READ, (char *) arg, 6);
+ i=verify_area(VERIFY_READ, (char *) arg, 6);
+ if(i)
+ return i;
do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
memcpy_fromfs(&(params[1]), (void *) arg, 6);
@@ -2272,12 +2289,8 @@
params[i] = int_to_bcd(params[i]);
}
params[0] = 0x03;
- do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMPLAYMSF)\n", res_reg[1]);
- return -EIO;
- }
+ if(do_sony_cd_cmd_chk("PLAYMSF",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
+ return -EIO;
/* Save the final position for pauses and resumes */
final_pos_msf[0] = params[4];
@@ -2285,7 +2298,6 @@
final_pos_msf[2] = params[6];
sony_audio_status = CDROM_AUDIO_PLAY;
return 0;
- break;
case CDROMREADTOCHDR: /* Read the table of contents header */
{
@@ -2299,13 +2311,14 @@
}
hdr = (struct cdrom_tochdr *) arg;
- verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
+ i=verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
+ if(i<0)
+ return i;
loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
memcpy_tofs(hdr, &loc_hdr, sizeof(*hdr));
}
return 0;
- break;
case CDROMREADTOCENTRY: /* Read a given table of contents entry */
{
@@ -2321,8 +2334,12 @@
}
entry = (struct cdrom_tocentry *) arg;
- verify_area(VERIFY_READ, entry, sizeof(*entry));
- verify_area(VERIFY_WRITE, entry, sizeof(*entry));
+ i=verify_area(VERIFY_READ, entry, sizeof(*entry));
+ if(i<0)
+ return i;
+ i=verify_area(VERIFY_WRITE, entry, sizeof(*entry));
+ if(i<0)
+ return i;
memcpy_fromfs(&loc_entry, entry, sizeof(loc_entry));
@@ -2373,7 +2390,9 @@
return -EIO;
}
- verify_area(VERIFY_READ, (char *) arg, sizeof(ti));
+ i=verify_area(VERIFY_READ, (char *) arg, sizeof(ti));
+ if(i<0)
+ return i;
memcpy_fromfs(&ti, (char *) arg, sizeof(ti));
if ( (ti.cdti_trk0 < sony_toc->first_track_num)
@@ -2416,6 +2435,7 @@
do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
+
if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
{
printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
@@ -2439,34 +2459,22 @@
{
struct cdrom_volctrl volctrl;
- verify_area(VERIFY_READ, (char *) arg, sizeof(volctrl));
+ i=verify_area(VERIFY_READ, (char *) arg, sizeof(volctrl));
+ if(i<0)
+ return i;
memcpy_fromfs(&volctrl, (char *) arg, sizeof(volctrl));
params[0] = SONY_SD_AUDIO_VOLUME;
params[1] = volctrl.channel0;
params[2] = volctrl.channel1;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMVOLCTRL)\n", res_reg[1]);
- return -EIO;
- }
+ return do_sony_cd_cmd_chk("VOLCTRL",SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
}
- return 0;
-
case CDROMEJECT: /* Eject the drive */
do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
sony_audio_status = CDROM_AUDIO_INVALID;
- do_sony_cd_cmd(SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error 0x%2.2x (CDROMEJECT)\n", res_reg[1]);
- return -EIO;
- }
- return 0;
- break;
+ return do_sony_cd_cmd_chk("EJECT",SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte
raw data tracks. */
@@ -2480,10 +2488,14 @@
return -EIO;
}
- verify_area(VERIFY_READ, (char *) arg, sizeof(ra));
+ i=verify_area(VERIFY_READ, (char *) arg, sizeof(ra));
+ if(i<0)
+ return i;
memcpy_fromfs(&ra, (char *) arg, sizeof(ra));
- verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
+ i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
+ if(i<0)
+ return i;
if (ra.addr_format == CDROM_LBA)
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this