Commit 43130446 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] Lindent pf.c

pf.c fed through lindent
parent e714bc9e
...@@ -124,19 +124,19 @@ ...@@ -124,19 +124,19 @@
*/ */
static int verbose = 0; static int verbose = 0;
static int major = PF_MAJOR; static int major = PF_MAJOR;
static char *name = PF_NAME; static char *name = PF_NAME;
static int cluster = 64; static int cluster = 64;
static int nice = 0; static int nice = 0;
static int disable = 0; static int disable = 0;
static int drive0[7] = {0,0,0,-1,-1,-1,-1}; static int drive0[7] = { 0, 0, 0, -1, -1, -1, -1 };
static int drive1[7] = {0,0,0,-1,-1,-1,-1}; static int drive1[7] = { 0, 0, 0, -1, -1, -1, -1 };
static int drive2[7] = {0,0,0,-1,-1,-1,-1}; static int drive2[7] = { 0, 0, 0, -1, -1, -1, -1 };
static int drive3[7] = {0,0,0,-1,-1,-1,-1}; static int drive3[7] = { 0, 0, 0, -1, -1, -1, -1 };
static int (*drives[4])[7] = {&drive0,&drive1,&drive2,&drive3}; static int (*drives[4])[7] = {&drive0, &drive1, &drive2, &drive3};
static int pf_drive_count; static int pf_drive_count;
#define D_PRT 0 #define D_PRT 0
...@@ -151,7 +151,6 @@ static int pf_drive_count; ...@@ -151,7 +151,6 @@ static int pf_drive_count;
/* end of parameters */ /* end of parameters */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/fs.h> #include <linux/fs.h>
...@@ -168,30 +167,32 @@ static spinlock_t pf_spin_lock; ...@@ -168,30 +167,32 @@ static spinlock_t pf_spin_lock;
#include "setup.h" #include "setup.h"
static STT pf_stt[7] = {{"drive0",7,drive0}, static STT pf_stt[7] = {
{"drive1",7,drive1}, {"drive0", 7, drive0},
{"drive2",7,drive2}, {"drive1", 7, drive1},
{"drive3",7,drive3}, {"drive2", 7, drive2},
{"disable",1,&disable}, {"drive3", 7, drive3},
{"cluster",1,&cluster}, {"disable", 1, &disable},
{"nice",1,&nice}}; {"cluster", 1, &cluster},
{"nice", 1, &nice}
void pf_setup( char *str, int *ints) };
{ generic_setup(pf_stt,7,str); void pf_setup(char *str, int *ints)
{
generic_setup(pf_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-7i"); MODULE_PARM(drive0, "1-7i");
MODULE_PARM(drive1,"1-7i"); MODULE_PARM(drive1, "1-7i");
MODULE_PARM(drive2,"1-7i"); MODULE_PARM(drive2, "1-7i");
MODULE_PARM(drive3,"1-7i"); MODULE_PARM(drive3, "1-7i");
#include "paride.h" #include "paride.h"
...@@ -207,15 +208,15 @@ MODULE_PARM(drive3,"1-7i"); ...@@ -207,15 +208,15 @@ MODULE_PARM(drive3,"1-7i");
/* constants for faking geometry numbers */ /* constants for faking geometry numbers */
#define PF_FD_MAX 8192 /* use FD geometry under this size */ #define PF_FD_MAX 8192 /* use FD geometry under this size */
#define PF_FD_HDS 2 #define PF_FD_HDS 2
#define PF_FD_SPT 18 #define PF_FD_SPT 18
#define PF_HD_HDS 64 #define PF_HD_HDS 64
#define PF_HD_SPT 32 #define PF_HD_SPT 32
#define PF_MAX_RETRIES 5 #define PF_MAX_RETRIES 5
#define PF_TMO 800 /* interrupt timeout in jiffies */ #define PF_TMO 800 /* interrupt timeout in jiffies */
#define PF_SPIN_DEL 50 /* spin delay in micro-seconds */ #define PF_SPIN_DEL 50 /* spin delay in micro-seconds */
#define PF_SPIN (1000000*PF_TMO)/(HZ*PF_SPIN_DEL) #define PF_SPIN (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
...@@ -238,24 +239,24 @@ MODULE_PARM(drive3,"1-7i"); ...@@ -238,24 +239,24 @@ MODULE_PARM(drive3,"1-7i");
#define ATAPI_WRITE_10 0x2a #define ATAPI_WRITE_10 0x2a
#ifdef MODULE #ifdef MODULE
void cleanup_module( void ); void cleanup_module(void);
#endif #endif
static int pf_open(struct inode *inode, struct file *file); static int pf_open(struct inode *inode, struct file *file);
static void do_pf_request(request_queue_t * q); static void do_pf_request(request_queue_t * q);
static int pf_ioctl(struct inode *inode,struct file *file, static int pf_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
static int pf_release (struct inode *inode, struct file *file); static int pf_release(struct inode *inode, struct file *file);
static int pf_detect(void); static int pf_detect(void);
static void do_pf_read(void); static void do_pf_read(void);
static void do_pf_read_start(void); static void do_pf_read_start(void);
static void do_pf_write(void); static void do_pf_write(void);
static void do_pf_write_start(void); static void do_pf_write_start(void);
static void do_pf_read_drq( void ); static void do_pf_read_drq(void);
static void do_pf_write_done( void ); static void do_pf_write_done(void);
static int pf_identify (int unit); static int pf_identify(int unit);
static void pf_lock(int unit, int func); static void pf_lock(int unit, int func);
static void pf_eject(int unit); static void pf_eject(int unit);
static int pf_check_media(kdev_t dev); static int pf_check_media(kdev_t dev);
...@@ -267,17 +268,17 @@ static int pf_check_media(kdev_t dev); ...@@ -267,17 +268,17 @@ static int pf_check_media(kdev_t dev);
#define PF_NAMELEN 8 #define PF_NAMELEN 8
struct pf_unit { struct pf_unit {
struct pi_adapter pia; /* interface to paride layer */ struct pi_adapter pia; /* interface to paride layer */
struct pi_adapter *pi; struct pi_adapter *pi;
int removable; /* removable media device ? */ int removable; /* removable media device ? */
int media_status; /* media present ? WP ? */ int media_status; /* media present ? WP ? */
int drive; /* drive */ int drive; /* drive */
int lun; int lun;
int access; /* count of active opens ... */ int access; /* count of active opens ... */
int capacity; /* Size of this volume in sectors */ int capacity; /* Size of this volume in sectors */
int present; /* device present ? */ int present; /* device present ? */
char name[PF_NAMELEN]; /* pf0, pf1, ... */ char name[PF_NAMELEN]; /* pf0, pf1, ... */
}; };
struct pf_unit pf[PF_UNITS]; struct pf_unit pf[PF_UNITS];
...@@ -286,140 +287,147 @@ struct pf_unit pf[PF_UNITS]; ...@@ -286,140 +287,147 @@ struct pf_unit pf[PF_UNITS];
#define PF pf[unit] #define PF pf[unit]
#define PI PF.pi #define PI PF.pi
static char pf_scratch[512]; /* scratch block buffer */ static char pf_scratch[512]; /* scratch block buffer */
/* the variables below are used mainly in the I/O request engine, which /* the variables below are used mainly in the I/O request engine, which
processes only one request at a time. processes only one request at a time.
*/ */
static int pf_retries = 0; /* i/o error retry count */ static int pf_retries = 0; /* i/o error retry count */
static int pf_busy = 0; /* request being processed ? */ static int pf_busy = 0; /* request being processed ? */
static int pf_block; /* address of next requested block */ static int pf_block; /* address of next requested block */
static int pf_count; /* number of blocks still to do */ static int pf_count; /* number of blocks still to do */
static int pf_run; /* sectors in current cluster */ static int pf_run; /* sectors in current cluster */
static int pf_cmd; /* current command READ/WRITE */ static int pf_cmd; /* current command READ/WRITE */
static int pf_unit; /* unit of current request */ static int pf_unit; /* unit of current request */
static int pf_mask; /* stopper for pseudo-int */ static int pf_mask; /* stopper for pseudo-int */
static char * pf_buf; /* buffer for request in progress */ static char *pf_buf; /* buffer for request in progress */
/* kernel glue structures */ /* kernel glue structures */
static struct block_device_operations pf_fops = { static struct block_device_operations pf_fops = {
owner: THIS_MODULE, owner:THIS_MODULE,
open: pf_open, open:pf_open,
release: pf_release, release:pf_release,
ioctl: pf_ioctl, ioctl:pf_ioctl,
check_media_change: pf_check_media, check_media_change:pf_check_media,
}; };
void pf_init_units( void ) void pf_init_units(void)
{
{ int unit, j; int unit, j;
pf_drive_count = 0; pf_drive_count = 0;
for (unit=0;unit<PF_UNITS;unit++) { for (unit = 0; unit < PF_UNITS; unit++) {
PF.pi = & PF.pia; PF.pi = &PF.pia;
PF.access = 0; PF.access = 0;
PF.media_status = PF_NM; PF.media_status = PF_NM;
PF.capacity = 0; PF.capacity = 0;
PF.present = 0; PF.present = 0;
PF.drive = DU[D_SLV]; PF.drive = DU[D_SLV];
PF.lun = DU[D_LUN]; PF.lun = DU[D_LUN];
j = 0; j = 0;
while ((j < PF_NAMELEN-2) && (PF.name[j]=name[j])) j++; while ((j < PF_NAMELEN - 2) && (PF.name[j] = name[j]))
PF.name[j++] = '0' + unit; j++;
PF.name[j] = 0; PF.name[j++] = '0' + unit;
if (DU[D_PRT]) pf_drive_count++; PF.name[j] = 0;
} if (DU[D_PRT])
} pf_drive_count++;
}
static int pf_open (struct inode *inode, struct file *file) }
{ int unit = DEVICE_NR(inode->i_rdev); static int pf_open(struct inode *inode, struct file *file)
{
int unit = DEVICE_NR(inode->i_rdev);
if ((unit >= PF_UNITS) || (!PF.present)) return -ENODEV; if ((unit >= PF_UNITS) || (!PF.present))
return -ENODEV;
pf_identify(unit); pf_identify(unit);
if (PF.media_status == PF_NM) if (PF.media_status == PF_NM)
return -ENODEV; return -ENODEV;
if ((PF.media_status == PF_RO) && (file ->f_mode & 2)) if ((PF.media_status == PF_RO) && (file->f_mode & 2))
return -EROFS; return -EROFS;
PF.access++; PF.access++;
if (PF.removable) pf_lock(unit,1); if (PF.removable)
pf_lock(unit, 1);
return 0; return 0;
} }
static int pf_ioctl(struct inode *inode,struct file *file, static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long arg) {
int err, unit;
{ int err, unit;
struct hd_geometry *geo = (struct hd_geometry *) arg; struct hd_geometry *geo = (struct hd_geometry *) arg;
if ((!inode) || kdev_none(inode->i_rdev)) return -EINVAL; if ((!inode) || kdev_none(inode->i_rdev))
unit = DEVICE_NR(inode->i_rdev); return -EINVAL;
if (unit >= PF_UNITS) return -EINVAL; unit = DEVICE_NR(inode->i_rdev);
if (!PF.present) return -ENODEV; if (unit >= PF_UNITS)
return -EINVAL;
if (!PF.present)
return -ENODEV;
switch (cmd) { switch (cmd) {
case CDROMEJECT: case CDROMEJECT:
if (PF.access == 1) { if (PF.access == 1) {
pf_eject(unit); pf_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 (PF.capacity < PF_FD_MAX) { if (err)
put_user(PF.capacity/(PF_FD_HDS*PF_FD_SPT), return err;
(short *) &geo->cylinders); if (PF.capacity < PF_FD_MAX) {
put_user(PF_FD_HDS, (char *) &geo->heads); put_user(PF.capacity / (PF_FD_HDS * PF_FD_SPT),
put_user(PF_FD_SPT, (char *) &geo->sectors); (short *) &geo->cylinders);
} else { put_user(PF_FD_HDS, (char *) &geo->heads);
put_user(PF.capacity/(PF_HD_HDS*PF_HD_SPT), put_user(PF_FD_SPT, (char *) &geo->sectors);
(short *) &geo->cylinders); } else {
put_user(PF_HD_HDS, (char *) &geo->heads); put_user(PF.capacity / (PF_HD_HDS * PF_HD_SPT),
put_user(PF_HD_SPT, (char *) &geo->sectors); (short *) &geo->cylinders);
} put_user(PF_HD_HDS, (char *) &geo->heads);
put_user(0,(long *)&geo->start); put_user(PF_HD_SPT, (char *) &geo->sectors);
return 0; }
case BLKGETSIZE: put_user(0, (long *) &geo->start);
return put_user(PF.capacity,(long *) arg); return 0;
case BLKGETSIZE64: case BLKGETSIZE:
return put_user((u64)PF.capacity << 9,(u64 *)arg); return put_user(PF.capacity, (long *) arg);
default: case BLKGETSIZE64:
return -EINVAL; return put_user((u64) PF.capacity << 9, (u64 *) arg);
} default:
return -EINVAL;
}
} }
static int pf_release(struct inode *inode, struct file *file)
{
kdev_t devp;
int unit;
static int pf_release (struct inode *inode, struct file *file) devp = inode->i_rdev;
unit = DEVICE_NR(devp);
{ kdev_t devp;
int unit;
devp = inode->i_rdev;
unit = DEVICE_NR(devp);
if ((unit >= PF_UNITS) || (PF.access <= 0)) if ((unit >= PF_UNITS) || (PF.access <= 0))
return -EINVAL; return -EINVAL;
PF.access--; PF.access--;
if (!PF.access && PF.removable) if (!PF.access && PF.removable)
pf_lock(unit,0); pf_lock(unit, 0);
return 0; return 0;
} }
static int pf_check_media( kdev_t dev) static int pf_check_media(kdev_t dev)
{
{ return 1; return 1;
} }
static inline int status_reg(int unit) static inline int status_reg(int unit)
...@@ -440,237 +448,254 @@ static inline void write_reg(int unit, int reg, int val) ...@@ -440,237 +448,254 @@ static inline void write_reg(int unit, int reg, int val)
#define LUN (0x20*PF.lun) #define LUN (0x20*PF.lun)
#define DRIVE (0xa0+0x10*PF.drive) #define DRIVE (0xa0+0x10*PF.drive)
static int pf_wait( int unit, int go, int stop, char * fun, char * msg ) static int pf_wait(int unit, int go, int stop, char *fun, char *msg)
{
{ int j, r, e, s, p; int j, r, e, s, p;
j = 0; j = 0;
while ((((r=status_reg(unit))&go)||(stop&&(!(r&stop))))&&(j++<PF_SPIN)) while ((((r = status_reg(unit)) & go) || (stop && (!(r & stop))))
udelay(PF_SPIN_DEL); && (j++ < PF_SPIN))
udelay(PF_SPIN_DEL);
if ((r&(STAT_ERR&stop))||(j>=PF_SPIN)) {
s = read_reg(unit, 7); if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
e = read_reg(unit, 1); s = read_reg(unit, 7);
p = read_reg(unit, 2); e = read_reg(unit, 1);
if (j >= PF_SPIN) e |= 0x100; p = read_reg(unit, 2);
if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" if (j >= PF_SPIN)
" loop=%d phase=%d\n", e |= 0x100;
PF.name,fun,msg,r,s,e,j,p); if (fun)
return (e<<8)+s; printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
} " loop=%d phase=%d\n",
return 0; PF.name, fun, msg, r, s, e, j, p);
return (e << 8) + s;
}
return 0;
} }
static int pf_command( int unit, char * cmd, int dlen, char * fun ) static int pf_command(int unit, char *cmd, int dlen, char *fun)
{
{ pi_connect(PI); pi_connect(PI);
write_reg(unit, 6,DRIVE); write_reg(unit, 6, DRIVE);
if (pf_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) { if (pf_wait(unit, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
pi_disconnect(PI); pi_disconnect(PI);
return -1; return -1;
} }
write_reg(unit, 4,dlen % 256); write_reg(unit, 4, dlen % 256);
write_reg(unit, 5,dlen / 256); write_reg(unit, 5, dlen / 256);
write_reg(unit, 7,0xa0); /* ATAPI packet command */ write_reg(unit, 7, 0xa0); /* ATAPI packet command */
if (pf_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) { if (pf_wait(unit, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
pi_disconnect(PI); pi_disconnect(PI);
return -1; return -1;
} }
if (read_reg(unit, 2) != 1) { if (read_reg(unit, 2) != 1) {
printk("%s: %s: command phase error\n",PF.name,fun); printk("%s: %s: command phase error\n", PF.name, fun);
pi_disconnect(PI); pi_disconnect(PI);
return -1; return -1;
} }
pi_write_block(PI,cmd,12); pi_write_block(PI, cmd, 12);
return 0; return 0;
} }
static int pf_completion( int unit, char * buf, char * fun ) static int pf_completion(int unit, char *buf, char *fun)
{
{ int r, s, n; int r, s, n;
r = pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR, r = pf_wait(unit, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
fun,"completion"); fun, "completion");
if ((read_reg(unit, 2)&2) && (read_reg(unit, 7)&STAT_DRQ)) { if ((read_reg(unit, 2) & 2) && (read_reg(unit, 7) & STAT_DRQ)) {
n = (((read_reg(unit, 4)+256*read_reg(unit, 5))+3)&0xfffc); n = (((read_reg(unit, 4) + 256 * read_reg(unit, 5)) +
pi_read_block(PI,buf,n); 3) & 0xfffc);
} pi_read_block(PI, buf, n);
}
s = pf_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done"); s = pf_wait(unit, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
pi_disconnect(PI); pi_disconnect(PI);
return (r?r:s); return (r ? r : s);
} }
static void pf_req_sense( int unit, int quiet ) static void pf_req_sense(int unit, int quiet)
{
{ char rs_cmd[12] = { ATAPI_REQ_SENSE,LUN,0,0,16,0,0,0,0,0,0,0 }; char rs_cmd[12] =
char buf[16]; { ATAPI_REQ_SENSE, LUN, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
int r; char buf[16];
int r;
r = pf_command(unit,rs_cmd,16,"Request sense");
mdelay(1); r = pf_command(unit, rs_cmd, 16, "Request sense");
if (!r) pf_completion(unit,buf,"Request sense"); mdelay(1);
if (!r)
if ((!r)&&(!quiet)) pf_completion(unit, buf, "Request sense");
printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
PF.name,buf[2]&0xf,buf[12],buf[13]); if ((!r) && (!quiet))
printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
PF.name, buf[2] & 0xf, buf[12], buf[13]);
} }
static int pf_atapi( int unit, char * cmd, int dlen, char * buf, char * fun ) static int pf_atapi(int unit, char *cmd, int dlen, char *buf, char *fun)
{
int r;
{ int r; r = pf_command(unit, cmd, dlen, fun);
mdelay(1);
if (!r)
r = pf_completion(unit, buf, fun);
if (r)
pf_req_sense(unit, !fun);
r = pf_command(unit,cmd,dlen,fun); return r;
mdelay(1);
if (!r) r = pf_completion(unit,buf,fun);
if (r) pf_req_sense(unit,!fun);
return r;
} }
#define DBMSG(msg) ((verbose>1)?(msg):NULL) #define DBMSG(msg) ((verbose>1)?(msg):NULL)
static void pf_lock(int unit, int func) static void pf_lock(int unit, int func)
{
char lo_cmd[12] = { ATAPI_LOCK, LUN, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 };
{ char lo_cmd[12] = { ATAPI_LOCK,LUN,0,0,func,0,0,0,0,0,0,0 }; pf_atapi(unit, lo_cmd, 0, pf_scratch, func ? "unlock" : "lock");
pf_atapi(unit,lo_cmd,0,pf_scratch,func?"unlock":"lock");
} }
static void pf_eject(int unit)
{
char ej_cmd[12] = { ATAPI_DOOR, LUN, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 };
static void pf_eject( int unit ) pf_lock(unit, 0);
pf_atapi(unit, ej_cmd, 0, pf_scratch, "eject");
{ char ej_cmd[12] = { ATAPI_DOOR,LUN,0,0,2,0,0,0,0,0,0,0 };
pf_lock(unit,0);
pf_atapi(unit,ej_cmd,0,pf_scratch,"eject");
} }
#define PF_RESET_TMO 30 /* in tenths of a second */ #define PF_RESET_TMO 30 /* in tenths of a second */
static void pf_sleep( int cs ) static void pf_sleep(int cs)
{
{ current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule_timeout(cs); schedule_timeout(cs);
} }
static int pf_reset( int unit )
/* the ATAPI standard actually specifies the contents of all 7 registers /* the ATAPI standard actually specifies the contents of all 7 registers
after a reset, but the specification is ambiguous concerning the last after a reset, but the specification is ambiguous concerning the last
two bytes, and different drives interpret the standard differently. two bytes, and different drives interpret the standard differently.
*/ */
{ int i, k, flg; static int pf_reset(int unit)
int expect[5] = {1,1,1,0x14,0xeb}; {
int i, k, flg;
int expect[5] = { 1, 1, 1, 0x14, 0xeb };
pi_connect(PI); pi_connect(PI);
write_reg(unit, 6,DRIVE); write_reg(unit, 6, DRIVE);
write_reg(unit, 7,8); write_reg(unit, 7, 8);
pf_sleep(20*HZ/1000); pf_sleep(20 * HZ / 1000);
k = 0; k = 0;
while ((k++ < PF_RESET_TMO) && (status_reg(unit)&STAT_BUSY)) while ((k++ < PF_RESET_TMO) && (status_reg(unit) & STAT_BUSY))
pf_sleep(HZ/10); pf_sleep(HZ / 10);
flg = 1; flg = 1;
for(i=0;i<5;i++) flg &= (read_reg(unit, i+1) == expect[i]); for (i = 0; i < 5; i++)
flg &= (read_reg(unit, i + 1) == expect[i]);
if (verbose) { if (verbose) {
printk("%s: Reset (%d) signature = ",PF.name,k); printk("%s: Reset (%d) signature = ", PF.name, k);
for (i=0;i<5;i++) printk("%3x",read_reg(unit, i+1)); for (i = 0; i < 5; i++)
if (!flg) printk(" (incorrect)"); printk("%3x", read_reg(unit, i + 1));
if (!flg)
printk(" (incorrect)");
printk("\n"); printk("\n");
} }
pi_disconnect(PI); pi_disconnect(PI);
return flg-1; return flg - 1;
} }
static void pf_mode_sense( int unit ) static void pf_mode_sense(int unit)
{
{ char ms_cmd[12] = { ATAPI_MODE_SENSE,LUN,0,0,0,0,0,0,8,0,0,0}; char ms_cmd[12] =
char buf[8]; { ATAPI_MODE_SENSE, LUN, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 };
char buf[8];
pf_atapi(unit,ms_cmd,8,buf,DBMSG("mode sense")); pf_atapi(unit, ms_cmd, 8, buf, DBMSG("mode sense"));
PF.media_status = PF_RW; PF.media_status = PF_RW;
if (buf[3] & 0x80) PF.media_status = PF_RO; if (buf[3] & 0x80)
PF.media_status = PF_RO;
} }
static void xs( char *buf, char *targ, int offs, int len ) static void xs(char *buf, char *targ, int offs, int len)
{
{ int j,k,l; int j, k, l;
j=0; l=0; j = 0;
for (k=0;k<len;k++) l = 0;
if((buf[k+offs]!=0x20)||(buf[k+offs]!=l)) for (k = 0; k < len; k++)
l=targ[j++]=buf[k+offs]; if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
if (l==0x20) j--; l = targ[j++] = buf[k + offs];
targ[j]=0; if (l == 0x20)
j--;
targ[j] = 0;
} }
static int xl( char *buf, int offs ) static int xl(char *buf, int offs)
{
{ int v,k; int v, k;
v=0; v = 0;
for(k=0;k<4;k++) v=v*256+(buf[k+offs]&0xff); for (k = 0; k < 4; k++)
v = v * 256 + (buf[k + offs] & 0xff);
return v; return v;
} }
static void pf_get_capacity( int unit ) static void pf_get_capacity(int unit)
{
{ char rc_cmd[12] = { ATAPI_CAPACITY,LUN,0,0,0,0,0,0,0,0,0,0}; char rc_cmd[12] = { ATAPI_CAPACITY, LUN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char buf[8]; char buf[8];
int bs; int bs;
if (pf_atapi(unit,rc_cmd,8,buf,DBMSG("get capacity"))) { if (pf_atapi(unit, rc_cmd, 8, buf, DBMSG("get capacity"))) {
PF.media_status = PF_NM; PF.media_status = PF_NM;
return; return;
} }
PF.capacity = xl(buf,0) + 1; PF.capacity = xl(buf, 0) + 1;
bs = xl(buf,4); bs = xl(buf, 4);
if (bs != 512) { if (bs != 512) {
PF.capacity = 0; PF.capacity = 0;
if (verbose) printk("%s: Drive %d, LUN %d," if (verbose)
" unsupported block size %d\n", printk("%s: Drive %d, LUN %d,"
PF.name,PF.drive,PF.lun,bs); " unsupported block size %d\n",
} PF.name, PF.drive, PF.lun, bs);
}
} }
static int pf_identify( int unit ) static int pf_identify(int unit)
{
{ int dt, s; int dt, s;
char *ms[2] = {"master","slave"}; char *ms[2] = { "master", "slave" };
char mf[10], id[18]; char mf[10], id[18];
char id_cmd[12] = { ATAPI_IDENTIFY,LUN,0,0,36,0,0,0,0,0,0,0}; char id_cmd[12] =
char buf[36]; { ATAPI_IDENTIFY, LUN, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
char buf[36];
s = pf_atapi(unit,id_cmd,36,buf,"identify");
if (s) return -1; s = pf_atapi(unit, id_cmd, 36, buf, "identify");
if (s)
return -1;
dt = buf[0] & 0x1f; dt = buf[0] & 0x1f;
if ((dt != 0) && (dt != 7)) { if ((dt != 0) && (dt != 7)) {
if (verbose) if (verbose)
printk("%s: Drive %d, LUN %d, unsupported type %d\n", printk("%s: Drive %d, LUN %d, unsupported type %d\n",
PF.name,PF.drive,PF.lun,dt); PF.name, PF.drive, PF.lun, dt);
return -1; return -1;
} }
xs(buf,mf,8,8); xs(buf, mf, 8, 8);
xs(buf,id,16,16); xs(buf, id, 16, 16);
PF.removable = (buf[1] & 0x80); PF.removable = (buf[1] & 0x80);
...@@ -680,313 +705,337 @@ static int pf_identify( int unit ) ...@@ -680,313 +705,337 @@ static int pf_identify( int unit )
pf_get_capacity(unit); pf_get_capacity(unit);
printk("%s: %s %s, %s LUN %d, type %d", printk("%s: %s %s, %s LUN %d, type %d",
PF.name,mf,id,ms[PF.drive],PF.lun,dt); PF.name, mf, id, ms[PF.drive], PF.lun, dt);
if (PF.removable) printk(", removable"); if (PF.removable)
if (PF.media_status == PF_NM) printk(", removable");
printk(", no media\n"); if (PF.media_status == PF_NM)
else { if (PF.media_status == PF_RO) printk(", RO"); printk(", no media\n");
printk(", %d blocks\n",PF.capacity); else {
} if (PF.media_status == PF_RO)
printk(", RO");
printk(", %d blocks\n", PF.capacity);
}
return 0; return 0;
} }
static int pf_probe( int unit )
/* returns 0, with id set if drive is detected /* returns 0, with id set if drive is detected
-1, if drive detection failed -1, if drive detection failed
*/ */
static int pf_probe(int unit)
{ if (PF.drive == -1) { {
for (PF.drive=0;PF.drive<=1;PF.drive++) if (PF.drive == -1) {
if (!pf_reset(unit)) { for (PF.drive = 0; PF.drive <= 1; PF.drive++)
if (PF.lun != -1) return pf_identify(unit); if (!pf_reset(unit)) {
else for (PF.lun=0;PF.lun<8;PF.lun++) if (PF.lun != -1)
if (!pf_identify(unit)) return 0; return pf_identify(unit);
} else
for (PF.lun = 0; PF.lun < 8; PF.lun++)
if (!pf_identify(unit))
return 0;
}
} else { } else {
if (pf_reset(unit)) return -1; if (pf_reset(unit))
if (PF.lun != -1) return pf_identify(unit); return -1;
for (PF.lun=0;PF.lun<8;PF.lun++) if (PF.lun != -1)
if (!pf_identify(unit)) return 0; return pf_identify(unit);
for (PF.lun = 0; PF.lun < 8; PF.lun++)
if (!pf_identify(unit))
return 0;
} }
return -1; return -1;
} }
static int pf_detect( void ) static int pf_detect(void)
{
{ int k, unit; int k, unit;
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,PF_VERSION,major,cluster,nice); name, name, PF_VERSION, major, cluster, nice);
k = 0; k = 0;
if (pf_drive_count == 0) { if (pf_drive_count == 0) {
unit = 0; unit = 0;
if (pi_init(PI,1,-1,-1,-1,-1,-1,pf_scratch, if (pi_init(PI, 1, -1, -1, -1, -1, -1, pf_scratch,
PI_PF,verbose,PF.name)) { PI_PF, verbose, PF.name)) {
if (!pf_probe(unit)) { if (!pf_probe(unit)) {
PF.present = 1; PF.present = 1;
k++; k++;
} else pi_release(PI); } else
} pi_release(PI);
}
} else for (unit=0;unit<PF_UNITS;unit++) if (DU[D_PRT])
if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI], } else
DU[D_PRO],DU[D_DLY],pf_scratch,PI_PF,verbose, for (unit = 0; unit < PF_UNITS; unit++)
PF.name)) { if (DU[D_PRT])
if (!pf_probe(unit)) { if (pi_init
PF.present = 1; (PI, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
k++; DU[D_PRO], DU[D_DLY], pf_scratch, PI_PF,
} else pi_release(PI); verbose, PF.name)) {
} if (!pf_probe(unit)) {
PF.present = 1;
if (k) return 0; k++;
} else
printk("%s: No ATAPI disk detected\n",name); pi_release(PI);
}
if (k)
return 0;
printk("%s: No ATAPI disk detected\n", name);
return -1; return -1;
} }
/* The i/o request engine */ /* The i/o request engine */
static int pf_start( int unit, int cmd, int b, int c ) static int pf_start(int unit, int cmd, int b, int c)
{
{ int i; int i;
char io_cmd[12] = {cmd,LUN,0,0,0,0,0,0,0,0,0,0}; char io_cmd[12] = { cmd, LUN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for(i=0;i<4;i++) { for (i = 0; i < 4; i++) {
io_cmd[5-i] = b & 0xff; io_cmd[5 - i] = b & 0xff;
b = b >> 8; b = b >> 8;
} }
io_cmd[8] = c & 0xff; io_cmd[8] = c & 0xff;
io_cmd[7] = (c >> 8) & 0xff; io_cmd[7] = (c >> 8) & 0xff;
i = pf_command(unit,io_cmd,c*512,"start i/o"); i = pf_command(unit, io_cmd, c * 512, "start i/o");
mdelay(1); mdelay(1);
return i; return i;
} }
static int pf_ready( void ) static int pf_ready(void)
{
{ int unit = pf_unit; int unit = pf_unit;
return (((status_reg(unit)&(STAT_BUSY|pf_mask)) == pf_mask)); return (((status_reg(unit) & (STAT_BUSY | pf_mask)) == pf_mask));
} }
static void do_pf_request (request_queue_t * q) static void do_pf_request(request_queue_t * q)
{ {
int unit; int unit;
if (pf_busy) return; if (pf_busy)
repeat: return;
repeat:
if (blk_queue_empty(QUEUE)) if (blk_queue_empty(QUEUE))
return; return;
pf_unit = unit = DEVICE_NR(CURRENT->rq_dev); pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
pf_block = CURRENT->sector; pf_block = CURRENT->sector;
pf_run = CURRENT->nr_sectors; pf_run = CURRENT->nr_sectors;
pf_count = CURRENT->current_nr_sectors; pf_count = CURRENT->current_nr_sectors;
if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) { if ((pf_unit >= PF_UNITS) || (pf_block + pf_count > PF.capacity)) {
end_request(CURRENT, 0); end_request(CURRENT, 0);
goto repeat; goto repeat;
} }
pf_cmd = rq_data_dir(CURRENT); pf_cmd = rq_data_dir(CURRENT);
pf_buf = CURRENT->buffer; pf_buf = CURRENT->buffer;
pf_retries = 0; pf_retries = 0;
pf_busy = 1; pf_busy = 1;
if (pf_cmd == READ) pi_do_claimed(PI,do_pf_read); if (pf_cmd == READ)
else if (pf_cmd == WRITE) pi_do_claimed(PI,do_pf_write); pi_do_claimed(PI, do_pf_read);
else { pf_busy = 0; else if (pf_cmd == WRITE)
pi_do_claimed(PI, do_pf_write);
else {
pf_busy = 0;
end_request(CURRENT, 0); end_request(CURRENT, 0);
goto repeat; goto repeat;
} }
} }
static void pf_next_buf( int unit ) static void pf_next_buf(int unit)
{
{ long saved_flags; long saved_flags;
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 1); end_request(CURRENT, 1);
if (!pf_run) { spin_unlock_irqrestore(&pf_spin_lock,saved_flags); if (!pf_run) {
return; spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return;
} }
/* paranoia */ /* paranoia */
if (blk_queue_empty(QUEUE) || if (blk_queue_empty(QUEUE) ||
(rq_data_dir(CURRENT) != pf_cmd) || (rq_data_dir(CURRENT) != pf_cmd) ||
(DEVICE_NR(CURRENT->rq_dev) != pf_unit) || (DEVICE_NR(CURRENT->rq_dev) != pf_unit) ||
(CURRENT->sector != pf_block)) (CURRENT->sector != pf_block))
printk("%s: OUCH: request list changed unexpectedly\n", printk("%s: OUCH: request list changed unexpectedly\n",
PF.name); PF.name);
pf_count = CURRENT->current_nr_sectors; pf_count = CURRENT->current_nr_sectors;
pf_buf = CURRENT->buffer; pf_buf = CURRENT->buffer;
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
} }
static void do_pf_read( void )
/* detach from the calling context - in case the spinlock is held */ /* detach from the calling context - in case the spinlock is held */
static void do_pf_read(void)
{ ps_set_intr(do_pf_read_start,0,0,nice); {
ps_set_intr(do_pf_read_start, 0, 0, nice);
} }
static void do_pf_read_start( void ) static void do_pf_read_start(void)
{
{ int unit = pf_unit; int unit = pf_unit;
long saved_flags; long saved_flags;
pf_busy = 1; pf_busy = 1;
if (pf_start(unit,ATAPI_READ_10,pf_block,pf_run)) { if (pf_start(unit, ATAPI_READ_10, pf_block, pf_run)) {
pi_disconnect(PI); pi_disconnect(PI);
if (pf_retries < PF_MAX_RETRIES) { if (pf_retries < PF_MAX_RETRIES) {
pf_retries++; pf_retries++;
pi_do_claimed(PI,do_pf_read_start); pi_do_claimed(PI, do_pf_read_start);
return; return;
} }
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pf_busy = 0; pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return; return;
} }
pf_mask = STAT_DRQ; pf_mask = STAT_DRQ;
ps_set_intr(do_pf_read_drq,pf_ready,PF_TMO,nice); ps_set_intr(do_pf_read_drq, pf_ready, PF_TMO, nice);
} }
static void do_pf_read_drq( void ) static void do_pf_read_drq(void)
{
int unit = pf_unit;
long saved_flags;
{ int unit = pf_unit;
long saved_flags;
while (1) { while (1) {
if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR, if (pf_wait(unit, STAT_BUSY, STAT_DRQ | STAT_ERR,
"read block","completion") & STAT_ERR) { "read block", "completion") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pf_retries < PF_MAX_RETRIES) { if (pf_retries < PF_MAX_RETRIES) {
pf_req_sense(unit,0); pf_req_sense(unit, 0);
pf_retries++; pf_retries++;
pi_do_claimed(PI,do_pf_read_start); pi_do_claimed(PI, do_pf_read_start);
return; return;
} }
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pf_busy = 0; pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return; return;
} }
pi_read_block(PI,pf_buf,512); pi_read_block(PI, pf_buf, 512);
pf_count--; pf_run--; pf_count--;
pf_buf += 512; pf_run--;
pf_block++; pf_buf += 512;
if (!pf_run) break; pf_block++;
if (!pf_count) pf_next_buf(unit); if (!pf_run)
} break;
pi_disconnect(PI); if (!pf_count)
spin_lock_irqsave(&pf_spin_lock,saved_flags); pf_next_buf(unit);
end_request(CURRENT, 1); }
pf_busy = 0; pi_disconnect(PI);
spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 1);
pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
} }
static void do_pf_write( void ) static void do_pf_write(void)
{
{ ps_set_intr(do_pf_write_start,0,0,nice); ps_set_intr(do_pf_write_start, 0, 0, nice);
} }
static void do_pf_write_start( void ) static void do_pf_write_start(void)
{
{ int unit = pf_unit; int unit = pf_unit;
long saved_flags; long saved_flags;
pf_busy = 1; pf_busy = 1;
if (pf_start(unit,ATAPI_WRITE_10,pf_block,pf_run)) { if (pf_start(unit, ATAPI_WRITE_10, pf_block, pf_run)) {
pi_disconnect(PI); pi_disconnect(PI);
if (pf_retries < PF_MAX_RETRIES) { if (pf_retries < PF_MAX_RETRIES) {
pf_retries++; pf_retries++;
pi_do_claimed(PI,do_pf_write_start); pi_do_claimed(PI, do_pf_write_start);
return; return;
} }
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pf_busy = 0; pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return; return;
} }
while (1) { while (1) {
if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR, if (pf_wait(unit, STAT_BUSY, STAT_DRQ | STAT_ERR,
"write block","data wait") & STAT_ERR) { "write block", "data wait") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pf_retries < PF_MAX_RETRIES) { if (pf_retries < PF_MAX_RETRIES) {
pf_retries++; pf_retries++;
pi_do_claimed(PI,do_pf_write_start); pi_do_claimed(PI, do_pf_write_start);
return; return;
} }
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pf_busy = 0; pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return; return;
} }
pi_write_block(PI,pf_buf,512); pi_write_block(PI, pf_buf, 512);
pf_count--; pf_run--; pf_count--;
pf_buf += 512; pf_run--;
pf_block++; pf_buf += 512;
if (!pf_run) break; pf_block++;
if (!pf_count) pf_next_buf(unit); if (!pf_run)
break;
if (!pf_count)
pf_next_buf(unit);
} }
pf_mask = 0; pf_mask = 0;
ps_set_intr(do_pf_write_done,pf_ready,PF_TMO,nice); ps_set_intr(do_pf_write_done, pf_ready, PF_TMO, nice);
} }
static void do_pf_write_done( void ) static void do_pf_write_done(void)
{
{ int unit = pf_unit; int unit = pf_unit;
long saved_flags; long saved_flags;
if (pf_wait(unit,STAT_BUSY,0,"write block","done") & STAT_ERR) { if (pf_wait(unit, STAT_BUSY, 0, "write block", "done") & STAT_ERR) {
pi_disconnect(PI); pi_disconnect(PI);
if (pf_retries < PF_MAX_RETRIES) { if (pf_retries < PF_MAX_RETRIES) {
pf_retries++; pf_retries++;
pi_do_claimed(PI,do_pf_write_start); pi_do_claimed(PI, do_pf_write_start);
return; return;
} }
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 0); end_request(CURRENT, 0);
pf_busy = 0; pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return; return;
} }
pi_disconnect(PI); pi_disconnect(PI);
spin_lock_irqsave(&pf_spin_lock,saved_flags); spin_lock_irqsave(&pf_spin_lock, saved_flags);
end_request(CURRENT, 1); end_request(CURRENT, 1);
pf_busy = 0; pf_busy = 0;
do_pf_request(NULL); do_pf_request(NULL);
spin_unlock_irqrestore(&pf_spin_lock,saved_flags); spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
} }
static int __init pf_init(void) /* preliminary initialisation */ static int __init pf_init(void)
{ { /* preliminary initialisation */
int i; int i;
request_queue_t * q; request_queue_t *q;
if (disable) if (disable)
return -1; return -1;
...@@ -997,7 +1046,7 @@ static int __init pf_init(void) /* preliminary initialisation */ ...@@ -997,7 +1046,7 @@ static int __init pf_init(void) /* preliminary initialisation */
return -1; return -1;
pf_busy = 0; pf_busy = 0;
if (register_blkdev(MAJOR_NR,name,&pf_fops)) { if (register_blkdev(MAJOR_NR, name, &pf_fops)) {
printk("pf_init: unable to get major number %d\n", major); printk("pf_init: unable to get major number %d\n", major);
return -1; return -1;
} }
...@@ -1006,7 +1055,7 @@ static int __init pf_init(void) /* preliminary initialisation */ ...@@ -1006,7 +1055,7 @@ static int __init pf_init(void) /* preliminary initialisation */
blk_queue_max_phys_segments(q, cluster); blk_queue_max_phys_segments(q, cluster);
blk_queue_max_hw_segments(q, cluster); blk_queue_max_hw_segments(q, cluster);
for (i=0;i<PF_UNITS;i++) for (i = 0; i < PF_UNITS; i++)
register_disk(NULL, mk_kdev(MAJOR_NR, i), 1, &pf_fops, 0); register_disk(NULL, mk_kdev(MAJOR_NR, i), 1, &pf_fops, 0);
return 0; return 0;
...@@ -1015,12 +1064,12 @@ static int __init pf_init(void) /* preliminary initialisation */ ...@@ -1015,12 +1064,12 @@ static int __init pf_init(void) /* preliminary initialisation */
static void __exit pf_exit(void) static void __exit pf_exit(void)
{ {
int unit; int unit;
unregister_blkdev(MAJOR_NR,name); unregister_blkdev(MAJOR_NR, name);
for (unit=0;unit<PF_UNITS;unit++) for (unit = 0; unit < PF_UNITS; unit++)
if (PF.present) if (PF.present)
pi_release(PI); pi_release(PI);
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_init(pf_init) module_init(pf_init)
module_exit(pf_exit) module_exit(pf_exit)
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