xfs
[Top] [All Lists]

For those people with IDE problems with XFS

To: linux-xfs@xxxxxxxxxxx
Subject: For those people with IDE problems with XFS
From: Steve Lord <lord@xxxxxxx>
Date: Mon, 12 Feb 2001 16:25:02 -0600
Sender: owner-linux-xfs@xxxxxxxxxxx
If you are using the development tree and ide is blowing chunks for you,
can you try the following patch, it removes some of the code added for
the kio patch, and backports some changes from 2.4.2-pre3 which fix ide
problems. No guarantees on this one but for me it appears to be working
here.

I think you can expect to see 2.4.2-pre3 in a day or so, it may be a real
2.4.2 by then.

Steve


===========================================================================
Index: linux/drivers/ide/ide-disk.c
===========================================================================

--- /usr/tmp/TmpDir.6536-0/linux/drivers/ide/ide-disk.c_1.10    Mon Feb 12 
16:21:42 2001
+++ linux/drivers/ide/ide-disk.c        Mon Feb 12 15:25:18 2001
@@ -140,7 +140,7 @@
        byte stat;
        int i;
        unsigned int msect, nsect;
-       struct request *rq = HWGROUP(drive)->rq;
+       struct request *rq;
 
        /* new way for dealing with premature shared PCI interrupts */
        if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
@@ -154,6 +154,7 @@
        msect = drive->mult_count;
        
 read_next:
+       rq = HWGROUP(drive)->rq;
        if (msect) {
                if ((nsect = rq->current_nr_sectors) > msect)
                        nsect = msect;
@@ -200,7 +201,7 @@
                        rq->nr_sectors-1);
 #endif
                if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) {
-                       //rq->sector++;
+                       rq->sector++;
                        rq->buffer += 512;
                        rq->errors = 0;
                        i = --rq->nr_sectors;
@@ -224,40 +225,53 @@
  * ide_multwrite() transfers a block of up to mcount sectors of data
  * to a drive as part of a disk multiple-sector write operation.
  *
- * Returns 0 if successful;  returns 1 if request had to be aborted due to 
corrupted buffer list.
+ * Returns 0 on success.
+ *
+ * Note that we may be called from two contexts - the do_rw_disk context
+ * and IRQ context. The IRQ can happen any time after we've output the
+ * full "mcount" number of sectors, so we must make sure we update the
+ * state _before_ we output the final part of the data!
  */
 int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
 {
        ide_hwgroup_t   *hwgroup= HWGROUP(drive);
-       struct request  *rq = hwgroup->rq;
-
+       struct request  *rq = &hwgroup->wrq;
+ 
        do {
-               unsigned int nsect = rq->current_nr_sectors;
+               char *buffer;
+               int nsect = rq->current_nr_sectors;
+ 
                if (nsect > mcount)
                        nsect = mcount;
                mcount -= nsect;
+               buffer = rq->buffer;
 
-               idedisk_output_data(drive, rq->buffer, nsect<<7);
-#ifdef DEBUG
-               printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, 
remaining=%ld\n",
-                       drive->name, rq->sector, (unsigned long) rq->buffer,
-                       nsect, rq->nr_sectors - nsect);
-#endif
-#ifdef CONFIG_BLK_DEV_PDC4030
                rq->sector += nsect;
-#endif
-               if (((long)(rq->nr_sectors -= nsect)) <= 0) {
-#ifdef DEBUG
-                       printk("%s: multwrite: count=%d, current=%ld\n",
-                               drive->name, nsect, rq->nr_sectors);
-#endif
-                       break;
+               rq->buffer += nsect << 9;
+               rq->nr_sectors -= nsect;
+               rq->current_nr_sectors -= nsect;
+
+               /* Do we move to the next bh after this? */
+               if (!rq->current_nr_sectors) {
+                       struct buffer_head *bh = rq->bh->b_reqnext;
+
+                       /* end early early we ran out of requests */
+                       if (!bh) {
+                               mcount = 0;
+                       } else {
+                               rq->bh = bh;
+                               rq->current_nr_sectors = bh->b_size >> 9;
+                               rq->buffer             = bh->b_data;
+                       }
                }
-               if ((rq->current_nr_sectors -= nsect) == 0)
-                       ide_end_request(1, hwgroup);
-               else
-                       rq->buffer += nsect << 9;
+
+               /*
+                * Ok, we're all setup for the interrupt
+                * re-entering us on the last transfer.
+                */
+               idedisk_output_data(drive, buffer, nsect<<7);
        } while (mcount);
+
         return 0;
 }
 
@@ -267,8 +281,9 @@
 static ide_startstop_t multwrite_intr (ide_drive_t *drive)
 {
        byte stat;
+       int i;
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
-       struct request *rq = hwgroup->rq;
+       struct request *rq = &hwgroup->wrq;
 
        if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
                if (stat & DRQ_STAT) {
@@ -283,10 +298,20 @@
                                return ide_started;
                        }
                } else {
-                       if (!rq->nr_sectors)
-                               ide_end_request(1, hwgroup);
+                       /*
+                        *      If the copy has all the blocks completed then
+                        *      we can end the original request.
+                        */
+                       if (!rq->nr_sectors) {  /* all done? */
+                               rq = hwgroup->rq;
+                               for (i = rq->nr_sectors; i > 0;){
+                                       i -= rq->current_nr_sectors;
+                                       ide_end_request(1, hwgroup);
+                               }
+                               return ide_stopped;
+                       }
                }
-               return ide_stopped;
+               return ide_stopped;     /* the original code did this here (?) 
*/
        }
        return ide_error(drive, "multwrite_intr", stat);
 }
@@ -423,6 +448,7 @@
                         *
                         * Except when you get an error it seems...
                         */
+                       hwgroup->wrq = *rq; /* scratchpad */
                        ide_set_handler (drive, &multwrite_intr, WAIT_CMD, 
NULL);
                        if (ide_multwrite(drive, drive->mult_count)) {
                                unsigned long flags;

===========================================================================
Index: linux/drivers/ide/ide.c
===========================================================================

--- /usr/tmp/TmpDir.6536-0/linux/drivers/ide/ide.c_1.16 Mon Feb 12 16:21:42 2001
+++ linux/drivers/ide/ide.c     Mon Feb 12 15:25:28 2001
@@ -512,6 +512,8 @@
        if ((nr_sectors = rq->hard_nr_sectors) > 256)
                nr_sectors = 256;
 
+       blk_finished_io(sectors);
+
        nr_pages = rq->kiobuf->nr_pages;
        total_bytes = nr_sectors << 9;
        curr_offset = rq->kiobuf->offset;

===========================================================================
Index: linux/drivers/ide/pdc4030.c
===========================================================================

--- /usr/tmp/TmpDir.6536-0/linux/drivers/ide/pdc4030.c_1.3      Mon Feb 12 
16:21:42 2001
+++ linux/drivers/ide/pdc4030.c Mon Feb 12 15:25:38 2001
@@ -453,7 +453,7 @@
 static ide_startstop_t promise_write (ide_drive_t *drive)
 {
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
-       struct request *rq = hwgroup->rq;
+       struct request *rq = &hwgroup->wrq;
 
 #ifdef DEBUG_WRITE
        printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), "
@@ -541,6 +541,7 @@
                }
                if (!drive->unmask)
                        __cli();        /* local CPU only */
+               HWGROUP(drive)->wrq = *rq; /* scratchpad */
                return promise_write(drive);
 
        } else {

===========================================================================
Index: linux/include/linux/ide.h
===========================================================================

--- /usr/tmp/TmpDir.6536-0/linux/include/linux/ide.h_1.26       Mon Feb 12 
16:21:42 2001
+++ linux/include/linux/ide.h   Mon Feb 12 15:23:31 2001
@@ -497,6 +497,7 @@
        ide_hwif_t              *hwif;  /* ptr to current hwif in linked-list */
        struct request          *rq;    /* current request */
        struct timer_list       timer;  /* failsafe timer */
+       struct request          wrq;    /* local copy of current write rq */
        unsigned long           poll_timeout;   /* timeout value during long 
polls */
        ide_expiry_t            *expiry;        /* queried upon timeouts */
 } ide_hwgroup_t;




<Prev in Thread] Current Thread [Next in Thread>