Re: linux-2.1.102/drivers/scsi/fdomain.c as module hangs system

Linus Torvalds (torvalds@transmeta.com)
Tue, 19 May 1998 17:09:35 -0700 (PDT)


On Tue, 19 May 1998, Jeffrey Hundstad wrote:
>
> Like the subject says... version 2.1.102 of Linux hangs the machine
> tight when you:
>
> insmod fdomain
>
> At line 1194:
> /* sti(); Yes, we really want sti() here if we want to lock up our machine */
>
> if you change it back to the 2.1.101 version as:
> sti(); /* Yes, we really want sti() here if we want to lock up our machine */
>
> then everything works just fine.

No it doesn't, but you may not have a SMP machine to see the problem.

Can you test this diff instead, which should fix the problem and still be
safe on SMP too?

(The alternate fix is to drop the io-request spinlock while waiting, but I
wouldn't want to do that without any way of testing it)

Linus

-----
--- v2.1.102/linux/drivers/scsi/fdomain.c Thu May 14 19:47:40 1998
+++ linux/drivers/scsi/fdomain.c Tue May 19 17:01:18 1998
@@ -553,9 +553,9 @@

static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
{
- unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
-
- while (jiffies < the_time);
+ do {
+ usleep(10*1000);
+ } while (--amount);
}

inline static void fdomain_make_bus_idle( void )
@@ -1101,12 +1101,13 @@
outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */

- timeout = jiffies + 50; /* 500 mS */
- while (jiffies < timeout) {
+ timeout = 500;
+ do {
status = inb( TMC_Status_port ); /* Read adapter status */
if (status & 0x02) /* Arbitration complete */
- return 0;
- }
+ return 0;
+ udelay(1000); /* Wait one millisecond */
+ } while (--timeout);

/* Make bus idle */
fdomain_make_bus_idle();
@@ -1134,17 +1135,17 @@
/* Stop arbitration and enable parity */
outb( PARITY_MASK, TMC_Cntl_port );

- timeout = jiffies + 35; /* 350mS -- because of timeouts
- (was 250mS) */
+ timeout = 350; /* 350 msec */

- while (jiffies < timeout) {
+ do {
status = inb( SCSI_Status_port ); /* Read adapter status */
if (status & 1) { /* Busy asserted */
/* Enable SCSI Bus (on error, should make bus idle with 0) */
outb( 0x80, SCSI_Cntl_port );
return 0;
}
- }
+ udelay(1000); /* wait one msec */
+ } while (--timeout);
/* Make bus idle */
fdomain_make_bus_idle();
#if EVERY_ACCESS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu