Commit 91c42c4d authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] Lindent pd.c

pd.c fed through Lindent
parent f299adc6
...@@ -132,12 +132,13 @@ static int cluster = 64; ...@@ -132,12 +132,13 @@ static int cluster = 64;
static int nice = 0; static int nice = 0;
static int disable = 0; static int disable = 0;
static int drive0[8] = {0,0,0,-1,0,1,-1,-1}; static int drive0[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
static int drive1[8] = {0,0,0,-1,0,1,-1,-1}; static int drive1[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
static int drive2[8] = {0,0,0,-1,0,1,-1,-1}; static int drive2[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
static int drive3[8] = {0,0,0,-1,0,1,-1,-1}; static int drive3[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
static int (*drives[4])[8] = {&drive0,&drive1,&drive2,&drive3}; static int (*drives[4])[8] = {
&drive0, &drive1, &drive2, &drive3};
static int pd_drive_count; static int pd_drive_count;
#define D_PRT 0 #define D_PRT 0
...@@ -168,30 +169,31 @@ static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED; ...@@ -168,30 +169,31 @@ static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED;
#include "setup.h" #include "setup.h"
static STT pd_stt[7] = {{"drive0",8,drive0}, static STT pd_stt[7] = { {"drive0", 8, drive0},
{"drive1",8,drive1}, {"drive1", 8, drive1},
{"drive2",8,drive2}, {"drive2", 8, drive2},
{"drive3",8,drive3}, {"drive3", 8, drive3},
{"disable",1,&disable}, {"disable", 1, &disable},
{"cluster",1,&cluster}, {"cluster", 1, &cluster},
{"nice",1,&nice}}; {"nice", 1, &nice}
};
void pd_setup( char *str, int *ints) void pd_setup(char *str, int *ints)
{ {
generic_setup(pd_stt,7,str); generic_setup(pd_stt, 7, str);
} }
#endif #endif
MODULE_PARM(verbose,"i"); MODULE_PARM(verbose, "i");
MODULE_PARM(major,"i"); MODULE_PARM(major, "i");
MODULE_PARM(name,"s"); MODULE_PARM(name, "s");
MODULE_PARM(cluster,"i"); MODULE_PARM(cluster, "i");
MODULE_PARM(nice,"i"); MODULE_PARM(nice, "i");
MODULE_PARM(drive0,"1-8i"); MODULE_PARM(drive0, "1-8i");
MODULE_PARM(drive1,"1-8i"); MODULE_PARM(drive1, "1-8i");
MODULE_PARM(drive2,"1-8i"); MODULE_PARM(drive2, "1-8i");
MODULE_PARM(drive3,"1-8i"); MODULE_PARM(drive3, "1-8i");
#include "paride.h" #include "paride.h"
...@@ -250,26 +252,26 @@ MODULE_PARM(drive3,"1-8i"); ...@@ -250,26 +252,26 @@ MODULE_PARM(drive3,"1-8i");
#define IDE_IDENTIFY 0xec #define IDE_IDENTIFY 0xec
#define IDE_EJECT 0xed #define IDE_EJECT 0xed
void pd_setup(char * str, int * ints); void pd_setup(char *str, int *ints);
static int pd_open(struct inode *inode, struct file *file); static int pd_open(struct inode *inode, struct file *file);
static void do_pd_request(request_queue_t * q); static void do_pd_request(request_queue_t * q);
static int pd_ioctl(struct inode *inode,struct file *file, static int pd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
static int pd_release (struct inode *inode, struct file *file); static int pd_release(struct inode *inode, struct file *file);
static int pd_revalidate(kdev_t dev); static int pd_revalidate(kdev_t dev);
static int pd_detect(void); static int pd_detect(void);
static void do_pd_read(void); static void do_pd_read(void);
static void do_pd_read_start(void); static void do_pd_read_start(void);
static void do_pd_write(void); static void do_pd_write(void);
static void do_pd_write_start(void); static void do_pd_write_start(void);
static void do_pd_read_drq( void ); static void do_pd_read_drq(void);
static void do_pd_write_done( void ); static void do_pd_write_done(void);
static int pd_identify (int unit); static int pd_identify(int unit);
static void pd_media_check(int unit); static void pd_media_check(int unit);
static void pd_doorlock(int unit, int func); static void pd_doorlock(int unit, int func);
static int pd_check_media(kdev_t dev); static int pd_check_media(kdev_t dev);
static void pd_eject( int unit); static void pd_eject(int unit);
#define PD_NAMELEN 8 #define PD_NAMELEN 8
...@@ -313,50 +315,53 @@ static int pd_run; /* sectors in current cluster */ ...@@ -313,50 +315,53 @@ static int pd_run; /* sectors in current cluster */
static int pd_cmd; /* current command READ/WRITE */ static int pd_cmd; /* current command READ/WRITE */
static int pd_unit; /* unit of current request */ static int pd_unit; /* unit of current request */
static int pd_dev; /* minor of current request */ static int pd_dev; /* minor of current request */
static char * pd_buf; /* buffer for request in progress */ static char *pd_buf; /* buffer for request in progress */
static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open); static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open);
static char *pd_errs[17] = { "ERR","INDEX","ECC","DRQ","SEEK","WRERR", static char *pd_errs[17] = { "ERR", "INDEX", "ECC", "DRQ", "SEEK", "WRERR",
"READY","BUSY","AMNF","TK0NF","ABRT","MCR", "READY", "BUSY", "AMNF", "TK0NF", "ABRT", "MCR",
"IDNF","MC","UNC","???","TMO"}; "IDNF", "MC", "UNC", "???", "TMO"
};
/* kernel glue structures */ /* kernel glue structures */
extern struct block_device_operations pd_fops; extern struct block_device_operations pd_fops;
static struct block_device_operations pd_fops = { static struct block_device_operations pd_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
open: pd_open, .open = pd_open,
release: pd_release, .release = pd_release,
ioctl: pd_ioctl, .ioctl = pd_ioctl,
check_media_change: pd_check_media, .check_media_change = pd_check_media,
revalidate: pd_revalidate .revalidate = pd_revalidate
}; };
void pd_init_units( void ) static void pd_init_units(void)
{
{ int unit, j; int unit, j;
pd_drive_count = 0; pd_drive_count = 0;
for (unit=0;unit<PD_UNITS;unit++) { for (unit = 0; unit < PD_UNITS; unit++) {
PD.pi = & PD.pia; PD.pi = &PD.pia;
PD.access = 0; PD.access = 0;
PD.changed = 1; PD.changed = 1;
PD.capacity = 0; PD.capacity = 0;
PD.drive = DU[D_SLV]; PD.drive = DU[D_SLV];
PD.present = 0; PD.present = 0;
j = 0; j = 0;
while ((j < PD_NAMELEN-2) && (PD.name[j]=name[j])) j++; while ((j < PD_NAMELEN - 2) && (PD.name[j] = name[j]))
j++;
PD.name[j++] = 'a' + unit; PD.name[j++] = 'a' + unit;
PD.name[j] = 0; PD.name[j] = 0;
PD.alt_geom = DU[D_GEO]; PD.alt_geom = DU[D_GEO];
PD.standby = DU[D_SBY]; PD.standby = DU[D_SBY];
if (DU[D_PRT]) pd_drive_count++; if (DU[D_PRT])
pd_drive_count++;
} }
} }
static int pd_open (struct inode *inode, struct file *file) static int pd_open(struct inode *inode, struct file *file)
{ {
int unit = DEVICE_NR(inode->i_rdev); int unit = DEVICE_NR(inode->i_rdev);
...@@ -367,12 +372,12 @@ static int pd_open (struct inode *inode, struct file *file) ...@@ -367,12 +372,12 @@ static int pd_open (struct inode *inode, struct file *file)
if (PD.removable) { if (PD.removable) {
pd_media_check(unit); pd_media_check(unit);
pd_doorlock(unit,IDE_DOORLOCK); pd_doorlock(unit, IDE_DOORLOCK);
} }
return 0; return 0;
} }
static int pd_ioctl(struct inode *inode,struct file *file, static int pd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct hd_geometry *geo = (struct hd_geometry *) arg; struct hd_geometry *geo = (struct hd_geometry *) arg;
...@@ -383,15 +388,18 @@ static int pd_ioctl(struct inode *inode,struct file *file, ...@@ -383,15 +388,18 @@ static int pd_ioctl(struct inode *inode,struct file *file,
switch (cmd) { switch (cmd) {
case CDROMEJECT: case CDROMEJECT:
if (PD.access == 1) pd_eject(unit); if (PD.access == 1)
pd_eject(unit);
return 0; return 0;
case HDIO_GETGEO: case HDIO_GETGEO:
if (!geo) return -EINVAL; if (!geo)
err = verify_area(VERIFY_WRITE,geo,sizeof(*geo)); return -EINVAL;
if (err) return err; err = verify_area(VERIFY_WRITE, geo, sizeof (*geo));
if (err)
return err;
if (PD.alt_geom) { if (PD.alt_geom) {
put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS), put_user(PD.capacity / (PD_LOG_HEADS * PD_LOG_SECTS),
(short *) &geo->cylinders); (short *) &geo->cylinders);
put_user(PD_LOG_HEADS, (char *) &geo->heads); put_user(PD_LOG_HEADS, (char *) &geo->heads);
put_user(PD_LOG_SECTS, (char *) &geo->sectors); put_user(PD_LOG_SECTS, (char *) &geo->sectors);
...@@ -400,24 +408,24 @@ static int pd_ioctl(struct inode *inode,struct file *file, ...@@ -400,24 +408,24 @@ static int pd_ioctl(struct inode *inode,struct file *file,
put_user(PD.heads, (char *) &geo->heads); put_user(PD.heads, (char *) &geo->heads);
put_user(PD.sectors, (char *) &geo->sectors); put_user(PD.sectors, (char *) &geo->sectors);
} }
put_user(get_start_sect(inode->i_bdev), (long *)&geo->start); put_user(get_start_sect(inode->i_bdev), (long *) &geo->start);
return 0; return 0;
default: default:
return -EINVAL; return -EINVAL;
} }
} }
static int pd_release (struct inode *inode, struct file *file) static int pd_release(struct inode *inode, struct file *file)
{ {
int unit = DEVICE_NR(inode->i_rdev); int unit = DEVICE_NR(inode->i_rdev);
if (!--PD.access && PD.removable) if (!--PD.access && PD.removable)
pd_doorlock(unit,IDE_DOORUNLOCK); pd_doorlock(unit, IDE_DOORUNLOCK);
return 0; return 0;
} }
static int pd_check_media( kdev_t dev) static int pd_check_media(kdev_t dev)
{ {
int r, unit = DEVICE_NR(dev); int r, unit = DEVICE_NR(dev);
if ((unit >= PD_UNITS) || (!PD.present)) if ((unit >= PD_UNITS) || (!PD.present))
...@@ -449,60 +457,63 @@ static int pd_revalidate(kdev_t dev) ...@@ -449,60 +457,63 @@ static int pd_revalidate(kdev_t dev)
/* ide command interface */ /* ide command interface */
static void pd_print_error( int unit, char * msg, int status ) static void pd_print_error(int unit, char *msg, int status)
{
{ int i; int i;
printk("%s: %s: status = 0x%x =",PD.name,msg,status); printk("%s: %s: status = 0x%x =", PD.name, msg, status);
for(i=0;i<18;i++) if (status & (1<<i)) printk(" %s",pd_errs[i]); for (i = 0; i < 18; i++)
if (status & (1 << i))
printk(" %s", pd_errs[i]);
printk("\n"); printk("\n");
} }
static void pd_reset( int unit ) /* called only for MASTER drive */ static void pd_reset(int unit)
{ /* called only for MASTER drive */
{ pi_connect(PI); pi_connect(PI);
WR(1,6,4); WR(1, 6, 4);
udelay(50); udelay(50);
WR(1,6,0); WR(1, 6, 0);
pi_disconnect(PI); pi_disconnect(PI);
udelay(250); udelay(250);
} }
#define DBMSG(msg) ((verbose>1)?(msg):NULL) #define DBMSG(msg) ((verbose>1)?(msg):NULL)
static int pd_wait_for( int unit, int w, char * msg ) /* polled wait */ static int pd_wait_for(int unit, int w, char *msg)
{ /* polled wait */
{ int k, r, e; int k, r, e;
k=0; k = 0;
while(k < PD_SPIN) { while (k < PD_SPIN) {
r = RR(1,6); r = RR(1, 6);
k++; k++;
if (((r & w) == w) && !(r & STAT_BUSY)) break; if (((r & w) == w) && !(r & STAT_BUSY))
break;
udelay(PD_SPIN_DEL); udelay(PD_SPIN_DEL);
} }
e = (RR(0,1)<<8) + RR(0,7); e = (RR(0, 1) << 8) + RR(0, 7);
if (k >= PD_SPIN) e |= ERR_TMO; if (k >= PD_SPIN)
if ((e & (STAT_ERR|ERR_TMO)) && (msg != NULL)) e |= ERR_TMO;
pd_print_error(unit,msg,e); if ((e & (STAT_ERR | ERR_TMO)) && (msg != NULL))
pd_print_error(unit, msg, e);
return e; return e;
} }
static void pd_send_command( int unit, int n, int s, int h, static void pd_send_command(int unit, int n, int s, int h, int c0, int c1, int func)
int c0, int c1, int func )
{ {
WR(0,6,DRIVE+h); WR(0, 6, DRIVE + h);
WR(0,1,0); /* the IDE task file */ WR(0, 1, 0); /* the IDE task file */
WR(0,2,n); WR(0, 2, n);
WR(0,3,s); WR(0, 3, s);
WR(0,4,c0); WR(0, 4, c0);
WR(0,5,c1); WR(0, 5, c1);
WR(0,7,func); WR(0, 7, func);
udelay(1); udelay(1);
} }
static void pd_ide_command( int unit, int func, int block, int count ) static void pd_ide_command(int unit, int func, int block, int count)
{ {
int c1, c0, h, s; int c1, c0, h, s;
...@@ -512,12 +523,12 @@ static void pd_ide_command( int unit, int func, int block, int count ) ...@@ -512,12 +523,12 @@ static void pd_ide_command( int unit, int func, int block, int count )
c1 = (block >>= 8) & 255; c1 = (block >>= 8) & 255;
h = ((block >>= 8) & 15) + 0x40; h = ((block >>= 8) & 15) + 0x40;
} else { } else {
s = ( block % PD.sectors) + 1; s = (block % PD.sectors) + 1;
h = ( block /= PD.sectors) % PD.heads; h = (block /= PD.sectors) % PD.heads;
c0 = ( block /= PD.heads) % 256; c0 = (block /= PD.heads) % 256;
c1 = (block >>= 8); c1 = (block >>= 8);
} }
pd_send_command(unit,count,s,h,c0,c1,func); pd_send_command(unit, count, s, h, c0, c1, func);
} }
/* According to the ATA standard, the default CHS geometry should be /* According to the ATA standard, the default CHS geometry should be
...@@ -526,76 +537,78 @@ static void pd_ide_command( int unit, int func, int block, int count ) ...@@ -526,76 +537,78 @@ static void pd_ide_command( int unit, int func, int block, int count )
parameters are initialised. parameters are initialised.
*/ */
static void pd_init_dev_parms( int unit ) static void pd_init_dev_parms(int unit)
{
{ pi_connect(PI); pi_connect(PI);
pd_wait_for(unit,0,DBMSG("before init_dev_parms")); pd_wait_for(unit, 0, DBMSG("before init_dev_parms"));
pd_send_command(unit,PD.sectors,0,PD.heads-1,0,0,IDE_INIT_DEV_PARMS); pd_send_command(unit, PD.sectors, 0, PD.heads - 1, 0, 0,
IDE_INIT_DEV_PARMS);
udelay(300); udelay(300);
pd_wait_for(unit,0,"Initialise device parameters"); pd_wait_for(unit, 0, "Initialise device parameters");
pi_disconnect(PI); pi_disconnect(PI);
} }
static void pd_doorlock( int unit, int func ) static void pd_doorlock(int unit, int func)
{
{ pi_connect(PI); pi_connect(PI);
if (pd_wait_for(unit,STAT_READY,"Lock") & STAT_ERR) { if (pd_wait_for(unit, STAT_READY, "Lock") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
return; return;
} }
pd_send_command(unit,1,0,0,0,0,func); pd_send_command(unit, 1, 0, 0, 0, 0, func);
pd_wait_for(unit,STAT_READY,"Lock done"); pd_wait_for(unit, STAT_READY, "Lock done");
pi_disconnect(PI); pi_disconnect(PI);
} }
static void pd_eject( int unit ) static void pd_eject(int unit)
{
{ pi_connect(PI); pi_connect(PI);
pd_wait_for(unit,0,DBMSG("before unlock on eject")); pd_wait_for(unit, 0, DBMSG("before unlock on eject"));
pd_send_command(unit,1,0,0,0,0,IDE_DOORUNLOCK); pd_send_command(unit, 1, 0, 0, 0, 0, IDE_DOORUNLOCK);
pd_wait_for(unit,0,DBMSG("after unlock on eject")); pd_wait_for(unit, 0, DBMSG("after unlock on eject"));
pd_wait_for(unit,0,DBMSG("before eject")); pd_wait_for(unit, 0, DBMSG("before eject"));
pd_send_command(unit,0,0,0,0,0,IDE_EJECT); pd_send_command(unit, 0, 0, 0, 0, 0, IDE_EJECT);
pd_wait_for(unit,0,DBMSG("after eject")); pd_wait_for(unit, 0, DBMSG("after eject"));
pi_disconnect(PI); pi_disconnect(PI);
} }
static void pd_media_check( int unit ) static void pd_media_check(int unit)
{
{ int r; int r;
pi_connect(PI); pi_connect(PI);
r = pd_wait_for(unit,STAT_READY,DBMSG("before media_check")); r = pd_wait_for(unit, STAT_READY, DBMSG("before media_check"));
if (!(r & STAT_ERR)) { if (!(r & STAT_ERR)) {
pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY); pd_send_command(unit, 1, 1, 0, 0, 0, IDE_READ_VRFY);
r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after READ_VRFY")); r = pd_wait_for(unit, STAT_READY, DBMSG("RDY after READ_VRFY"));
} else PD.changed = 1; /* say changed if other error */ } else
PD.changed = 1; /* say changed if other error */
if (r & ERR_MC) { if (r & ERR_MC) {
PD.changed = 1; PD.changed = 1;
pd_send_command(unit,1,0,0,0,0,IDE_ACKCHANGE); pd_send_command(unit, 1, 0, 0, 0, 0, IDE_ACKCHANGE);
pd_wait_for(unit,STAT_READY,DBMSG("RDY after ACKCHANGE")); pd_wait_for(unit, STAT_READY, DBMSG("RDY after ACKCHANGE"));
pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY); pd_send_command(unit, 1, 1, 0, 0, 0, IDE_READ_VRFY);
r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after VRFY")); r = pd_wait_for(unit, STAT_READY, DBMSG("RDY after VRFY"));
} }
pi_disconnect(PI); pi_disconnect(PI);
} }
static void pd_standby_off( int unit ) static void pd_standby_off(int unit)
{
{ pi_connect(PI); pi_connect(PI);
pd_wait_for(unit,0,DBMSG("before STANDBY")); pd_wait_for(unit, 0, DBMSG("before STANDBY"));
pd_send_command(unit,0,0,0,0,0,IDE_STANDBY); pd_send_command(unit, 0, 0, 0, 0, 0, IDE_STANDBY);
pd_wait_for(unit,0,DBMSG("after STANDBY")); pd_wait_for(unit, 0, DBMSG("after STANDBY"));
pi_disconnect(PI); pi_disconnect(PI);
} }
#define word_val(n) ((pd_scratch[2*n]&0xff)+256*(pd_scratch[2*n+1]&0xff)) #define word_val(n) ((pd_scratch[2*n]&0xff)+256*(pd_scratch[2*n+1]&0xff))
static int pd_identify( int unit ) static int pd_identify(int unit)
{
{ int j; int j;
char id[PD_ID_LEN+1]; char id[PD_ID_LEN + 1];
/* WARNING: here there may be dragons. reset() applies to both drives, /* WARNING: here there may be dragons. reset() applies to both drives,
but we call it only on probing the MASTER. This should allow most but we call it only on probing the MASTER. This should allow most
...@@ -603,52 +616,58 @@ static int pd_identify( int unit ) ...@@ -603,52 +616,58 @@ static int pd_identify( int unit )
settings on the SLAVE drive. settings on the SLAVE drive.
*/ */
if (PD.drive == 0) pd_reset(unit); if (PD.drive == 0)
pd_reset(unit);
pi_connect(PI); pi_connect(PI);
WR(0,6,DRIVE); WR(0, 6, DRIVE);
pd_wait_for(unit,0,DBMSG("before IDENT")); pd_wait_for(unit, 0, DBMSG("before IDENT"));
pd_send_command(unit,1,0,0,0,0,IDE_IDENTIFY); pd_send_command(unit, 1, 0, 0, 0, 0, IDE_IDENTIFY);
if (pd_wait_for(unit,STAT_DRQ,DBMSG("IDENT DRQ")) & STAT_ERR) { if (pd_wait_for(unit, STAT_DRQ, DBMSG("IDENT DRQ")) & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
return 0; return 0;
} }
pi_read_block(PI,pd_scratch,512); pi_read_block(PI, pd_scratch, 512);
pi_disconnect(PI); pi_disconnect(PI);
PD.can_lba = pd_scratch[99] & 2; PD.can_lba = pd_scratch[99] & 2;
PD.sectors = le16_to_cpu(*(u16*)(pd_scratch+12)); PD.sectors = le16_to_cpu(*(u16 *) (pd_scratch + 12));
PD.heads = le16_to_cpu(*(u16*)(pd_scratch+6)); PD.heads = le16_to_cpu(*(u16 *) (pd_scratch + 6));
PD.cylinders = le16_to_cpu(*(u16*)(pd_scratch+2)); PD.cylinders = le16_to_cpu(*(u16 *) (pd_scratch + 2));
if (PD.can_lba) if (PD.can_lba)
PD.capacity = le32_to_cpu(*(u32*)(pd_scratch + 120)); PD.capacity = le32_to_cpu(*(u32 *) (pd_scratch + 120));
else else
PD.capacity = PD.sectors*PD.heads*PD.cylinders; PD.capacity = PD.sectors * PD.heads * PD.cylinders;
for(j=0;j<PD_ID_LEN;j++) id[j^1] = pd_scratch[j+PD_ID_OFF]; for (j = 0; j < PD_ID_LEN; j++)
j = PD_ID_LEN-1; id[j ^ 1] = pd_scratch[j + PD_ID_OFF];
while ((j >= 0) && (id[j] <= 0x20)) j--; j = PD_ID_LEN - 1;
j++; id[j] = 0; while ((j >= 0) && (id[j] <= 0x20))
j--;
j++;
id[j] = 0;
PD.removable = (word_val(0) & 0x80); PD.removable = (word_val(0) & 0x80);
printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n", printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n",
PD.name,id, PD.name, id,
PD.drive?"slave":"master", PD.drive ? "slave" : "master",
PD.capacity,PD.capacity/2048, PD.capacity, PD.capacity / 2048,
PD.cylinders,PD.heads,PD.sectors, PD.cylinders, PD.heads, PD.sectors,
PD.removable?"removable":"fixed"); PD.removable ? "removable" : "fixed");
if (PD.capacity) pd_init_dev_parms(unit); if (PD.capacity)
if (!PD.standby) pd_standby_off(unit); pd_init_dev_parms(unit);
if (!PD.standby)
pd_standby_off(unit);
return 1; return 1;
} }
static int pd_probe_drive( int unit ) static int pd_probe_drive(int unit)
{ {
if (PD.drive == -1) { if (PD.drive == -1) {
for (PD.drive=0;PD.drive<=1;PD.drive++) for (PD.drive = 0; PD.drive <= 1; PD.drive++)
if (pd_identify(unit)) if (pd_identify(unit))
return 1; return 1;
return 0; return 0;
...@@ -656,31 +675,36 @@ static int pd_probe_drive( int unit ) ...@@ -656,31 +675,36 @@ static int pd_probe_drive( int unit )
return pd_identify(unit); return pd_identify(unit);
} }
static int pd_detect( void ) static int pd_detect(void)
{ {
int k, unit; int k, unit;
k = 0; k = 0;
if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
unit = 0; unit = 0;
if (pi_init(PI,1,-1,-1,-1,-1,-1,pd_scratch, if (pi_init(PI, 1, -1, -1, -1, -1, -1, pd_scratch,
PI_PD,verbose,PD.name)) { PI_PD, verbose, PD.name)) {
if (pd_probe_drive(unit)) { if (pd_probe_drive(unit)) {
PD.present = 1; PD.present = 1;
k = 1; k = 1;
} else pi_release(PI); } else
pi_release(PI);
} }
} else for (unit=0;unit<PD_UNITS;unit++) if (DU[D_PRT]) } else
if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI], for (unit = 0; unit < PD_UNITS; unit++)
DU[D_PRO],DU[D_DLY],pd_scratch, if (DU[D_PRT])
PI_PD,verbose,PD.name)) { if (pi_init
(PI, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
DU[D_PRO], DU[D_DLY], pd_scratch, PI_PD,
verbose, PD.name)) {
if (pd_probe_drive(unit)) { if (pd_probe_drive(unit)) {
PD.present = 1; PD.present = 1;
k = unit+1; k = unit + 1;
} else pi_release(PI); } else
pi_release(PI);
} }
for (unit=0;unit<PD_UNITS;unit++) { for (unit = 0; unit < PD_UNITS; unit++) {
if (PD.present) { if (PD.present) {
PD.gd.major_name = PD.name; PD.gd.major_name = PD.name;
PD.gd.minor_shift = PD_BITS; PD.gd.minor_shift = PD_BITS;
...@@ -693,24 +717,25 @@ static int pd_detect( void ) ...@@ -693,24 +717,25 @@ static int pd_detect( void )
} }
if (k) if (k)
return 1; return 1;
printk("%s: no valid drive found\n",name); printk("%s: no valid drive found\n", name);
return 0; return 0;
} }
/* The i/o request engine */ /* The i/o request engine */
static int pd_ready( void ) static int pd_ready(void)
{
{ int unit = pd_unit; int unit = pd_unit;
return (!(RR(1,6) & STAT_BUSY)) ; return (!(RR(1, 6) & STAT_BUSY));
} }
static void do_pd_request (request_queue_t * q) static void do_pd_request(request_queue_t * q)
{ {
int unit; int unit;
if (pd_busy) return; if (pd_busy)
return;
repeat: repeat:
if (blk_queue_empty(QUEUE)) if (blk_queue_empty(QUEUE))
return; return;
...@@ -722,7 +747,7 @@ static void do_pd_request (request_queue_t * q) ...@@ -722,7 +747,7 @@ static void do_pd_request (request_queue_t * q)
pd_count = CURRENT->current_nr_sectors; pd_count = CURRENT->current_nr_sectors;
if ((pd_dev >= PD_DEVS) || if ((pd_dev >= PD_DEVS) ||
((pd_block+pd_count) > get_capacity(&pd[unit].gd))) { ((pd_block + pd_count) > get_capacity(&pd[unit].gd))) {
end_request(CURRENT, 0); end_request(CURRENT, 0);
goto repeat; goto repeat;
} }
...@@ -732,21 +757,25 @@ static void do_pd_request (request_queue_t * q) ...@@ -732,21 +757,25 @@ static void do_pd_request (request_queue_t * q)
pd_retries = 0; pd_retries = 0;
pd_busy = 1; pd_busy = 1;
if (pd_cmd == READ) pi_do_claimed(PI,do_pd_read); if (pd_cmd == READ)
else if (pd_cmd == WRITE) pi_do_claimed(PI,do_pd_write); pi_do_claimed(PI, do_pd_read);
else { pd_busy = 0; else if (pd_cmd == WRITE)
pi_do_claimed(PI, do_pd_write);
else {
pd_busy = 0;
end_request(CURRENT, 0); end_request(CURRENT, 0);
goto repeat; goto repeat;
} }
} }
static void pd_next_buf( int unit ) static void pd_next_buf(int unit)
{
{ long saved_flags; long saved_flags;
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 1); end_request(CURRENT, 1);
if (!pd_run) { spin_unlock_irqrestore(&pd_lock,saved_flags); if (!pd_run) {
spin_unlock_irqrestore(&pd_lock, saved_flags);
return; return;
} }
...@@ -754,169 +783,174 @@ static void pd_next_buf( int unit ) ...@@ -754,169 +783,174 @@ static void pd_next_buf( int unit )
if (blk_queue_empty(QUEUE) || if (blk_queue_empty(QUEUE) ||
(rq_data_dir(CURRENT) != pd_cmd) || (rq_data_dir(CURRENT) != pd_cmd) ||
(minor(CURRENT->rq_dev) != pd_dev) || (minor(CURRENT->rq_dev) != pd_dev) || (CURRENT->sector != pd_block))
(CURRENT->sector != pd_block))
printk("%s: OUCH: request list changed unexpectedly\n", printk("%s: OUCH: request list changed unexpectedly\n",
PD.name); PD.name);
pd_count = CURRENT->current_nr_sectors; pd_count = CURRENT->current_nr_sectors;
pd_buf = CURRENT->buffer; pd_buf = CURRENT->buffer;
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
} }
static void do_pd_read( void ) static void do_pd_read(void)
{
{ ps_set_intr(do_pd_read_start,0,0,nice); ps_set_intr(do_pd_read_start, 0, 0, nice);
} }
static void do_pd_read_start( void ) static void do_pd_read_start(void)
{
{ int unit = pd_unit; int unit = pd_unit;
long saved_flags; long saved_flags;
pd_busy = 1; pd_busy = 1;
pi_connect(PI); pi_connect(PI);
if (pd_wait_for(unit,STAT_READY,"do_pd_read") & STAT_ERR) { if (pd_wait_for(unit, STAT_READY, "do_pd_read") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pd_retries < PD_MAX_RETRIES) { if (pd_retries < PD_MAX_RETRIES) {
pd_retries++; pd_retries++;
pi_do_claimed(PI,do_pd_read_start); pi_do_claimed(PI, do_pd_read_start);
return; return;
} }
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
return; return;
} }
pd_ide_command(unit,IDE_READ,pd_block,pd_run); pd_ide_command(unit, IDE_READ, pd_block, pd_run);
ps_set_intr(do_pd_read_drq,pd_ready,PD_TMO,nice); ps_set_intr(do_pd_read_drq, pd_ready, PD_TMO, nice);
} }
static void do_pd_read_drq( void ) static void do_pd_read_drq(void)
{
{ int unit = pd_unit; int unit = pd_unit;
long saved_flags; long saved_flags;
while (1) { while (1) {
if (pd_wait_for(unit,STAT_DRQ,"do_pd_read_drq") & STAT_ERR) { if (pd_wait_for(unit, STAT_DRQ, "do_pd_read_drq") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pd_retries < PD_MAX_RETRIES) { if (pd_retries < PD_MAX_RETRIES) {
pd_retries++; pd_retries++;
pi_do_claimed(PI,do_pd_read_start); pi_do_claimed(PI, do_pd_read_start);
return; return;
} }
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
return; return;
} }
pi_read_block(PI,pd_buf,512); pi_read_block(PI, pd_buf, 512);
pd_count--; pd_run--; pd_count--;
pd_run--;
pd_buf += 512; pd_buf += 512;
pd_block++; pd_block++;
if (!pd_run) break; if (!pd_run)
if (!pd_count) pd_next_buf(unit); break;
if (!pd_count)
pd_next_buf(unit);
} }
pi_disconnect(PI); pi_disconnect(PI);
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 1); end_request(CURRENT, 1);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
} }
static void do_pd_write( void ) static void do_pd_write(void)
{
{ ps_set_intr(do_pd_write_start,0,0,nice); ps_set_intr(do_pd_write_start, 0, 0, nice);
} }
static void do_pd_write_start( void ) static void do_pd_write_start(void)
{
{ int unit = pd_unit; int unit = pd_unit;
long saved_flags; long saved_flags;
pd_busy = 1; pd_busy = 1;
pi_connect(PI); pi_connect(PI);
if (pd_wait_for(unit,STAT_READY,"do_pd_write") & STAT_ERR) { if (pd_wait_for(unit, STAT_READY, "do_pd_write") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pd_retries < PD_MAX_RETRIES) { if (pd_retries < PD_MAX_RETRIES) {
pd_retries++; pd_retries++;
pi_do_claimed(PI,do_pd_write_start); pi_do_claimed(PI, do_pd_write_start);
return; return;
} }
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
return; return;
} }
pd_ide_command(unit,IDE_WRITE,pd_block,pd_run); pd_ide_command(unit, IDE_WRITE, pd_block, pd_run);
while (1) { while (1) {
if (pd_wait_for(unit,STAT_DRQ,"do_pd_write_drq") & STAT_ERR) { if (pd_wait_for(unit, STAT_DRQ, "do_pd_write_drq") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pd_retries < PD_MAX_RETRIES) { if (pd_retries < PD_MAX_RETRIES) {
pd_retries++; pd_retries++;
pi_do_claimed(PI,do_pd_write_start); pi_do_claimed(PI, do_pd_write_start);
return; return;
} }
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
return; return;
} }
pi_write_block(PI,pd_buf,512); pi_write_block(PI, pd_buf, 512);
pd_count--; pd_run--; pd_count--;
pd_run--;
pd_buf += 512; pd_buf += 512;
pd_block++; pd_block++;
if (!pd_run) break; if (!pd_run)
if (!pd_count) pd_next_buf(unit); break;
if (!pd_count)
pd_next_buf(unit);
} }
ps_set_intr(do_pd_write_done,pd_ready,PD_TMO,nice); ps_set_intr(do_pd_write_done, pd_ready, PD_TMO, nice);
} }
static void do_pd_write_done( void ) static void do_pd_write_done(void)
{
{ int unit = pd_unit; int unit = pd_unit;
long saved_flags; long saved_flags;
if (pd_wait_for(unit,STAT_READY,"do_pd_write_done") & STAT_ERR) { if (pd_wait_for(unit, STAT_READY, "do_pd_write_done") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pd_retries < PD_MAX_RETRIES) { if (pd_retries < PD_MAX_RETRIES) {
pd_retries++; pd_retries++;
pi_do_claimed(PI,do_pd_write_start); pi_do_claimed(PI, do_pd_write_start);
return; return;
} }
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
return; return;
} }
pi_disconnect(PI); pi_disconnect(PI);
spin_lock_irqsave(&pd_lock,saved_flags); spin_lock_irqsave(&pd_lock, saved_flags);
end_request(CURRENT, 1); end_request(CURRENT, 1);
pd_busy = 0; pd_busy = 0;
do_pd_request(NULL); do_pd_request(NULL);
spin_unlock_irqrestore(&pd_lock,saved_flags); spin_unlock_irqrestore(&pd_lock, saved_flags);
} }
static int __init pd_init(void) static int __init pd_init(void)
{ {
request_queue_t * q; request_queue_t *q;
if (disable) return -1; if (disable)
if (register_blkdev(MAJOR_NR,name,&pd_fops)) { return -1;
printk("%s: unable to get major number %d\n", if (register_blkdev(MAJOR_NR, name, &pd_fops)) {
name,major); printk("%s: unable to get major number %d\n", name, major);
return -1; return -1;
} }
q = BLK_DEFAULT_QUEUE(MAJOR_NR); q = BLK_DEFAULT_QUEUE(MAJOR_NR);
...@@ -924,7 +958,7 @@ static int __init pd_init(void) ...@@ -924,7 +958,7 @@ static int __init pd_init(void)
blk_queue_max_sectors(q, cluster); blk_queue_max_sectors(q, cluster);
printk("%s: %s version %s, major %d, cluster %d, nice %d\n", printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
name,name,PD_VERSION,major,cluster,nice); name, name, PD_VERSION, major, cluster, nice);
pd_init_units(); pd_init_units();
if (!pd_detect()) { if (!pd_detect()) {
unregister_blkdev(MAJOR_NR, name); unregister_blkdev(MAJOR_NR, name);
...@@ -937,7 +971,7 @@ static void __exit pd_exit(void) ...@@ -937,7 +971,7 @@ static void __exit pd_exit(void)
{ {
int unit; int unit;
unregister_blkdev(MAJOR_NR, name); unregister_blkdev(MAJOR_NR, name);
for (unit=0; unit<PD_UNITS; unit++) for (unit = 0; unit < PD_UNITS; unit++)
if (PD.present) { if (PD.present) {
del_gendisk(&PD.gd); del_gendisk(&PD.gd);
pi_release(PI); pi_release(PI);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment