patch-2.1.103 linux/drivers/block/paride/pcd.c
Next file: linux/drivers/block/paride/pd.c
Previous file: linux/drivers/block/paride/paride.h
Back to the patch index
Back to the overall index
- Lines: 196
- Date:
Thu May 14 19:11:48 1998
- Orig file:
v2.1.102/linux/drivers/block/paride/pcd.c
- Orig date:
Fri Jan 30 11:28:06 1998
diff -u --recursive --new-file v2.1.102/linux/drivers/block/paride/pcd.c linux/drivers/block/paride/pcd.c
@@ -1,6 +1,6 @@
/*
- pcd.c (c) 1997 Grant R. Guenther <grant@torque.net>
- Under the terms of the GNU public license.
+ pcd.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
+ Under the terms of the GNU public license.
This is high-level driver for parallel port ATAPI CDrom
drives based on chips supported by the paride module.
@@ -86,16 +86,20 @@
/* Changes:
1.01 GRG 1997.01.24 Added test unit ready support
+ 1.02 GRG 1998.05.06 Changes to pcd_completion, ready_wait,
+ and loosen interpretation of ATAPI
+ standard for clearing error status.
+ Use spinlocks. Eliminate sti().
*/
-#define PCD_VERSION "1.01"
+#define PCD_VERSION "1.02"
#define PCD_MAJOR 46
#define PCD_NAME "pcd"
#define PCD_UNITS 4
/* Here are things one can override from the insmod command.
- Most are autoprobed by paride unless set here. Verbose is on
+ Most are autoprobed by paride unless set here. Verbose is off
by default.
*/
@@ -133,6 +137,7 @@
#include <linux/cdrom.h>
#include <asm/uaccess.h>
+#include <asm/spinlock.h>
#ifndef MODULE
@@ -193,7 +198,7 @@
static int pcd_open(struct inode *inode, struct file *file);
static void do_pcd_request(void);
-static void do_pcd_read(int unit);
+static void do_pcd_read(void);
static int pcd_ioctl(struct inode *inode,struct file *file,
unsigned int cmd, unsigned long arg);
@@ -343,8 +348,9 @@
pcd_sector = CURRENT->sector;
pcd_count = CURRENT->nr_sectors;
pcd_buf = CURRENT->buffer;
- do_pcd_read(unit);
- if (pcd_busy) return;
+ pcd_busy = 1;
+ ps_set_intr(do_pcd_read,0,0,nice);
+ return;
}
else end_request(0);
}
@@ -474,7 +480,7 @@
WR(0,5,dlen / 256);
WR(0,7,0xa0); /* ATAPI packet command */
- if (pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_ERR,fun,"command DRQ")) {
+ if (pcd_wait(unit,IDE_BUSY,IDE_DRQ,fun,"command DRQ")) {
pi_disconnect(PI);
return -1;
}
@@ -497,7 +503,7 @@
r = pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,fun,"completion");
if ((RR(0,2)&2) && (RR(0,7)&IDE_DRQ)) {
- n = (RR(0,4)+256*RR(0,5));
+ n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
pi_read_block(PI,buf,n);
}
@@ -589,23 +595,17 @@
{ int i, k, flg;
int expect[5] = {1,1,1,0x14,0xeb};
- long flags;
pi_connect(PI);
WR(0,6,0xa0 + 0x10*PCD.drive);
WR(0,7,8);
- save_flags(flags);
- sti();
-
pcd_sleep(2); /* delay a bit*/
k = 0;
while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
pcd_sleep(10);
- restore_flags(flags);
-
flg = 1;
for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
@@ -631,7 +631,7 @@
pcd_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
p = PCD.last_sense;
if (!p) return 0;
- if (!((p == 0x010402)||((p & 0xff) == 6))) return p;
+ if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
k++;
pcd_sleep(100);
}
@@ -749,6 +749,7 @@
{ int unit = pcd_unit;
int b, i;
char rd_cmd[12] = {0xa8,0,0,0,0,0,0,0,0,1,0,0};
+ long saved_flags;
pcd_bufblk = pcd_sector / 4;
b = pcd_bufblk;
@@ -757,13 +758,13 @@
b = b >> 8;
}
-
if (pcd_command(unit,rd_cmd,2048,"read block")) {
pcd_bufblk = -1;
+ spin_lock_irqsave(&io_request_lock,saved_flags);
pcd_busy = 0;
- cli();
end_request(0);
do_pcd_request();
+ spin_unlock_irqrestore(&io_request_lock,saved_flags);
return;
}
@@ -773,17 +774,23 @@
}
-static void do_pcd_read( int unit )
+static void do_pcd_read( void )
-{ pcd_busy = 1;
+
+{ int unit = pcd_unit;
+ long saved_flags;
+
+ pcd_busy = 1;
pcd_retries = 0;
pcd_transfer();
if (!pcd_count) {
+ spin_lock_irqsave(&io_request_lock,saved_flags);
end_request(1);
pcd_busy = 0;
+ do_pcd_request();
+ spin_unlock_irqrestore(&io_request_lock,saved_flags);
return;
}
- sti();
pi_do_claimed(PI,pcd_start);
}
@@ -791,8 +798,7 @@
static void do_pcd_read_drq( void )
{ int unit = pcd_unit;
-
- sti();
+ long saved_flags;
if (pcd_completion(unit,pcd_buffer,"read block")) {
if (pcd_retries < PCD_RETRIES) {
@@ -801,16 +807,20 @@
pi_do_claimed(PI,pcd_start);
return;
}
- cli();
+ spin_lock_irqsave(&io_request_lock,saved_flags);
pcd_busy = 0;
pcd_bufblk = -1;
end_request(0);
do_pcd_request();
+ spin_unlock_irqrestore(&io_request_lock,saved_flags);
return;
}
- do_pcd_read(unit);
+ do_pcd_read();
+ spin_lock_irqsave(&io_request_lock,saved_flags);
do_pcd_request();
+ spin_unlock_irqrestore(&io_request_lock,saved_flags);
}
/* end of pcd.c */
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov