Alan Cox writes:
 > > in the SELECTION PHASE:at the last before statement in  NCR5380_main()
 > > after a "won arbitration" in the (second) return of 
 > > NCR5380_select(), the spin_lock_irq(&io_request_lock) hangs 
 > > (it looks like a dead lock), and so does the system (too bad). 
 > 
 > The NCR5380 driver is not SMP safe. 

strangely enough I thought SMP is harmless anyway.

 > The core processing loop needs rewriting
 > to fix this. Unfortunately the code is so bad nobody has had time to figure
 > what it is meant to be doing, let alone fix it.

OK, lets say... Is it worth it? Are they many duds (I am not one) out
there trying to use this puny card for heavy transfer (interrupts do
not work) by polling the driver's addresses? etc...
Any better quality framework for a SCSI (II) driver?
Any documents on SMP? I have got some changes on this file, are they
any ways they can be tested for other targets than a scanner which
skew and darken pictures? Where can I give those to experts?

I noticed during my Fail-And-Try-And-re-Try campaign using __SMP__ on a
mono-CPU,  that the lock "io_request_lock" get set by another task
(must be the hard-drive) during the selection phase. I did not spend
time to check which one. 
Also, one should surely un-lock before using timers, as the macro
time_before() expects marvels from them.

The changes below works in my environment without hanging the system
forever,  but then, at the PIO transfer, this greedy driver grabs it all,
it seems to stop most of the activities. Lets find the way which
allows a smoother multi-tasking...


Predictively, I put some patches here; we never know, somebody might
be interested or inspired or disgusted. 
One could notice the lock is spinning a lot at 5Terra RPM... in the void for now!


Cheers,

Christian.



Index: NCR5380.c
===================================================================
RCS file: /usr/arch/linux/drivers/scsi/NCR5380.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1.2.11
diff -c -r1.1 -r1.1.1.1.2.11
*** NCR5380.c   2000/05/21 13:10:33     1.1
--- NCR5380.c   2000/06/02 21:48:57     1.1.1.1.2.11
***************
*** 31,39 ****
  
  /*
   * $Log: NCR5380.c,v $
!  * Revision 1.1  2000/05/21 13:10:33  christian
!  * Initial revision
   *
  
   * Revision 1.10 1998/9/2     Alan Cox
   *                            ([EMAIL PROTECTED])
--- 31,74 ----
  
  /*
   * $Log: NCR5380.c,v $
!  * Revision 1.1.1.1.2.11  2000/06/02 21:48:57  christian
!  * added save flags in front of a break in main(). It restore balance.
!  *
!  * Revision 1.1.1.1.2.10  2000/06/02 21:17:52  christian
!  * got selection.
!  * need to unlock io-requests before using time_before macro-function.
!  *
!  * Revision 1.1.1.1.2.9  2000/06/02 20:23:53  christian
!  * Again, removed a lock before break in main loop.
!  *
!  * Revision 1.1.1.1.2.8  2000/05/31 23:12:29  christian
!  * macrofied cli/sti  a bit too much.
!  *
!  * Revision 1.1.1.1.2.7  2000/05/25 23:03:19  christian
!  * unified a bit more the locks/unlocks. Working set, without much irq-locks.
!  *
!  * Revision 1.1.1.1.2.6  2000/05/25 20:56:08  christian
!  * removed spin locks before breaks in main().
!  *
!  * Revision 1.1.1.1.2.5  2000/05/24 04:41:42  christian
!  * use cli in main().
   *
+  * Revision 1.1.1.1.2.4  2000/05/24 03:45:17  christian
+  * added debug prints for lock spinning.
+  *
+  * Revision 1.1.1.1.2.3  2000/05/22 04:50:00  christian
+  * changed typo for spin_unlock_irqrestore().
+  *
+  * Revision 1.1.1.1.2.2  2000/05/22 03:57:04  christian
+  * removed spin locs in the timer_fn function() it is suspicious!
+  * use of spin/unspin locks in the main function: freeze the for loops and when 
+writting in the instances stack
+  * or the issue queues.
+  * removed interrupts in the run_main function and added the semaphore reset in the 
+inline command.
+  *
+  * Revision 1.1.1.1.2.1  2000/05/21 17:01:59  christian
+  *
+  * disable lock ans CLI in main function
+  *
  
   * Revision 1.10 1998/9/2     Alan Cox
   *                            ([EMAIL PROTECTED])
***************
*** 96,103 ****
   */
  
  #if (NDEBUG & NDEBUG_LISTS)
! #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), 
(void*)(y)); if ((x)==(y)) udelay(5); }
! #define REMOVE(w,x,y,z) {printk("LINE:%d   Removing: %p->%p  %p->%p \n", __LINE__, 
(void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
  #else
  #define LIST(x,y)
  #define REMOVE(w,x,y,z)
--- 131,138 ----
   */
  
  #if (NDEBUG & NDEBUG_LISTS)
! #define LIST(x,y) {printk("NCR5380[%d]: Adding %p to %p\n", __LINE__, (void*)(x), 
(void*)(y)); if ((x)==(y)) udelay(5); }
! #define REMOVE(w,x,y,z) {printk("NCR5380[%d]: Removing: %p->%p  %p->%p \n", 
__LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
  #else
  #define LIST(x,y)
  #define REMOVE(w,x,y,z)
***************
*** 113,118 ****
--- 148,186 ----
  #define READ_OVERRUNS
  #endif
  
+ #if (NDEBUG)
+ #define NCR5380_printk printk
+ #else
+ #define NCR5380_printk()
+ #endif
+ 
+ #define NCR5380_spin_lock_irq(_lock_) do {\
+               NCR5380_printk("NCR5380[%d]: to lock=%d\n", __LINE__, (_lock_)->lock);\
+               spin_lock_irq(_lock_);\
+               } while(0)
+ 
+ #define NCR5380_spin_lock_irqsave(_lock_,_f_) do {\
+               NCR5380_printk("NCR5380[%d]: to lock=%d and save\n", __LINE__, 
+(_lock_)->lock);\
+               save_flags(_f_);cli();\
+               } while(0)
+ 
+ #define NCR5380_spin_unlock_irq(_lock_) do {\
+               NCR5380_printk("NCR5380[%d]: un lock=%d\n", __LINE__, (_lock_)->lock);\
+               spin_unlock_irq(_lock_);\
+               } while(0)
+ 
+ #define NCR5380_spin_unlock_irqrestore(_lock_,_f_) do {\
+               NCR5380_printk("NCR5380[%d]: un lock=%d and restore\n", __LINE__, 
+(_lock_)->lock);\
+               restore_flags(_f_);\
+               } while(0)
+ 
+ //            spin_lock_irqsave(_lock_,_f_);
+ //            spin_unlock_irqrestore(_lock_,_f_);
+ //             if(!spin_trylock(&io_request_lock)) { 
+ //            } else {
+ //               __save_flags(flags); __cli();
+ //            }
+ 
  /*
   * Design
   * Issues :
***************
*** 455,468 ****
        unsigned long flags;
        unsigned char status, data, basr, mr, icr, i;
        NCR5380_setup(instance);
!       save_flags(flags);
!       cli();
        data = NCR5380_read(CURRENT_SCSI_DATA_REG);
        status = NCR5380_read(STATUS_REG);
        mr = NCR5380_read(MODE_REG);
        icr = NCR5380_read(INITIATOR_COMMAND_REG);
        basr = NCR5380_read(BUS_AND_STATUS_REG);
!       restore_flags(flags);
        printk("STATUS_REG: %02x ", status);
        for (i = 0; signals[i].mask; ++i)
                if (status & signals[i].mask)
--- 523,539 ----
        unsigned long flags;
        unsigned char status, data, basr, mr, icr, i;
        NCR5380_setup(instance);
! 
!     NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
        data = NCR5380_read(CURRENT_SCSI_DATA_REG);
        status = NCR5380_read(STATUS_REG);
        mr = NCR5380_read(MODE_REG);
        icr = NCR5380_read(INITIATOR_COMMAND_REG);
        basr = NCR5380_read(BUS_AND_STATUS_REG);
! 
!     NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
        printk("STATUS_REG: %02x ", status);
        for (i = 0; signals[i].mask; ++i)
                if (status & signals[i].mask)
***************
*** 566,579 ****
  
  static __inline__ void run_main(void)
  {
-       unsigned long flags;
-       save_flags(flags);
-       cli();
        if (!main_running) {
                main_running = 1;
                NCR5380_main();
        }
-       restore_flags(flags);
  }
  
  #ifdef USLEEP
--- 637,647 ----
  
  static __inline__ void run_main(void)
  {
        if (!main_running) {
                main_running = 1;
                NCR5380_main();
+               main_running = 0;
        }
  }
  
  #ifdef USLEEP
***************
*** 654,664 ****
        unsigned long flags;
        struct Scsi_Host *tmp, **prev;
  
!       save_flags(flags);
!       cli();
        if (((struct NCR5380_hostdata *) (instance->hostdata))->next_timer) {
!               restore_flags(flags);
!               return -1;
        }
        for (prev = &expires_first, tmp = expires_first; tmp;
                prev = &(((struct NCR5380_hostdata *) tmp->hostdata)->next_timer), 
--- 722,732 ----
        unsigned long flags;
        struct Scsi_Host *tmp, **prev;
  
!       NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
        if (((struct NCR5380_hostdata *) (instance->hostdata))->next_timer) {
!         NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
!         return -1;
        }
        for (prev = &expires_first, tmp = expires_first; tmp;
                prev = &(((struct NCR5380_hostdata *) tmp->hostdata)->next_timer), 
***************
*** 673,679 ****
        del_timer(&usleep_timer);
        usleep_timer.expires = ((struct NCR5380_hostdata *) 
expires_first->hostdata)->time_expires;
        add_timer(&usleep_timer);
!       restore_flags(flags);
        return 0;
  }
  
--- 741,749 ----
        del_timer(&usleep_timer);
        usleep_timer.expires = ((struct NCR5380_hostdata *) 
expires_first->hostdata)->time_expires;
        add_timer(&usleep_timer);
! 
!       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
        return 0;
  }
  
***************
*** 682,689 ****
  {
        unsigned long flags;
        struct Scsi_Host *instance;
!       save_flags(flags);
!       cli();
        for (; expires_first &&
                time_before_eq(((struct NCR5380_hostdata 
*)expires_first->hostdata)->time_expires, jiffies); )
        {
--- 752,760 ----
  {
        unsigned long flags;
        struct Scsi_Host *instance;
! 
!       NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
        for (; expires_first &&
                time_before_eq(((struct NCR5380_hostdata 
*)expires_first->hostdata)->time_expires, jiffies); )
        {
***************
*** 699,709 ****
                usleep_timer.expires = ((struct NCR5380_hostdata 
*)expires_first->hostdata)->time_expires;
                add_timer(&usleep_timer);
        }
!       restore_flags(flags);
  
-       spin_lock_irqsave(&io_request_lock, flags);
        run_main();
-       spin_unlock_irqrestore(&io_request_lock, flags);
  }
  #endif                                /* def USLEEP */
  
--- 770,779 ----
                usleep_timer.expires = ((struct NCR5380_hostdata 
*)expires_first->hostdata)->time_expires;
                add_timer(&usleep_timer);
        }
! 
!       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
  
        run_main();
  }
  #endif                                /* def USLEEP */
  
***************
*** 951,958 ****
        SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n",
                pas_wmaxi, pas_maxi);
  #endif
!       save_flags(flags);
!       cli();
        SPRINTF("NCR5380 : coroutine is%s running.\n", main_running ? "" : "n't");
        if (!hostdata->connected)
                SPRINTF("scsi%d: no currently connected command\n", instance->host_no);
--- 1021,1029 ----
        SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n",
                pas_wmaxi, pas_maxi);
  #endif
! 
!     NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
        SPRINTF("NCR5380 : coroutine is%s running.\n", main_running ? "" : "n't");
        if (!hostdata->connected)
                SPRINTF("scsi%d: no currently connected command\n", instance->host_no);
***************
*** 969,975 ****
             ptr = (Scsi_Cmnd *) ptr->host_scribble)
                pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
  
!       restore_flags(flags);
        *start = buffer;
        if (pos - buffer < offset)
                return 0;
--- 1040,1047 ----
             ptr = (Scsi_Cmnd *) ptr->host_scribble)
                pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
  
!       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
        *start = buffer;
        if (pos - buffer < offset)
                return 0;
***************
*** 1170,1176 ****
--- 1242,1250 ----
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
         instance->hostdata;
        Scsi_Cmnd *tmp;
+       unsigned long flags;
  
+ 
  #if (NDEBUG & NDEBUG_NO_WRITE)
        switch (cmd->cmnd[0]) {
                case WRITE_6:
***************
*** 1228,1235 ****
         * clear the contingent allegiance condition that exists and the 
         * sense data is only guaranteed to be valid while the condition exists.
         */
  
-       cli();
        if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
                LIST(cmd, hostdata->issue_queue);
                cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
--- 1302,1310 ----
         * clear the contingent allegiance condition that exists and the 
         * sense data is only guaranteed to be valid while the condition exists.
         */
+ 
+       NCR5380_spin_lock_irqsave(&io_request_lock, flags);
  
        if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
                LIST(cmd, hostdata->issue_queue);
                cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
***************
*** 1240,1251 ****
                LIST(cmd, tmp);
                tmp->host_scribble = (unsigned char *) cmd;
        }
  #if (NDEBUG & NDEBUG_QUEUES)
        printk("scsi%d : command added to %s of queue\n", instance->host_no,
               (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
  #endif
! 
! /* Run the coroutine if it isn't already running. */
        run_main();
        return 0;
  }
--- 1315,1329 ----
                LIST(cmd, tmp);
                tmp->host_scribble = (unsigned char *) cmd;
        }
+ 
+     NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
+ 
  #if (NDEBUG & NDEBUG_QUEUES)
        printk("scsi%d : command added to %s of queue\n", instance->host_no,
               (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
  #endif
!       
!       /* Run the coroutine if it isn't already running. */
        run_main();
        return 0;
  }
***************
*** 1281,1297 ****
         * this should prevent any race conditions.
         */
  
-       spin_unlock_irq(&io_request_lock);
-       
-       save_flags(flags);
-       
        do {
-               cli();          /* Freeze request queues */
                done = 1;
                for (instance = first_instance; instance &&
                     instance->hostt == the_template; instance = instance->next) {
                         hostdata = (struct NCR5380_hostdata *) instance->hostdata;
!                        cli();
  #ifdef USLEEP
                        if (!hostdata->connected && !hostdata->selecting) {
  #else
--- 1359,1376 ----
         * this should prevent any race conditions.
         */
  
        do {
                done = 1;
+ 
+               /* Freeze request queues */
+               NCR5380_spin_lock_irqsave(&io_request_lock, flags);
+ 
                for (instance = first_instance; instance &&
                     instance->hostt == the_template; instance = instance->next) {
                         hostdata = (struct NCR5380_hostdata *) instance->hostdata;
! 
!                        NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
  #ifdef USLEEP
                        if (!hostdata->connected && !hostdata->selecting) {
  #else
***************
*** 1300,1305 ****
--- 1379,1387 ----
  #if (NDEBUG & NDEBUG_MAIN)
                                printk("scsi%d : not connected\n", instance->host_no);
  #endif
+ 
+                               NCR5380_spin_lock_irqsave(&io_request_lock, flags);
+ 
                                /*
                                 * Search through the issue_queue for a command 
destined
                                 * for a target that's not busy.
***************
*** 1314,1325 ****
                                     prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
                                     tmp->host_scribble) {
  
  #if (NDEBUG & NDEBUG_LISTS)
                                        if (prev != tmp)
!                                               printk("MAIN tmp=%p   target=%d   
busy=%d lun=%d\n", tmp, tmp->target, hostdata->busy[tmp->target], tmp->lun);
  #endif
                                        /*  When we find one, remove it from the issue 
queue. */
                                        if (!(hostdata->busy[tmp->target] & (1 << 
tmp->lun))) {
                                                if (prev) {
                                                        REMOVE(prev, 
prev->host_scribble, tmp, tmp->host_scribble);
                                                        prev->host_scribble = 
tmp->host_scribble;
--- 1396,1415 ----
                                     prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
                                     tmp->host_scribble) {
  
+                                       
+NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
+ 
+ 
  #if (NDEBUG & NDEBUG_LISTS)
                                        if (prev != tmp)
!                                               printk("MAIN tmp=%p   target=%d   
busy=%d lun=%d\n",
!                                                                tmp, tmp->target, 
hostdata->busy[tmp->target], tmp->lun);
  #endif
+ 
                                        /*  When we find one, remove it from the issue 
queue. */
                                        if (!(hostdata->busy[tmp->target] & (1 << 
tmp->lun))) {
+ 
+                                               
+NCR5380_spin_lock_irqsave(&io_request_lock, flags);
+ 
                                                if (prev) {
                                                        REMOVE(prev, 
prev->host_scribble, tmp, tmp->host_scribble);
                                                        prev->host_scribble = 
tmp->host_scribble;
***************
*** 1329,1337 ****
                                                }
                                                tmp->host_scribble = NULL;
  
-                                               /* reenable interrupts after finding 
one */
-                                               restore_flags(flags);
- 
                                                /* 
                                                 * Attempt to establish an I_T_L nexus 
here. 
                                                 * On success, 
instance->hostdata->connected is set.
--- 1419,1424 ----
***************
*** 1358,1363 ****
--- 1445,1454 ----
                                                        to indicate a new command is 
being performed */
  #endif
  
+                                               /* reenable interrupts after finding 
+one */
+                                               
+NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
+ 
+ 
                                                if (!NCR5380_select(instance, tmp,
                                                /* 
                                                 * REQUEST SENSE commands are issued 
without tagged
***************
*** 1365,1389 ****
                                                 * contingent allegiance condition 
exists for the 
                                                 * entire unit.
                                                 */
!                                                                   (tmp->cmnd[0] == 
REQUEST_SENSE) ? TAG_NONE :
                                                             TAG_NEXT)) {
                                                        break;
                                                } else {
!                                                       cli();
                                                        LIST(tmp, 
hostdata->issue_queue);
                                                        tmp->host_scribble = (unsigned 
char *)
                                                            hostdata->issue_queue;
                                                        hostdata->issue_queue = tmp;
                                                        done = 0;
!                                                       restore_flags(flags);
  #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
                                                        printk("scsi%d : main(): 
select() failed, returned to issue_queue\n",
                                                               instance->host_no);
  #endif
                                                }
                                        }       /* if target/lun is not busy */
                                }       /* for */
                        }       /* if (!hostdata->connected) */
  #ifdef USLEEP
                        if (hostdata->selecting) 
                        {
--- 1456,1489 ----
                                                 * contingent allegiance condition 
exists for the 
                                                 * entire unit.
                                                 */
!                                                   (tmp->cmnd[0] == REQUEST_SENSE) ? 
TAG_NONE :
                                                             TAG_NEXT)) {
+ 
+                                                       
+NCR5380_spin_lock_irqsave(&io_request_lock, flags);
                                                        break;
+ 
                                                } else {
!                                                       
NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
                                                        LIST(tmp, 
hostdata->issue_queue);
                                                        tmp->host_scribble = (unsigned 
char *)
                                                            hostdata->issue_queue;
                                                        hostdata->issue_queue = tmp;
                                                        done = 0;
!                                                               
!                                                       
NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
  #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
                                                        printk("scsi%d : main(): 
select() failed, returned to issue_queue\n",
                                                               instance->host_no);
  #endif
                                                }
                                        }       /* if target/lun is not busy */
+                     NCR5380_spin_lock_irqsave(&io_request_lock, flags);
                                }       /* for */
+                          NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
                        }       /* if (!hostdata->connected) */
+ 
  #ifdef USLEEP
                        if (hostdata->selecting) 
                        {
***************
*** 1401,1417 ****
                                        after a scan */
                                        printk(KERN_DEBUG "scsi%d: device %d did not 
respond in time\n",
                                                instance->host_no, tmp->target);
!                                       cli();
                                        LIST(tmp, hostdata->issue_queue);
                                        tmp->host_scribble = (unsigned char *) 
hostdata->issue_queue;
                                        hostdata->issue_queue = tmp;
-                                       restore_flags(flags);
  
                                        hostdata->time_expires = jiffies + 
USLEEP_WAITLONG;
                                        NCR5380_set_timer (instance);
                                }
                        } /* if hostdata->selecting */
  #endif
                        if (hostdata->connected
  #ifdef REAL_DMA
                            && !hostdata->dmalen
--- 1501,1522 ----
                                        after a scan */
                                        printk(KERN_DEBUG "scsi%d: device %d did not 
respond in time\n",
                                                instance->host_no, tmp->target);
! 
!                                       NCR5380_spin_lock_irqsave(&io_request_lock, 
flags);
! 
                                        LIST(tmp, hostdata->issue_queue);
                                        tmp->host_scribble = (unsigned char *) 
hostdata->issue_queue;
                                        hostdata->issue_queue = tmp;
  
+                                       
+NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
+ 
+ 
                                        hostdata->time_expires = jiffies + 
USLEEP_WAITLONG;
                                        NCR5380_set_timer (instance);
                                }
                        } /* if hostdata->selecting */
  #endif
+ 
                        if (hostdata->connected
  #ifdef REAL_DMA
                            && !hostdata->dmalen
***************
*** 1420,1448 ****
                            && (!hostdata->time_expires || 
time_before_eq(hostdata->time_expires, jiffies))
  #endif
                            ) {
-                               restore_flags(flags);
  #if (NDEBUG & NDEBUG_MAIN)
                                printk("scsi%d : main() : performing information 
transfer\n",
                                       instance->host_no);
  #endif
                                NCR5380_information_transfer(instance);
  #if (NDEBUG & NDEBUG_MAIN)
                                printk("scsi%d : main() : done set false\n", 
instance->host_no);
  #endif
                                done = 0;
!                       } else
                                break;
                }               /* for instance */
        } while (!done);
-       spin_lock_irq(&io_request_lock);
-   /*  cli();*/
-       main_running = 0;
  }
  
  #ifndef DONT_USE_INTR
- #include <linux/blk.h>
- #include <asm/spinlock.h>
- 
  /*
   * Function : void NCR5380_intr (int irq)
   * 
--- 1525,1552 ----
                            && (!hostdata->time_expires || 
time_before_eq(hostdata->time_expires, jiffies))
  #endif
                            ) {
  #if (NDEBUG & NDEBUG_MAIN)
                                printk("scsi%d : main() : performing information 
transfer\n",
                                       instance->host_no);
  #endif
+ 
                                NCR5380_information_transfer(instance);
+ 
  #if (NDEBUG & NDEBUG_MAIN)
                                printk("scsi%d : main() : done set false\n", 
instance->host_no);
  #endif
                                done = 0;
!             } else {                  
!                               NCR5380_spin_lock_irqsave(&io_request_lock, flags);
                                break;
+             }
+                       NCR5380_spin_lock_irqsave(&io_request_lock, flags);
                }               /* for instance */
+               NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
        } while (!done);
  }
  
  #ifndef DONT_USE_INTR
  /*
   * Function : void NCR5380_intr (int irq)
   * 
***************
*** 1461,1468 ****
        unsigned char basr;
        unsigned long flags;
  
!        save_flags(flags);
!        cli();
  #if (NDEBUG & NDEBUG_INTR)
         printk("scsi : NCR5380 irq %d triggered\n", irq);
  #endif
--- 1565,1572 ----
        unsigned char basr;
        unsigned long flags;
  
!     NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
  #if (NDEBUG & NDEBUG_INTR)
         printk("scsi : NCR5380 irq %d triggered\n", irq);
  #endif
***************
*** 1483,1489 ****
                                        if ((NCR5380_read(STATUS_REG) & (SR_SEL | 
SR_IO)) ==
                                            (SR_SEL | SR_IO)) {
                                                done = 0;
!                                               restore_flags(flags);
  #if (NDEBUG & NDEBUG_INTR)
                                                printk("scsi%d : SEL interrupt\n", 
instance->host_no);
  #endif
--- 1587,1595 ----
                                        if ((NCR5380_read(STATUS_REG) & (SR_SEL | 
SR_IO)) ==
                                            (SR_SEL | SR_IO)) {
                                                done = 0;
! 
!                                   NCR5380_spin_unlock_irqrestore(&io_request_lock, 
flags);
! 
  #if (NDEBUG & NDEBUG_INTR)
                                                printk("scsi%d : SEL interrupt\n", 
instance->host_no);
  #endif
***************
*** 1531,1540 ****
                                                        {
                                                                unsigned long timeout 
= jiffies + NCR_TIMEOUT;
  
!                                                               
spin_unlock_irq(&io_request_lock);
                                                                while 
(NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK
                                                                       && 
time_before(jiffies, timeout));
!                                                               
spin_lock_irq(&io_request_lock);
                                                                
                                                                if 
(time_after_eq(jiffies, timeout) )
                                                                        
printk("scsi%d: timeout at NCR5380.c:%d\n",
--- 1637,1646 ----
                                                        {
                                                                unsigned long timeout 
= jiffies + NCR_TIMEOUT;
  
!                                                               
NCR5380_spin_unlock_irq(&io_request_lock);
                                                                while 
(NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK
                                                                       && 
time_before(jiffies, timeout));
!                                                               
NCR5380_spin_lock_irq(&io_request_lock);
                                                                
                                                                if 
(time_after_eq(jiffies, timeout) )
                                                                        
printk("scsi%d: timeout at NCR5380.c:%d\n",
***************
*** 1563,1573 ****
  
  
  static void do_NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs) {
-       unsigned long flags;
- 
-        spin_lock_irqsave(&io_request_lock, flags);
         NCR5380_intr(irq, dev_id, regs);
-        spin_unlock_irqrestore(&io_request_lock, flags);
  }
  
  #endif
--- 1669,1675 ----
***************
*** 1654,1662 ****
         printk("scsi%d : starting arbitration, id = %d\n", instance->host_no,
                instance->this_id);
  #endif
-        save_flags(flags);
-        cli();
  
        /* 
         * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
         * data bus during SELECTION.
--- 1756,1763 ----
         printk("scsi%d : starting arbitration, id = %d\n", instance->host_no,
                instance->this_id);
  #endif
  
+       NCR5380_spin_lock_irqsave(&io_request_lock, flags);
        /* 
         * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
         * data bus during SELECTION.
***************
*** 1672,1691 ****
         NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
         NCR5380_write(MODE_REG, MR_ARBITRATE);
  
!        restore_flags(flags);
  
        /* Wait for arbitration logic to complete */
  #if NCR_TIMEOUT
        {
                unsigned long timeout = jiffies + 2 * NCR_TIMEOUT;
  
-               spin_unlock_irq(&io_request_lock);
- 
                while (!(NCR5380_read(INITIATOR_COMMAND_REG) & 
ICR_ARBITRATION_PROGRESS)
                       && time_before(jiffies,timeout));
  
-               spin_lock_irq(&io_request_lock);
-                      
                if (time_after_eq(jiffies,timeout)) {
                        printk("scsi: arbitration timeout at %d\n", __LINE__);
                        NCR5380_write(MODE_REG, MR_BASE);
--- 1773,1788 ----
         NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
         NCR5380_write(MODE_REG, MR_ARBITRATE);
  
!        NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
  
        /* Wait for arbitration logic to complete */
  #if NCR_TIMEOUT
        {
                unsigned long timeout = jiffies + 2 * NCR_TIMEOUT;
  
                while (!(NCR5380_read(INITIATOR_COMMAND_REG) & 
ICR_ARBITRATION_PROGRESS)
                       && time_before(jiffies,timeout));
  
                if (time_after_eq(jiffies,timeout)) {
                        printk("scsi: arbitration timeout at %d\n", __LINE__);
                        NCR5380_write(MODE_REG, MR_BASE);
***************
*** 1847,1854 ****
        spin_unlock_irq(&io_request_lock);
        while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) &
                                        (SR_BSY | SR_IO)));
-       spin_lock_irq(&io_request_lock);
  #endif
        if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
            (SR_SEL | SR_IO)) {
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
--- 1944,1951 ----
        spin_unlock_irq(&io_request_lock);
        while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) &
                                        (SR_BSY | SR_IO)));
  #endif
+ 
        if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
            (SR_SEL | SR_IO)) {
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
***************
*** 1915,1923 ****
        {
                unsigned long timeout = jiffies + NCR_TIMEOUT;
  
-               spin_unlock_irq(&io_request_lock);
                while (!(NCR5380_read(STATUS_REG) & SR_REQ) && time_before(jiffies, 
timeout));
-               spin_lock_irq(&io_request_lock);
                
                if (time_after_eq(jiffies, timeout)) {
                        printk("scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, 
__LINE__);
--- 2012,2018 ----
***************
*** 1973,1979 ****
  
        initialize_SCp(cmd);
  
- 
        return 0;
  }
  
--- 2068,2073 ----
***************
*** 2167,2193 ****
         NCR5380_local_declare();
         NCR5380_setup(host);
  
!        save_flags(flags);
!        cli();
         NCR5380_write(TARGET_COMMAND_REG,
                 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
         NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
         udelay(25);
         NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-        restore_flags(flags);
- }                             /*
  
                                 * Function : do_abort (Scsi_Host *host)
                                 * 
                                 * Purpose : abort the currently established nexus.  
Should only be 
                                 *      called from a routine which can drop into a 
                                 * 
                                 * Returns : 0 on success, -1 on failure.
!                                */ static int do_abort(struct Scsi_Host *host) {
        NCR5380_local_declare();
        unsigned char tmp, *msgptr, phase;
        int len;
!        NCR5380_setup(host);
  
  
        /* Request message out phase */
--- 2261,2290 ----
         NCR5380_local_declare();
         NCR5380_setup(host);
  
!        NCR5380_spin_lock_irqsave(&io_request_lock, flags);
! 
         NCR5380_write(TARGET_COMMAND_REG,
                 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
         NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
         udelay(25);
         NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
  
+        NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
+ }
+                               /*
+ 
                                 * Function : do_abort (Scsi_Host *host)
                                 * 
                                 * Purpose : abort the currently established nexus.  
Should only be 
                                 *      called from a routine which can drop into a 
                                 * 
                                 * Returns : 0 on success, -1 on failure.
!                                */ 
! static int do_abort(struct Scsi_Host *host) {
        NCR5380_local_declare();
        unsigned char tmp, *msgptr, phase;
        int len;
!       NCR5380_setup(host);
  
  
        /* Request message out phase */
***************
*** 2299,2306 ****
         */
  
  #if defined(PSEUDO_DMA) && !defined(UNSAFE)
! save_flags(flags);
! cli();
  #endif
        /* KLL May need eop and parity in 53c400 */
  if (hostdata->flags & FLAG_NCR53C400)
--- 2396,2402 ----
         */
  
  #if defined(PSEUDO_DMA) && !defined(UNSAFE)
!       NCR5380_spin_lock_irqsave(&io_request_lock, flags);
  #endif
        /* KLL May need eop and parity in 53c400 */
  if (hostdata->flags & FLAG_NCR53C400)
***************
*** 2579,2585 ****
        NCR5380_print_phase(instance);
  #endif
  #if defined(PSEUDO_DMA) && !defined(UNSAFE)
!       restore_flags(flags);
  #endif                                /* defined(REAL_DMA_POLL) */
        return foo;
  #endif                                /* def REAL_DMA */
--- 2675,2681 ----
        NCR5380_print_phase(instance);
  #endif
  #if defined(PSEUDO_DMA) && !defined(UNSAFE)
!       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
  #endif                                /* defined(REAL_DMA_POLL) */
        return foo;
  #endif                                /* def REAL_DMA */
***************
*** 2845,2857 ****
                                                cmd->SCp.ptr = (char *) 
cmd->sense_buffer;
                                                cmd->SCp.this_residual = 
sizeof(cmd->sense_buffer);
  
!                                               save_flags(flags);
!                                               cli();
                                                LIST(cmd, hostdata->issue_queue);
                                                cmd->host_scribble = (unsigned char *)
                                                    hostdata->issue_queue;
                                                hostdata->issue_queue = (Scsi_Cmnd *) 
cmd;
!                                               restore_flags(flags);
  #if (NDEBUG & NDEBUG_QUEUES)
                                                printk("scsi%d : REQUEST SENSE added 
to head of issue queue\n", instance->host_no);
  #endif
--- 2941,2956 ----
                                                cmd->SCp.ptr = (char *) 
cmd->sense_buffer;
                                                cmd->SCp.this_residual = 
sizeof(cmd->sense_buffer);
  
! 
!                           NCR5380_spin_lock_irqsave(&io_request_lock, flags); 
! 
                                                LIST(cmd, hostdata->issue_queue);
                                                cmd->host_scribble = (unsigned char *)
                                                    hostdata->issue_queue;
                                                hostdata->issue_queue = (Scsi_Cmnd *) 
cmd;
! 
!                         NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
  #if (NDEBUG & NDEBUG_QUEUES)
                                                printk("scsi%d : REQUEST SENSE added 
to head of issue queue\n", instance->host_no);
  #endif
***************
*** 3322,3329 ****
  
        NCR5380_print_status(instance);
  
!       save_flags(flags);
!       cli();
        NCR5380_setup(instance);
  
  #if (NDEBUG & NDEBUG_ABORT)
--- 3421,3428 ----
  
        NCR5380_print_status(instance);
  
!       NCR5380_spin_lock_irqsave(&io_request_lock, flags);     
! 
        NCR5380_setup(instance);
  
  #if (NDEBUG & NDEBUG_ABORT)
***************
*** 3382,3388 ****
                        (*prev) = (Scsi_Cmnd *) tmp->host_scribble;
                        tmp->host_scribble = NULL;
                        tmp->result = DID_ABORT << 16;
!                       restore_flags(flags);
  #if (NDEBUG & NDEBUG_ABORT)
                        printk("scsi%d : abort removed command from issue queue.\n",
                               instance->host_no);
--- 3481,3489 ----
                        (*prev) = (Scsi_Cmnd *) tmp->host_scribble;
                        tmp->host_scribble = NULL;
                        tmp->result = DID_ABORT << 16;
! 
!                       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
  #if (NDEBUG & NDEBUG_ABORT)
                        printk("scsi%d : abort removed command from issue queue.\n",
                               instance->host_no);
***************
*** 3408,3414 ****
   */
  
        if (hostdata->connected) {
!               restore_flags(flags);
  #if (NDEBUG & NDEBUG_ABORT)
                printk("scsi%d : abort failed, command connected.\n", 
instance->host_no);
  #endif
--- 3509,3518 ----
   */
  
        if (hostdata->connected) {
! 
!               NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
! 
  #if (NDEBUG & NDEBUG_ABORT)
                printk("scsi%d : abort failed, command connected.\n", 
instance->host_no);
  #endif
***************
*** 3442,3448 ****
        for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
             tmp = (Scsi_Cmnd *) tmp->host_scribble)
                if (cmd == tmp) {
!                       restore_flags(flags);
  #if (NDEBUG & NDEBUG_ABORT)
                        printk("scsi%d : aborting disconnected command.\n", 
instance->host_no);
  #endif
--- 3546,3555 ----
        for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
             tmp = (Scsi_Cmnd *) tmp->host_scribble)
                if (cmd == tmp) {
! 
!                       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
! 
  #if (NDEBUG & NDEBUG_ABORT)
                        printk("scsi%d : aborting disconnected command.\n", 
instance->host_no);
  #endif
***************
*** 3456,3475 ****
  
                        do_abort(instance);
  
!                       cli();
                        for (prev = (Scsi_Cmnd **) & (hostdata->disconnected_queue),
                        tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
                             tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp =
!                            (Scsi_Cmnd *) tmp->host_scribble)
                                if (cmd == tmp) {
                                        REMOVE(5, *prev, tmp, tmp->host_scribble);
                                        *prev = (Scsi_Cmnd *) tmp->host_scribble;
                                        tmp->host_scribble = NULL;
                                        tmp->result = DID_ABORT << 16;
!                                       restore_flags(flags);
                                        tmp->done(tmp);
                                        return SCSI_ABORT_SUCCESS;
                                }
                }
  /*
   * Case 5 : If we reached this point, the command was not found in any of 
--- 3563,3594 ----
  
                        do_abort(instance);
  
! 
!               NCR5380_spin_lock_irqsave(&io_request_lock, flags);     
!                        
                        for (prev = (Scsi_Cmnd **) & (hostdata->disconnected_queue),
                        tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
                             tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp =
!                                  (Scsi_Cmnd *) tmp->host_scribble) {
! 
!                               NCR5380_spin_unlock_irqrestore(&io_request_lock, 
flags);
! 
                                if (cmd == tmp) {
+                     NCR5380_spin_lock_irqsave(&io_request_lock, flags);       
+ 
                                        REMOVE(5, *prev, tmp, tmp->host_scribble);
                                        *prev = (Scsi_Cmnd *) tmp->host_scribble;
                                        tmp->host_scribble = NULL;
                                        tmp->result = DID_ABORT << 16;
! 
!                                       
NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
! 
                                        tmp->done(tmp);
                                        return SCSI_ABORT_SUCCESS;
                                }
+ 
+                               NCR5380_spin_lock_irqsave(&io_request_lock, flags);    
+ 
+                       }
                }
  /*
   * Case 5 : If we reached this point, the command was not found in any of 
***************
*** 3480,3487 ****
   * so we won't panic, but we will notify the user in case something really
   * broke.
   */
  
-       restore_flags(flags);
        printk("scsi%d : warning : SCSI command probably completed successfully\n"
               "         before abortion\n", instance->host_no);
        return SCSI_ABORT_NOT_RUNNING;
--- 3599,3607 ----
   * so we won't panic, but we will notify the user in case something really
   * broke.
   */
+ 
+       NCR5380_spin_unlock_irqrestore(&io_request_lock, flags);
  
        printk("scsi%d : warning : SCSI command probably completed successfully\n"
               "         before abortion\n", instance->host_no);
        return SCSI_ABORT_NOT_RUNNING;



-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]

Reply via email to