From: Petr Vandrovec (akpm: not for applying. This is a bug reminder ;)) I'm not quite sure that this patch is correct thing to do, but if I do not remove mod_timer() call from ahc_scb_timer_reset then aic7xxx driver commits suicide on error recovery (at least from data overrun). Problem is that scb->io_ctx->eh_timeout.function is NULL at that time and so BUG_ON(!timer->function) in mod_timer fires. As I was not able to find which function should be invoked in 5 seconds, I just removed this, and it now seems much happier - it correctly recovers from test. (scsi5:A:0:0): data overrun detected in Data-in phase. Tag == 0x3. (scsi5:A:0:0): Have seen Data Phase. Length = 0. NumSGs = 0. sd 5:0:0:0: Attempting to queue an ABORT message CDB: 0x12 0x0 0x0 0x0 0xff 0x0 scsi5: At time of recovery, card was not paused >>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<< scsi5: Dumping Card State in Data-in phase, at SEQADDR 0x16c ... <<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>> sd 5:0:0:0: Device is active, asserting ATN Recovery code sleeping Recovery code awake Timer Expired aic7xxx_abort returns 0x2003 sd 5:0:0:0: Attempting to queue a TARGET RESET message CDB: 0x12 0x0 0x0 0x0 0xff 0x0 aic7xxx_dev_reset returns 0x2003 Recovery SCB completes Without patch kernel got killed after 'Recovery SCB completes' appeared with BUG at kernel/timer.c:292. Changes in aic7xxx_osm.h are just cleanup - ahc_timer_reset was not used even before, ahc_scb_timer_reset is not used after removing its call from aic7xxx_core.c (akpm: well. Perhaps we should be initialising the timer.function to something?) James said: I'm afraid if you hit this, it may be something much more serious is happening. That function pointer should only be NULL if the SCSI layer has taken back control of the command, in which case it's either a simple race (which your patch will fix) or the aic7xxx driver is hanging on to a command when it shouldn't (which will ultimately cause it to use free'd memory). Signed-off-by: Petr Vandrovec Cc: James Bottomley Signed-off-by: Andrew Morton --- drivers/scsi/aic7xxx/aic7xxx_core.c | 5 ---- drivers/scsi/aic7xxx/aic7xxx_osm.h | 27 -------------------------- 2 files changed, 32 deletions(-) diff -puN drivers/scsi/aic7xxx/aic7xxx_core.c~aic7xxx-crash-on-data-overrun drivers/scsi/aic7xxx/aic7xxx_core.c --- devel/drivers/scsi/aic7xxx/aic7xxx_core.c~aic7xxx-crash-on-data-overrun 2006-01-05 22:47:46.000000000 -0800 +++ devel-akpm/drivers/scsi/aic7xxx/aic7xxx_core.c 2006-01-05 22:47:46.000000000 -0800 @@ -567,11 +567,6 @@ ahc_handle_seqint(struct ahc_softc *ahc, scb->flags |= SCB_SENSE; ahc_qinfifo_requeue_tail(ahc, scb); ahc_outb(ahc, RETURN_1, SEND_SENSE); - /* - * Ensure we have enough time to actually - * retrieve the sense. - */ - ahc_scb_timer_reset(scb, 5 * 1000000); break; } default: diff -puN drivers/scsi/aic7xxx/aic7xxx_osm.h~aic7xxx-crash-on-data-overrun drivers/scsi/aic7xxx/aic7xxx_osm.h --- devel/drivers/scsi/aic7xxx/aic7xxx_osm.h~aic7xxx-crash-on-data-overrun 2006-01-05 22:47:46.000000000 -0800 +++ devel-akpm/drivers/scsi/aic7xxx/aic7xxx_osm.h 2006-01-05 22:47:46.000000000 -0800 @@ -234,33 +234,6 @@ typedef struct timer_list ahc_timer_t; #endif #include "aic7xxx.h" -/***************************** Timer Facilities *******************************/ -#define ahc_timer_init init_timer -#define ahc_timer_stop del_timer_sync -typedef void ahc_linux_callback_t (u_long); -static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec, - ahc_callback_t *func, void *arg); -static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec); - -static __inline void -ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg) -{ - struct ahc_softc *ahc; - - ahc = (struct ahc_softc *)arg; - del_timer(timer); - timer->data = (u_long)arg; - timer->expires = jiffies + (usec * HZ)/1000000; - timer->function = (ahc_linux_callback_t*)func; - add_timer(timer); -} - -static __inline void -ahc_scb_timer_reset(struct scb *scb, u_int usec) -{ - mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); -} - /***************************** SMP support ************************************/ #include _