On Mon, 13 Feb 2006, Fredrik Roubert wrote: > On Sat 11 Feb 22:06 CET 2006, Guennadi Liakhovetski wrote: > > > ...and your 64-bit dual-core CPU makes it even more fun. On the other > > hand, it means we won't be able to test it on highmem... Unless you > > agree to swap it to a 32-bit machine for a test:-) > > I actually have an old Pentium machine standing by that I could use for > testing (when the driver seems to work). ...and you still use your presumably main desktop PC for testing... brave man:-) > > Ok, if you feel adventurous, you might try the patch below. > > OK, that patch compiles with the following warnings: > > drivers/scsi/dc395x.c: In function ‘dump_register_info’: > drivers/scsi/dc395x.c:1226: warning: format ‘%i’ expects type ‘int’, but argument 5 has type ‘size_t’ > drivers/scsi/dc395x.c: In function ‘data_in_phase0’: > drivers/scsi/dc395x.c:2322: warning: comparison of distinct pointer types lacks a cast 64 bit... the first one might be fixed with the attached, the second one I removed altogether. > drivers/scsi/dc395x.c: In function ‘dc395x_init_one’: > drivers/scsi/dc395x.c:4357: warning: ‘ptr’ may be used uninitialized in this function Actually, even a compiler can guess, that it cannot be used uninitialised here. Mine, actually, doesn't complain. What version are you using? > Then it gives the following syslog output when I load the module and try > to scan an image: > > Feb 13 18:00:39 skalman kernel: dc395x: Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040 v2.05, 2004/03/08 > Feb 13 18:00:39 skalman kernel: ACPI: PCI Interrupt 0000:04:05.0[A] -> GSI 20 (level, low) -> IRQ 19 > Feb 13 18:00:39 skalman kernel: dc395x: Used settings: AdapterID=07, Speed=0(20.0MHz), dev_mode=0x57 > Feb 13 18:00:39 skalman kernel: dc395x: AdaptMode=0x0f, Tags=4(16), DelayReset=1s > Feb 13 18:00:39 skalman kernel: dc395x: Connectors: Termination: Auto Low High > Feb 13 18:00:39 skalman kernel: dc395x: Performing initial SCSI bus reset > Feb 13 18:00:39 skalman kernel: scsi3 : Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040 v2.05, 2004/03/08 > Feb 13 18:00:41 skalman kernel: Vendor: HP Model: C2520A Rev: 3503 > Feb 13 18:00:41 skalman kernel: Type: Processor ANSI SCSI revision: 02 > Feb 13 18:00:41 skalman kernel: 3:0:2:0: Attached scsi generic sg2 type 3 > Feb 13 18:02:57 skalman kernel: dc395x: reselect: w/o disconnected cmds <02-0> > Feb 13 18:02:57 skalman kernel: dc395x: disconnect: Unexpected reselection <02-0> > Feb 13 18:04:57 skalman kernel: dc395x: eh_abort: (pid#751) target=<02-0> cmd=ffff81007eb64080 > Feb 13 18:04:57 skalman kernel: dc395x: eh_abort: Command in progress<6>dc395x: eh_bus_reset: (pid#751) target=<02-0> cmd=ffff81007eb64080 > Feb 13 18:04:57 skalman kernel: dc395x: doing_srb_done: pids G:751(02-0) It might indeed be a hardware error in the end... Please, try the attached patch. It only adds a couple of printk's on the top of the previous one. As the problem happens only ones, hopefully, nothing bad will happen. The only thing I am not entirely sure about - you might get a warning for calling printk under spinlock_irqsave, if you have respective debugging enabled, I think. Then we'll hopefully see if at least for you the original patch does the right thing... Thanks Guennadi --- Guennadi Liakhovetski diff -u a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c --- a/drivers/scsi/dc395x.c 2006-02-13 23:55:52.000000000 +0100 +++ b/drivers/scsi/dc395x.c 2006-02-13 23:53:37.000000000 +0100 @@ -1221,7 +1221,7 @@ srb, srb->cmd, srb->cmd->pid, srb->cmd->cmnd[0], srb->cmd->device->id, srb->cmd->device->lun); - printk(" sglist=%p cnt=%i idx=%i len=%i\n", + printk(" sglist=%p cnt=%i idx=%i len=%u\n", srb->segment_x, srb->sg_count, srb->sg_index, srb->total_xfer_length); printk(" state=0x%04x status=0x%02x phase=0x%02x (%sconn.)\n", @@ -2227,6 +2227,9 @@ BUG_ON(i == sg_count); + printk(KERN_DEBUG "dc395x: Found sg-entry #%d[%u] of %d, offset %u after %u bytes for offset %u\n", + i, sg[i].length, sg_count, sg[i].offset, l2, *offset); + /* Offset starting from the beginning of first page in this sg-entry */ *offset = *offset - l2 + sg[i].offset; @@ -2266,7 +2269,7 @@ * seem to be a bad idea, actually. */ if (!(srb->state & SRB_XFERPAD)) { - unsigned int d_left_counter, max_left; + unsigned int d_left_counter; if (scsi_status & PARITYERROR) { dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " "Parity Error\n", srb->cmd->pid); @@ -2319,7 +2322,6 @@ DC395x_read32(acb, TRM_S1040_DMA_CXCNT), srb->total_xfer_length, d_left_counter); #if DC395x_LASTPIO - max_left = max(d_left_counter, srb->total_xfer_length); /* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */ if (d_left_counter && srb->total_xfer_length <= DC395x_LASTPIO) { @@ -2351,6 +2353,8 @@ base = dc395x_kmap_atomic_sg((struct scatterlist *)srb->cmd->request_buffer, srb->sg_count, &offset, &len); virt = base + offset; + printk(KERN_DEBUG "dc395x: Needed %u bytes in, mapped %u at %p\n", + left_io, len, base); } else { virt = srb->cmd->request_buffer + srb->cmd->request_bufflen - left_io; len = left_io; @@ -2395,6 +2399,7 @@ if (srb->cmd->use_sg) { dc395x_kunmap_atomic_sg(base); local_irq_restore(flags); + printk(KERN_DEBUG "dc395x: Unmapped at %p\n", base); } } @@ -2573,6 +2578,8 @@ base = dc395x_kmap_atomic_sg((struct scatterlist *)srb->cmd->request_buffer, srb->sg_count, &offset, &len); virt = base + offset; + printk(KERN_DEBUG "dc395x: Needed %u bytes out, mapped %u at %p\n", + left_io, len, base); } else { virt = srb->cmd->request_buffer + srb->cmd->request_bufflen - left_io; len = left_io; @@ -2591,6 +2598,7 @@ if (srb->cmd->use_sg) { dc395x_kunmap_atomic_sg(base); local_irq_restore(flags); + printk(KERN_DEBUG "dc395x: Unmapped at %p\n", base); } }