xd.c patch (2.0) (fwd)

=?ISO-8859-2?Q?Tomasz_K=B3oczko?= (kloczek@rudy.mif.pg.gda.pl)
Mon, 11 Aug 1997 13:02:50 +0200 (MET DST)


This is forwarded message from my friend who is non subscribed to this
list (I forward him linux-kernel via procmail).

---------- Forwarded message ----------
Date: Mon, 11 Aug 1997 11:15:21 +0200 (MET DST)
From: "Andrzej M. Krzysztofowicz" <ankry@disneyland.mif.pg.gda.pl>
To: Tomasz Kloczko <kloczek@disneyland.mif.pg.gda.pl>
Subject: xd.c patch (2.0)

Hi
I don't know if anybody (except me) uses old XT drives with Linux,
but ...
I've just prepared a patch to the xd.c driver to the 2.0 series kernels.
I've just fixed, I hope, some problems. I:

- added short delay in xd_initdrives(). It helps in 2nd disk initialization
with Seagate ST11M controller. Without this the 2nd disk geometry was
difficult to obtain.
- removed overriding of io-base parameter if it's set as LILO/command line
parameter (xd=...) (I assume that if one set the controler manually he
knows what he is doing)

- corrected some problems with modularization:

* reading the partition table in init_module(), (without this the module
was rather unusable)
* increasing/decreasing the usage count of the module in xd_open() and
xd_release() to enable using the module with kerneld
* enabling possibility to put the xd=... command line parameter to
the module (via e.g. "insmod xd xd=...").

I've tested the patch with some 386 and 486 MB, ST-225 drives, ST11M and
WDXT-GEN2 controllers under 2.0.27 and 2.0.30p3 it works and is very useful
for me.
Please send me any comments if you find this patch useful. I still
have some problems with WD controllers. I also attend to prepare a patch
to 2.1 series kernels.

Greetings for everybody
Andrzej

PS. the patch is available also as
ftp://rudy.mif.pg.gda.pl/pub/People/ankry/patch-xd-2.0.gz

***********************************************************************
** XT patch starts **************************************************
diff -u v2.0.30p3/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.0.30p3/drivers/block/xd.c Sun Sep 8 18:50:20 1996
+++ linux/drivers/block/xd.c Mon Aug 11 00:53:30 1997
@@ -20,6 +20,8 @@
*
* Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
*
+ * Revised: 10-aug-97 by Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl
+ * Fixed(?) problems with 2nd disk initialization. Continued modularization.
*/

#include <linux/module.h>
@@ -39,6 +41,10 @@
#define MAJOR_NR XT_DISK_MAJOR
#include <linux/blk.h>

+#define XD_INIT_DISK_DELAY 3 /* 30 ms delay during disk initialization */
+ /* It may need to be increased if a problem with the 2nd drive detection appears
+ (especially for ST11M controller) */
+
XD_INFO xd_info[XD_MAXDRIVES];

/* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
@@ -84,7 +90,7 @@
(u_char *) 0xE0000
};

-static struct hd_struct xd[XD_MAXDRIVES << 6];
+static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES] = { 0, 0 };
static int xd_blocksizes[XD_MAXDRIVES << 6];
static struct gendisk xd_gendisk = {
@@ -98,7 +104,7 @@
#else
xd_geninit, /* init function */
#endif
- xd, /* hd struct */
+ xd_struct, /* hd struct */
xd_sizes, /* block sizes */
0, /* number */
(void *) xd_info, /* internal */
@@ -187,7 +193,7 @@
}

for (i = 0; i < xd_drives; i++) {
- xd[i << 6].nr_sects = xd_info[i].heads * xd_info[i].cylinders * xd_info[i].sectors;
+ xd_struct[i << 6].nr_sects = xd_info[i].heads * xd_info[i].cylinders * xd_info[i].sectors;
xd_valid[i] = 1;
}

@@ -206,6 +212,10 @@
while (!xd_valid[dev])
sleep_on(&xd_wait_open);

+#ifdef MODULE
+ MOD_INC_USE_COUNT;
+#endif /* MODULE */
+
xd_access[dev]++;

return (0);
@@ -226,8 +236,8 @@

if (CURRENT_DEV < xd_drives
&& CURRENT->sector + CURRENT->nr_sectors
- <= xd[MINOR(CURRENT->rq_dev)].nr_sects) {
- block = CURRENT->sector + xd[MINOR(CURRENT->rq_dev)].start_sect;
+ <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
+ block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
count = CURRENT->nr_sectors;

switch (CURRENT->cmd) {
@@ -259,7 +269,7 @@
put_user(xd_info[dev].heads, &geometry->heads);
put_user(xd_info[dev].sectors, &geometry->sectors);
put_user(xd_info[dev].cylinders, &geometry->cylinders);
- put_user(xd[MINOR(inode->i_rdev)].start_sect,&geometry->start);
+ put_user(xd_struct[MINOR(inode->i_rdev)].start_sect,&geometry->start);

return (0);
}
@@ -277,7 +287,7 @@
if (arg) {
if ((err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long))))
return (err);
- put_user(xd[MINOR(inode->i_rdev)].nr_sects,(long *) arg);
+ put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(long *) arg);

return (0);
}
@@ -305,6 +315,11 @@
if (dev < xd_drives) {
sync_dev(inode->i_rdev);
xd_access[dev]--;
+
+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif /* MODULE */
+
}
}

@@ -527,12 +542,19 @@
static u_char xd_initdrives (void (*init_drive)(u_char drive))
{
u_char cmdblk[6],i,count = 0;
+ u_long end_delay;

for (i = 0; i < XD_MAXDRIVES; i++) {
xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
+ end_delay = jiffies + XD_INIT_DISK_DELAY;
+ while (jiffies < end_delay)
+ ;
init_drive(count);
count++;
+ end_delay = jiffies + XD_INIT_DISK_DELAY;
+ while (jiffies < end_delay)
+ ;
}
}
return (count);
@@ -543,6 +565,7 @@
switch ((u_long) address) {
case 0xC8000: xd_iobase = 0x320; break;
case 0xCA000: xd_iobase = 0x324; break;
+ case 0x00000: break; /* don't change manually set iobase */
default: printk("xd_dtc_init_controller: unsupported BIOS address %p\n",address);
xd_iobase = 0x320; break;
}
@@ -587,6 +610,7 @@
case 0xCE000: xd_iobase = 0x32C; break;
case 0xD0000: xd_iobase = 0x328; break;
case 0xD8000: xd_iobase = 0x32C; break;
+ case 0x00000: break; /* don't change manually set iobase */
default: printk("xd_wd_init_controller: unsupported BIOS address %p\n",address);
xd_iobase = 0x320; break;
}
@@ -626,6 +650,7 @@
case 0xD0000: xd_iobase = 0x324; break;
case 0xD8000: xd_iobase = 0x328; break;
case 0xE0000: xd_iobase = 0x32C; break;
+ case 0x00000: break; /* don't change manually set iobase */
default: printk("xd_seagate_init_controller: unsupported BIOS address %p\n",address);
xd_iobase = 0x320; break;
}
@@ -659,6 +684,7 @@
case 0xD0000: xd_iobase = 0x324; break;
case 0xD8000: xd_iobase = 0x328; break;
case 0xE0000: xd_iobase = 0x32C; break;
+ case 0x00000: break; /* don't change manually set iobase */
default: printk("xd_omti_init_controller: unsupported BIOS address %p\n",address);
xd_iobase = 0x320; break;
}
@@ -706,6 +732,11 @@
/* xd_setup: initialise from command line parameters */
void xd_setup (char *command,int *integers)
{
+ if (integers[0] != 4) {
+ printk("xd_setup: wrong number of parameters for xd\n");
+ return;
+ }
+
xd_override = 1;

xd_type = integers[1];
@@ -737,13 +768,23 @@


#ifdef MODULE
+int xd[5] = { 0,0,0,0,0 };
+
int init_module(void)
{
+ int i, count=0;
int error = xd_init();
if (!error)
{
printk(KERN_INFO "XD: Loaded as a module.\n");
+ for (i = 4; i > 0; i--)
+ if ((xd[i]=xd[i-1]) && !count)
+ count=i;
+ if ((xd[0]=count))
+ xd_setup(NULL, xd);
xd_geninit(&(struct gendisk) { 0,0,0,0,0,0,0,0,0,0,0 });
+ for (i = 0; i < xd_drives; i++)
+ resetup_one_dev(&xd_gendisk, i);
}

return error;
** XT patch ends **************************************************
***********************************************************************

-- 
=======================================================================
  Andrzej M. Krzysztofowicz               ankry@mif.pg.gda.pl
  tel.  (0-58) 47 14 61
Wydz.Fizyki Technicznej i Matematyki Stosowanej Politechniki Gdanskiej