Messages in this thread Patch in this message | | | Date | Wed, 16 Jun 1999 22:58:54 -0300 (EST) | From | Marcelo Tosatti <> | Subject | [PATCH] SCSI drivers SMP problems |
| |
This patch fixes problems with some drivers which dont locked the io_request_lock before calling scsi_done. Drivers with problems : wd33c93.c, 53c7xx.c, NCR53C9x.c (Linus, update your tree with the current driver which fixes this and another problems), atp870u.c (i sent the patch a while ago), sym53c416.c, sgiwd93.c and aha152x (will be in 2.2.10ac3)
- Marcelo
diff -Nur linux.orig/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c --- linux.orig/drivers/scsi/53c7xx.c Sun Jun 13 14:48:03 1999 +++ linux/drivers/scsi/53c7xx.c Wed Jun 16 22:06:14 1999 @@ -7,6 +7,8 @@ * The chip type is #defined in script_asm.pl, as well as the Makefile. * Host scsi ID expected to be 7 - see NCR53c7x0_init(). * + * Added io_request_lock locking by Marcelo Tosatti <marcelo@conectiva.com.br> + * * I have removed the PCI code and some of the 53c8xx specific code - * simply to make this file smaller and easier to manage. * @@ -1938,7 +1940,10 @@ /* And return */ c->result = result; - c->scsi_done(c); + + spin_lock_irqsave(&io_request_lock, flags); + c->scsi_done(c); + spin_unlock_irqrestore(&io_request_lock, flags); restore_flags(flags); run_process_issue_queue(); @@ -4205,7 +4210,10 @@ print_command (tmp->cmnd); } + spin_lock_irqsave(&io_request_lock, flags); tmp->scsi_done(tmp); + spin_unlock_irqrestore(&io_request_lock, flags); + goto restart; } restore_flags(flags); @@ -5357,7 +5365,9 @@ for (; nuke_list; nuke_list = tmp) { tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer; nuke_list->result = DID_RESET << 16; + spin_lock_irqsave(&io_request_lock, flags); nuke_list->scsi_done (nuke_list); + spin_lock_irqrestore(&io_request_lock, flags); } restore_flags(flags); return SCSI_RESET_SUCCESS; diff -Nur linux.orig/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c --- linux.orig/drivers/scsi/in2000.c Sun Jun 13 14:48:02 1999 +++ linux/drivers/scsi/in2000.c Wed Jun 16 21:45:59 1999 @@ -5,6 +5,9 @@ * Copyright (c) 1996 John Shifflett, GeoLog Consulting * john@geolog.com * jshiffle@netcom.com + * + * Changes : + * Marcelo Tosatti <marcelo@conectiva.com.br> : Added io_request_lock locking * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Nur linux.orig/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c --- linux.orig/drivers/scsi/sym53c416.c Sun Jun 13 14:48:07 1999 +++ linux/drivers/scsi/sym53c416.c Wed Jun 16 21:10:00 1999 @@ -3,6 +3,10 @@ * Low-level SCSI driver for sym53c416 chip. * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) * + * Changes : + * + * Marcelo Tosatti <marcelo@conectiva.com.br> : Added io_request_lock locking + * * LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>] * * This program is free software; you can redistribute it and/or modify it @@ -30,6 +34,7 @@ #include <asm/dma.h> #include <asm/system.h> #include <asm/io.h> +#include <asm/spinlock.h> #include <linux/blk.h> #include <linux/version.h> #include "scsi.h" @@ -371,7 +376,9 @@ printk("sym53c416: Warning: Reset received\n"); current_command->SCp.phase = idle; current_command->result = DID_RESET << 16; + spin_lock_irqsave(&io_request_lock, flags); current_command->scsi_done(current_command); + spin_unlock_irqrestore(&io_request_lock, flags); return; } if(int_reg & ILCMD) /* Illegal Command */ @@ -379,7 +386,9 @@ printk("sym53c416: Warning: Illegal Command: 0x%02x\n", inb(base + COMMAND_REG)); current_command->SCp.phase = idle; current_command->result = DID_ERROR << 16; + spin_lock_irqsave(&io_request_lock, flags); current_command->scsi_done(current_command); + spin_unlock_irqrestore(&io_request_lock, flags); return; } if(status_reg & GE) /* Gross Error */ @@ -387,7 +396,9 @@ printk("sym53c416: Warning: Gross Error\n"); current_command->SCp.phase = idle; current_command->result = DID_ERROR << 16; + spin_lock_irqsave(&io_request_lock, flags); current_command->scsi_done(current_command); + spin_unlock_irqrestore(&io_request_lock, flags); return; } if(status_reg & PE) /* Parity Error */ @@ -395,7 +406,9 @@ printk("sym53c416: Warning: Parity Error\n"); current_command->SCp.phase = idle; current_command->result = DID_PARITY << 16; + spin_lock_irqsave(&io_request_lock, flags); current_command->scsi_done(current_command); + spin_unlock_irqrestore(&io_request_lock, flags); return; } if(pio_int_reg & (CE | OUE)) @@ -403,7 +416,9 @@ printk("sym53c416: Warning: PIO Interrupt Error\n"); current_command->SCp.phase = idle; current_command->result = DID_ERROR << 16; + spin_lock_irqsave(&io_request_lock, flags); current_command->scsi_done(current_command); + spin_unlock_irqrestore(&io_request_lock, flags); return; } if(int_reg & DIS) /* Disconnect */ @@ -413,7 +428,10 @@ else current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16); current_command->SCp.phase = idle; + + spin_lock_irqsave(&io_request_lock, flags); current_command->scsi_done(current_command); + spin_unlock_irqrestore(&io_request_lock, flags); return; } /* Now we handle SCSI phases */ diff -Nur linux.orig/drivers/scsi/wd33c93.c linux/drivers/scsi/wd33c93.c --- linux.orig/drivers/scsi/wd33c93.c Sun Jun 13 14:48:07 1999 +++ linux/drivers/scsi/wd33c93.c Wed Jun 16 20:36:40 1999 @@ -2,10 +2,15 @@ * wd33c93.c - Linux-68k device driver for the Commodore * Amiga A2091/590 SCSI controller card * + * * Copyright (c) 1996 John Shifflett, GeoLog Consulting * john@geolog.com * jshiffle@netcom.com * + * Changes : + * Augusto Cesar Radtke <bishop@sekure.org> : + * SMP bug fixed, locked io_request_lock before scsi_done + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -76,6 +81,7 @@ #include <linux/delay.h> #include <linux/version.h> #include <asm/irq.h> +#include <asm/spinlock.h> #if LINUX_VERSION_CODE >= 0x010300 #include <linux/blk.h> @@ -810,7 +816,9 @@ cmd->result = DID_NO_CONNECT << 16; hostdata->busy[cmd->target] &= ~(1 << cmd->lun); hostdata->state = S_UNCONNECTED; + spin_lock_irqsave(&io_request_lock, flags); cmd->scsi_done(cmd); + spin_unlock_irqrestore(&io_request_lock, flags); /* From esp.c: * There is a window of time within the scsi_done() path | |