* dc395x: can't write to tape
@ 2005-01-06 10:18 Andrew Schulman
2005-01-06 21:48 ` Guennadi Liakhovetski
0 siblings, 1 reply; 17+ messages in thread
From: Andrew Schulman @ 2005-01-06 10:18 UTC (permalink / raw)
To: linux-scsi
I have a Travan NS-20 tape drive connected to a Tekram DC395UW controller.
Both have worked without trouble for years. My kernel is 2.6.7, and I use
the dc395x driver (built as a module) from the kernel source.
Since about a month ago, I can't write a tar archive to tape. The operation
aborts before completion:
# tar -vv --one-file-system --file=/dev/st0 --create / /boot /home
tar: Removing leading `/' from member names
tar: /dev/st0: Wrote only 0 of 10240 bytes
tar: Error is not recoverable: exiting now
I've cleaned the drive with the approved head cleaner, tried three
different tapes, and retensioned each tape before writing. Still no joy. I
haven't rebuilt my kernel since the problem started, so it seems likely to be
a hardware problem.
/var/log/kern.log says
Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info fld=0x67,
Current st0: sense = f0 4
Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
Jan 5 22:50:18 helium kernel: Raw sense data:0xf0 0x00 0x04 0x00 0x00 0x00
0x67 0x0a 0x00 0x00 0x00 0x00 0x80 0x98 0x00 0x00 0x00 0x00
Jan 5 22:50:18 helium kernel: st0: Error with sense data: Current st0: sense
= 70 4
Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
Jan 5 22:50:18 helium kernel: Raw sense data:0x70 0x00 0x04 0x00 0x00 0x00
0x00 0x0a 0x00 0x00 0x00 0x00 0x80 0x98 0x00 0x00 0x00 0x00
Jan 5 22:50:18 helium kernel: st0: Error on write filemark.
Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info
fld=0xffffff63, Current st0: sense = f0 4
Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
Jan 5 22:50:18 helium kernel: Raw sense data:0xf0 0x00 0x04 0xff 0xff 0xff
0x63 0x0a 0x00 0x00 0x00 0x00 0x80 0x98 0x00 0x00 0x00 0x00
Question: from this log output, can anyone tell if my problem is more
likely in the controller, or in the tape drive? I realize there's not a lot
of data there... unfortunately even that doesn't mean anything to me.
To get more information, I uncommented
#define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)
in drivers/scsi/dc395x.c, rebuilt and reinserted the module, and tried to tar
again. But this resulted in multi-GB log files, so if there's a smaller
subset of debug options that would be useful, please let me know and I'll try
again.
I'd like very much to keep using this tape drive for several more years. It's
noisy and slow, but 10 GB/tape still isn't bad, and to replace the drive and
6 tapes would cost around $400, even today.
OTOH, SCSI cards are cheap and I wouldn't mind junking my old DC395 if it's at
fault.
Thanks in advance for any light you can shed.
Andrew.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-06 10:18 dc395x: can't write to tape Andrew Schulman
@ 2005-01-06 21:48 ` Guennadi Liakhovetski
2005-01-07 10:52 ` Andrew Schulman
2005-01-09 5:33 ` Jamie Lenehan
0 siblings, 2 replies; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-06 21:48 UTC (permalink / raw)
To: Andrew Schulman; +Cc: linux-scsi, Jamie Lenehan
Hi
On Thu, 6 Jan 2005, Andrew Schulman wrote:
> I have a Travan NS-20 tape drive connected to a Tekram DC395UW controller.
> Both have worked without trouble for years. My kernel is 2.6.7, and I use
> the dc395x driver (built as a module) from the kernel source.
>
> Since about a month ago, I can't write a tar archive to tape. The operation
> aborts before completion:
>
> # tar -vv --one-file-system --file=/dev/st0 --create / /boot /home
> tar: Removing leading `/' from member names
> tar: /dev/st0: Wrote only 0 of 10240 bytes
> tar: Error is not recoverable: exiting now
>
> I've cleaned the drive with the approved head cleaner, tried three
> different tapes, and retensioned each tape before writing. Still no joy. I
> haven't rebuilt my kernel since the problem started, so it seems likely to be
> a hardware problem.
>
> /var/log/kern.log says
>
> Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
This doesn't look good. However, after a brief look at the code, I cannot
say what exactly went wrong there. Jamie?
> Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info fld=0x67,
> Current st0: sense = f0 4
Sense key 4 - hardware error.
> Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
Additional sense code 0x80 - vendor specific.
So, the sense codes indicate a hardware problem on the tape drive, but the
first message might mean a software bug. You don't have highmem on that
machine (> 1GB RAM), do you?
Regards
Guennadi
> Jan 5 22:50:18 helium kernel: Raw sense data:0xf0 0x00 0x04 0x00 0x00 0x00
> 0x67 0x0a 0x00 0x00 0x00 0x00 0x80 0x98 0x00 0x00 0x00 0x00
> Jan 5 22:50:18 helium kernel: st0: Error with sense data: Current st0: sense
> = 70 4
> Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
> Jan 5 22:50:18 helium kernel: Raw sense data:0x70 0x00 0x04 0x00 0x00 0x00
> 0x00 0x0a 0x00 0x00 0x00 0x00 0x80 0x98 0x00 0x00 0x00 0x00
> Jan 5 22:50:18 helium kernel: st0: Error on write filemark.
> Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info
> fld=0xffffff63, Current st0: sense = f0 4
> Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
> Jan 5 22:50:18 helium kernel: Raw sense data:0xf0 0x00 0x04 0xff 0xff 0xff
> 0x63 0x0a 0x00 0x00 0x00 0x00 0x80 0x98 0x00 0x00 0x00 0x00
>
> Question: from this log output, can anyone tell if my problem is more
> likely in the controller, or in the tape drive? I realize there's not a lot
> of data there... unfortunately even that doesn't mean anything to me.
>
> To get more information, I uncommented
>
> #define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)
>
> in drivers/scsi/dc395x.c, rebuilt and reinserted the module, and tried to tar
> again. But this resulted in multi-GB log files, so if there's a smaller
> subset of debug options that would be useful, please let me know and I'll try
> again.
>
> I'd like very much to keep using this tape drive for several more years. It's
> noisy and slow, but 10 GB/tape still isn't bad, and to replace the drive and
> 6 tapes would cost around $400, even today.
>
> OTOH, SCSI cards are cheap and I wouldn't mind junking my old DC395 if it's at
> fault.
>
> Thanks in advance for any light you can shed.
> Andrew.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-06 21:48 ` Guennadi Liakhovetski
@ 2005-01-07 10:52 ` Andrew Schulman
2005-01-07 20:13 ` Guennadi Liakhovetski
2005-01-09 5:33 ` Jamie Lenehan
1 sibling, 1 reply; 17+ messages in thread
From: Andrew Schulman @ 2005-01-07 10:52 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linux-scsi, Jamie Lenehan
> > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
>
> This doesn't look good. However, after a brief look at the code, I cannot
> say what exactly went wrong there. Jamie?
I didn't mention it before, but I've gotten that particular message for a long
time, even when the tape drive used to work. I reported on it several months
ago on this list
(http://marc.theaimsgroup.com/?l=linux-scsi&m=108039964822342&w=2) in
connection with a balky CD burner, which I've since junked. After some work
and upgrading my kernel, I got the CD burner working again, but the flood of
sg_to_virt failed messages continued. Jaime finally recommended that I just
disable them, which I did until I got rid of the CD burner. Maybe
relevant...
> > Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info fld=0x67,
> > Current st0: sense = f0 4
>
> Sense key 4 - hardware error.
>
> > Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
>
> Additional sense code 0x80 - vendor specific.
>
> So, the sense codes indicate a hardware problem on the tape drive, but the
> first message might mean a software bug. You don't have highmem on that
> machine (> 1GB RAM), do you?
CONFIG_HIGHMEM4G is enabled in the kernel, and I have 1 GiB of RAM.
Thanks,
Andrew.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-07 10:52 ` Andrew Schulman
@ 2005-01-07 20:13 ` Guennadi Liakhovetski
2005-01-08 21:42 ` Guennadi Liakhovetski
2005-01-11 15:19 ` Andrew Schulman
0 siblings, 2 replies; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-07 20:13 UTC (permalink / raw)
To: Andrew Schulman; +Cc: linux-scsi, Jamie Lenehan
On Fri, 7 Jan 2005, Andrew Schulman wrote:
> > > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
> >
> > This doesn't look good. However, after a brief look at the code, I cannot
> > say what exactly went wrong there. Jamie?
>
> I didn't mention it before, but I've gotten that particular message for a long
> time, even when the tape drive used to work. I reported on it several months
> ago on this list
> (http://marc.theaimsgroup.com/?l=linux-scsi&m=108039964822342&w=2) in
> connection with a balky CD burner, which I've since junked. After some work
> and upgrading my kernel, I got the CD burner working again, but the flood of
> sg_to_virt failed messages continued. Jaime finally recommended that I just
> disable them, which I did until I got rid of the CD burner. Maybe
> relevant...
Could you try disabling highmem either try a kernel without highmem
support, or boot with mem=900M, or remove a part of your RAM (if you
don't have to saw your RAMs for that:-)), maybe, booting with highmem=0,
or with nohighio.
> > > Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info fld=0x67,
> > > Current st0: sense = f0 4
> >
> > Sense key 4 - hardware error.
> >
> > > Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
> >
> > Additional sense code 0x80 - vendor specific.
> >
> > So, the sense codes indicate a hardware problem on the tape drive, but the
> > first message might mean a software bug. You don't have highmem on that
> > machine (> 1GB RAM), do you?
>
> CONFIG_HIGHMEM4G is enabled in the kernel, and I have 1 GiB of RAM.
Yeah, that should have been >= 1G. So, at least the message could indicate
a bug in highmem support in the driver.
Still, your tape problem seems to be unrelated. Do you have a chance to
test it in another system / with another controller?
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-07 20:13 ` Guennadi Liakhovetski
@ 2005-01-08 21:42 ` Guennadi Liakhovetski
2005-01-11 15:19 ` Andrew Schulman
1 sibling, 0 replies; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-08 21:42 UTC (permalink / raw)
To: Andrew Schulman; +Cc: linux-scsi, Jamie Lenehan
On Fri, 7 Jan 2005, Guennadi Liakhovetski wrote:
> On Fri, 7 Jan 2005, Andrew Schulman wrote:
>
> > > > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
> > > > Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info fld=0x67,
> > > > Current st0: sense = f0 4
> > >
> > > Sense key 4 - hardware error.
> > >
> > > > Jan 5 22:50:18 helium kernel: ASC=80 ASCQ=98
> > >
> > > Additional sense code 0x80 - vendor specific.
Ok. My interpretation of the errors you see is 1) the dc395x driver is
buggy for highmem, and 2) your tape drive has a problem. For the first
problem I _could_ try to fix it, however, this will take some time. Unless
somebody more skilled does it faster and better than I, I will start
slowly fixing it, but it will take some time. And, although I do have a
dc-315 adapter, I don't have highmem (would just booting with highmem=64M
allow me to test it? Oh, I can check it - will just try it and see if I
now get the same error messages), so, would be good if you, Andrew, could
test my results, when I am ready (could be a couple of months:-))? I'll
mail you then.
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-06 21:48 ` Guennadi Liakhovetski
2005-01-07 10:52 ` Andrew Schulman
@ 2005-01-09 5:33 ` Jamie Lenehan
2005-01-09 11:42 ` Guennadi Liakhovetski
1 sibling, 1 reply; 17+ messages in thread
From: Jamie Lenehan @ 2005-01-09 5:33 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: Andrew Schulman, linux-scsi
On Thu, Jan 06, 2005 at 10:48:38PM +0100, Guennadi Liakhovetski wrote:
[...]
> > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
>
> This doesn't look good. However, after a brief look at the code, I cannot
> say what exactly went wrong there. Jamie?
This messages has been happening in the driver for ever for some
people (mos tlikely related to specific devices they are using?). I
believe the sg_to_virt thing is trying to convert from the bus
address back to the virtual address to be able to recaculate the
position for the next transfer after a partial transfer. I've never
been able to actually reproduce this specific problem myself.
All the s/g list handling stuff really needs to be re-written. I'm
certain that it's not high-mem safe and another rather nasty thing is
that it modifies the sg lists after dma mapping them in some
situations which isn't really on (and seems to be the cause of the
hangs I see when running on sparc64 with some additional patches I
have to support big endien machines.)
[...]
--
Jamie Lenehan <lenehan@twibble.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-09 5:33 ` Jamie Lenehan
@ 2005-01-09 11:42 ` Guennadi Liakhovetski
2005-01-09 12:51 ` Jamie Lenehan
0 siblings, 1 reply; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-09 11:42 UTC (permalink / raw)
To: Jamie Lenehan; +Cc: Andrew Schulman, linux-scsi
On Sun, 9 Jan 2005, Jamie Lenehan wrote:
> On Thu, Jan 06, 2005 at 10:48:38PM +0100, Guennadi Liakhovetski wrote:
> [...]
> > > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt failed
> >
> > This doesn't look good. However, after a brief look at the code, I cannot
> > say what exactly went wrong there. Jamie?
>
> This messages has been happening in the driver for ever for some
> people (mos tlikely related to specific devices they are using?). I
I think, the search createria are wrong. Possibly, the following would be
better:
Index: drivers/scsi/dc395x.c
===================================================================
RCS file: /usr/src/cvs/linux-2_6/drivers/scsi/dc395x.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 dc395x.c
--- drivers/scsi/dc395x.c 17 Nov 2004 21:04:51 -0000 1.1.1.4
+++ drivers/scsi/dc395x.c 9 Jan 2005 11:36:17 -0000
@@ -2004,9 +2004,7 @@
/* We have to walk the scatterlist to find it */
sg = (struct scatterlist *)cmd->request_buffer;
while (segment--) {
- unsigned long mask =
- ~((unsigned long)sg->length - 1) & PAGE_MASK;
- if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
+ if (sg_dma_address(sg) <= psge->address && sg_dma_address(sg) + psge->length > psge->address) {
srb->virt_addr = (page_address(sg->page)
+ psge->address -
(psge->address & PAGE_MASK));
(untested). Andrew, could you test?
> believe the sg_to_virt thing is trying to convert from the bus
> address back to the virtual address to be able to recaculate the
> position for the next transfer after a partial transfer. I've never
> been able to actually reproduce this specific problem myself.
The driver is full of "hardware bug workarounds". Jamie, are those PIO
operations really needed? Do you ever see, that DMA doesn't transfer the
last 1-3 bytes of the segment?
> All the s/g list handling stuff really needs to be re-written. I'm
> certain that it's not high-mem safe and another rather nasty thing is
> that it modifies the sg lists after dma mapping them in some
> situations which isn't really on (and seems to be the cause of the
> hangs I see when running on sparc64 with some additional patches I
> have to support big endien machines.)
I could try to improve the highmem situation / sg-handling. Or do you plan
to do it, Jamie?
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-09 11:42 ` Guennadi Liakhovetski
@ 2005-01-09 12:51 ` Jamie Lenehan
2005-01-22 23:20 ` Guennadi Liakhovetski
0 siblings, 1 reply; 17+ messages in thread
From: Jamie Lenehan @ 2005-01-09 12:51 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: Andrew Schulman, linux-scsi
On Sun, Jan 09, 2005 at 12:42:26PM +0100, Guennadi Liakhovetski wrote:
[...]
> The driver is full of "hardware bug workarounds". Jamie, are those PIO
> operations really needed? Do you ever see, that DMA doesn't transfer the
> last 1-3 bytes of the segment?
What I suspect those workarounds were added for was to handle a
driver bug with dealing with WIDE transfers. The dc315 doesn't
support WIDE transfers and that's the card I have.
I wouldn't mind removing all the PIO code and disabling support for
WIDE devices. It'll simplify various bits of code a lot and mean no
longer having to be concered about breaking things for the dc395 when
making changes.
[...]
> I could try to improve the highmem situation / sg-handling. Or do you plan
> to do it, Jamie?
It's on my list of things to do, but I doubt I'll have any time to do
anything about in the next few months. So if you have the time and
desire please go ahead! I'll can test any changes you make (with a
CD-R/W, tape-drive and HDD), although it may take me a week or two to
get around to it.
--
Jamie Lenehan <lenehan@twibble.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-07 20:13 ` Guennadi Liakhovetski
2005-01-08 21:42 ` Guennadi Liakhovetski
@ 2005-01-11 15:19 ` Andrew Schulman
2005-01-11 22:16 ` Guennadi Liakhovetski
1 sibling, 1 reply; 17+ messages in thread
From: Andrew Schulman @ 2005-01-11 15:19 UTC (permalink / raw)
To: linux-scsi
> > > > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt
> > > > failed
> > >
> > > This doesn't look good. However, after a brief look at the code, I
> > > cannot say what exactly went wrong there. Jamie?
> >
> > I didn't mention it before, but I've gotten that particular message for a
> > long time, even when the tape drive used to work.
>
> Could you try disabling highmem either try a kernel without highmem
> support, or boot with mem=900M, or remove a part of your RAM (if you
> don't have to saw your RAMs for that:-)), maybe, booting with highmem=0,
> or with nohighio.
Okay, I finally got to this. Rebooted with mem=900M. Unfortunately tar fails
as before:
tar: /dev/st0: Wrote only 0 of 10240 bytes
tar: Error is not recoverable: exiting now
I had rebuilt dc395x with
#define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)
uncommented in dc395x.c. Here's what I got:
# tail -40 /var/log/kern.log
Jan 11 06:29:18 helium kernel: dc395x: srb_done: (pid#4596449) <02-0>
Jan 11 06:29:18 helium kernel: dc395x: srb_done: srb=f6aa2eec sg=0(0/1)
buf=e7c64000 addr=e7c64000
Jan 11 06:29:18 helium kernel: dc395x: srb_done: AUTO_REQSENSE1
Jan 11 06:29:18 helium kernel: dc395x: pci_unmap_srb_sense: buffer=12a69452
Jan 11 06:29:18 helium kernel: dc395x: ReqSense: MEDIUM_ERROR cmnd=0x10 <02-0>
stat=0 scan=1 sense=0x03 ASC=0x0c ASCQ=0x00 (0x00000000 0x00000000)
Jan 11 06:29:18 helium kernel: dc395x: srb_done: AUTO_REQSENSE2
Jan 11 06:29:18 helium kernel: dc395x: srb_going_remove: (pid#4596449) <02-0>
srb=f6aa2eec
Jan 11 06:29:18 helium kernel: dc395x: srb_done: (pid#4596449) done
result=0x08000002
Jan 11 06:29:18 helium kernel: dc395x: srb_free_insert: srb=f6aa2eec
Jan 11 06:29:18 helium kernel: st0: Error with sense data: Current st0: sense
= 70 3
Jan 11 06:29:18 helium kernel: ASC= c ASCQ= 0
Jan 11 06:29:18 helium kernel: Raw sense data:0x70 0x00 0x03 0x00 0x00 0x00
0x00 0x0a 0x00 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00 0x00
Jan 11 06:29:18 helium kernel: st0: Error on write filemark.
Jan 11 06:29:18 helium kernel: dc395x: queue_command: (pid#4596450) <02-0>
cmnd=0x01
Jan 11 06:29:18 helium kernel: dc395x: srb_get_free: srb=f6aa2f2c
Jan 11 06:29:18 helium kernel: dc395x: build_srb: (pid#4596450) <02-0>
Jan 11 06:29:18 helium kernel: dc395x: build_srb: [0] len=0 buf=e7c64000
use_sg=0 !MAP=277c0000
Jan 11 06:29:18 helium kernel: dc395x: start_scsi: (pid#4596450) <02-0>
srb=f6aa2f2c
Jan 11 06:29:18 helium kernel: dc395x: srb_going_append: (pid#4596450) <02-0>
srb=f6aa2f2c
Jan 11 06:29:18 helium kernel: dc395x: queue_command: (pid#4596450) done
Jan 11 06:29:18 helium kernel: dc395x: msgin_phase1: (pid#4596450)
Jan 11 06:29:18 helium kernel: dc395x: msgin_phase0: (pid#4596450)
Jan 11 06:29:18 helium kernel: dc395x: msgin_phase0: (pid#4596450) SAVE
POINTER rem=0 Ignore
Jan 11 06:29:18 helium kernel: dc395x: msgin_phase1: (pid#4596450)
Jan 11 06:29:18 helium kernel: dc395x: msgin_phase0: (pid#4596450)
Jan 11 06:29:18 helium kernel: dc395x: disconnect: (pid#4596450)
Jan 11 06:30:41 helium kernel: dc395x: reselect: acb=f6aa21e4
Jan 11 06:30:41 helium kernel: dc395x: reselect: select <2>
Jan 11 06:30:41 helium kernel: dc395x: status_phase1: (pid#4596450) <02-0>
Jan 11 06:30:41 helium kernel: dc395x: status_phase0: (pid#4596450) <02-0>
Jan 11 06:30:41 helium kernel: dc395x: disconnect: (pid#4596450)
Jan 11 06:30:41 helium kernel: dc395x: srb_done: (pid#4596450) <02-0>
Jan 11 06:30:41 helium kernel: dc395x: srb_done: srb=f6aa2f2c sg=0(0/0)
buf=e7c64000 addr=e7c64000
Jan 11 06:30:41 helium kernel: dc395x: srb_going_remove: (pid#4596450) <02-0>
srb=f6aa2f2c
Jan 11 06:30:41 helium kernel: dc395x: srb_done: (pid#4596450) done
result=0x00000000
Jan 11 06:30:41 helium kernel: dc395x: srb_free_insert: srb=f6aa2f2c
The log file is 2.8 GB uncompressed after this operation. Let me know if it
would be helpful to see more of it and I can post it (or part of it) on my
web site for download.
> > > > Jan 5 22:50:18 helium kernel: st0: Error with sense data: Info
> > > > fld=0x67, Current st0: sense = f0 4
> > >
> > > Sense key 4 - hardware error.
I notice that the sense key is 3 this time.
> Still, your tape problem seems to be unrelated. Do you have a chance to
> test it in another system / with another controller?
Not now, although I may replace the controller just as something to try. That
would be much cheaper than a new tape drive.
I have your other suggestions and will get to them as soon as I have time.
A.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-11 15:19 ` Andrew Schulman
@ 2005-01-11 22:16 ` Guennadi Liakhovetski
2005-01-12 8:58 ` Andrew Schulman
0 siblings, 1 reply; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-11 22:16 UTC (permalink / raw)
To: Andrew Schulman; +Cc: linux-scsi, Jamie Lenehan
On Tue, 11 Jan 2005, Andrew Schulman wrote:
> > > > > Jan 5 22:50:18 helium kernel: dc395x: sg_update_list: sg_to_virt
> > > > > failed
> >
> > Could you try disabling highmem either try a kernel without highmem
> > support, or boot with mem=900M, or remove a part of your RAM (if you
> > don't have to saw your RAMs for that:-)), maybe, booting with highmem=0,
> > or with nohighio.
>
> Okay, I finally got to this. Rebooted with mem=900M. Unfortunately tar fails
> as before:
>
> tar: /dev/st0: Wrote only 0 of 10240 bytes
> tar: Error is not recoverable: exiting now
I didn't expect disabling highmem to fix _this_ error. But do you still
see the "dc395x: sg_update_list: sg_to_virt failed" message with 900M?
Perhaps, the most interesting test would be with my patch...
> I had rebuilt dc395x with
>
> #define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)
>
> uncommented in dc395x.c. Here's what I got:
>
> # tail -40 /var/log/kern.log
> Jan 11 06:29:18 helium kernel: dc395x: srb_done: (pid#4596449) <02-0>
> Jan 11 06:29:18 helium kernel: dc395x: srb_done: srb=f6aa2eec sg=0(0/1)
> buf=e7c64000 addr=e7c64000
> Jan 11 06:29:18 helium kernel: dc395x: srb_done: AUTO_REQSENSE1
> Jan 11 06:29:18 helium kernel: dc395x: pci_unmap_srb_sense: buffer=12a69452
> Jan 11 06:29:18 helium kernel: dc395x: ReqSense: MEDIUM_ERROR cmnd=0x10 <02-0>
> stat=0 scan=1 sense=0x03 ASC=0x0c ASCQ=0x00 (0x00000000 0x00000000)
...well, could you just keep the log for now, maybe we'll have a look at
it later, I'd just first try to fix the highmem problem, before trying to
figure out what's going on with your tape drive. BTW, when it worked, you
already had 1G RAM in the PC, right?
> I have your other suggestions and will get to them as soon as I have time.
Thanks
Guennadi
P.S. Please, don't trim the CC list.
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-11 22:16 ` Guennadi Liakhovetski
@ 2005-01-12 8:58 ` Andrew Schulman
0 siblings, 0 replies; 17+ messages in thread
From: Andrew Schulman @ 2005-01-12 8:58 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linux-scsi, Jamie Lenehan
> > Okay, I finally got to this. Rebooted with mem=900M. Unfortunately tar
> > fails as before:
> >
> > tar: /dev/st0: Wrote only 0 of 10240 bytes
> > tar: Error is not recoverable: exiting now
>
> I didn't expect disabling highmem to fix _this_ error. But do you still
> see the "dc395x: sg_update_list: sg_to_virt failed" message with 900M?
> Perhaps, the most interesting test would be with my patch...
OK. Yes, with mem=900M, the 'sg_to_virt failed' messages all went away. Will
test the patch when I can.
> ...well, could you just keep the log for now, maybe we'll have a look at
> it later, I'd just first try to fix the highmem problem, before trying to
> figure out what's going on with your tape drive. BTW, when it worked, you
> already had 1G RAM in the PC, right?
Right.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-09 12:51 ` Jamie Lenehan
@ 2005-01-22 23:20 ` Guennadi Liakhovetski
2005-01-27 1:13 ` Andrew Schulman
2005-02-06 22:11 ` [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape) Guennadi Liakhovetski
0 siblings, 2 replies; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-22 23:20 UTC (permalink / raw)
To: Jamie Lenehan; +Cc: Andrew Schulman, linux-scsi
On Sun, 9 Jan 2005, Jamie Lenehan wrote:
> On Sun, Jan 09, 2005 at 12:42:26PM +0100, Guennadi Liakhovetski wrote:
> [...]
> > I could try to improve the highmem situation / sg-handling. Or do you plan
> > to do it, Jamie?
>
> It's on my list of things to do, but I doubt I'll have any time to do
> anything about in the next few months. So if you have the time and
> desire please go ahead! I'll can test any changes you make (with a
> CD-R/W, tape-drive and HDD), although it may take me a week or two to
> get around to it.
Ok, less than 2 weeks and here comes the first attempt. It removes
page_to_virt and maps sg lists dynamically. Please, review, test. Slightly
tested here - without highmem.
Thanks
Guennadi
---
Guennadi Liakhovetski
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
diff -u a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c 17 Nov 2004 21:04:51
+++ b/drivers/scsi/dc395x.c 22 Jan 2005 22:55:45
@@ -182,7 +182,7 @@
* cross a page boundy.
*/
#define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
-
+#define VIRTX_LEN (sizeof(void *) * DC395x_MAX_SG_LISTENTRY)
struct SGentry {
u32 address; /* bus! address */
@@ -234,6 +234,7 @@
u8 sg_count; /* No of HW sg entries for this request */
u8 sg_index; /* Index of HW sg entry for this request */
u32 total_xfer_length; /* Total number of bytes remaining to be transfered */
+ void **virt_map;
unsigned char *virt_addr; /* Virtual address of current transfer position */
/*
@@ -1020,14 +1021,14 @@
reqlen, cmd->request_buffer, cmd->use_sg,
srb->sg_count);
- srb->virt_addr = page_address(sl->page);
for (i = 0; i < srb->sg_count; i++) {
- u32 busaddr = (u32)sg_dma_address(&sl[i]);
- u32 seglen = (u32)sl[i].length;
- sgp[i].address = busaddr;
+ u32 seglen = (u32)sg_dma_len(sl + i);
+ sgp[i].address = (u32)sg_dma_address(sl + i);
sgp[i].length = seglen;
srb->total_xfer_length += seglen;
+ srb->virt_map[i] = kmap(sl[i].page);
}
+ srb->virt_addr = srb->virt_map[0];
sgp += srb->sg_count - 1;
/*
@@ -1964,6 +1965,7 @@
int segment = cmd->use_sg;
u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
struct SGentry *psge = srb->segment_x + srb->sg_index;
+ void **virt = srb->virt_map;
dprintkdbg(DBG_0,
"sg_update_list: Transfered %i of %i bytes, %i remain\n",
@@ -2003,16 +2005,16 @@
/* We have to walk the scatterlist to find it */
sg = (struct scatterlist *)cmd->request_buffer;
+ idx = 0;
while (segment--) {
unsigned long mask =
~((unsigned long)sg->length - 1) & PAGE_MASK;
if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
- srb->virt_addr = (page_address(sg->page)
- + psge->address -
- (psge->address & PAGE_MASK));
+ srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK);
return;
}
++sg;
+ ++idx;
}
dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
@@ -2138,7 +2140,7 @@
DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
}
/*
- * calculate all the residue data that not yet tranfered
+ * calculate all the residue data that not yet transfered
* SCSI transfer counter + left in SCSI FIFO data
*
* .....TRM_S1040_SCSI_COUNTER (24bits)
@@ -3256,6 +3258,7 @@
struct scsi_cmnd *cmd = srb->cmd;
enum dma_data_direction dir = cmd->sc_data_direction;
if (cmd->use_sg && dir != PCI_DMA_NONE) {
+ int i;
/* unmap DC395x SG list */
dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
srb->sg_bus_addr, SEGMENTX_LEN);
@@ -3265,6 +3268,8 @@
dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
cmd->use_sg, cmd->request_buffer);
/* unmap the sg segments */
+ for (i = 0; i < srb->sg_count; i++)
+ kunmap(virt_to_page(srb->virt_map[i]));
pci_unmap_sg(acb->dev,
(struct scatterlist *)cmd->request_buffer,
cmd->use_sg, dir);
@@ -3311,7 +3316,7 @@
if (cmd->use_sg) {
struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
- ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
+ ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset);
} else {
ptr = (struct ScsiInqData *)(cmd->request_buffer);
}
@@ -4246,8 +4251,9 @@
const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
- if (acb->srb_array[i].segment_x)
- kfree(acb->srb_array[i].segment_x);
+ kfree(acb->srb_array[i].segment_x);
+
+ vfree(acb->srb_array[0].virt_map);
}
@@ -4263,9 +4269,12 @@
int srb_idx = 0;
unsigned i = 0;
struct SGentry *ptr;
+ void **virt_array;
- for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
+ for (i = 0; i < DC395x_MAX_SRB_CNT; i++) {
acb->srb_array[i].segment_x = NULL;
+ acb->srb_array[i].virt_map = NULL;
+ }
dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
while (pages--) {
@@ -4286,6 +4295,19 @@
ptr + (i * DC395x_MAX_SG_LISTENTRY);
else
dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
+
+ virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*));
+
+ if (!virt_array) {
+ adapter_sg_tables_free(acb);
+ return 1;
+ }
+
+ for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) {
+ acb->srb_array[i].virt_map = virt_array;
+ virt_array += DC395x_MAX_SG_LISTENTRY;
+ }
+
return 0;
}
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-22 23:20 ` Guennadi Liakhovetski
@ 2005-01-27 1:13 ` Andrew Schulman
2005-01-27 20:45 ` Guennadi Liakhovetski
2005-02-06 22:11 ` [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape) Guennadi Liakhovetski
1 sibling, 1 reply; 17+ messages in thread
From: Andrew Schulman @ 2005-01-27 1:13 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: Jamie Lenehan, linux-scsi
> > > I could try to improve the highmem situation / sg-handling. Or do you
> > > plan to do it, Jamie?
> >
> > It's on my list of things to do, but I doubt I'll have any time to do
> > anything about in the next few months. So if you have the time and
> > desire please go ahead! I'll can test any changes you make (with a
> > CD-R/W, tape-drive and HDD), although it may take me a week or two to
> > get around to it.
>
> Ok, less than 2 weeks and here comes the first attempt. It removes
> page_to_virt and maps sg lists dynamically. Please, review, test. Slightly
> tested here - without highmem.
Guennadi and Jamie, thanks for your help on this. However, I'm afraid I have
to bail out at this point. My tape drive was the only reason I was keeping
my old DC395UW controller going, and it has now gone bad. So I've had to
yank both the card and tape drive and install a different backup solution.
So, I can't test any patches.
Good luck, and my highest regards to both of you for your continuing work on
this project. You are making one corner of Linux and open source software
work.
Andrew.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: dc395x: can't write to tape
2005-01-27 1:13 ` Andrew Schulman
@ 2005-01-27 20:45 ` Guennadi Liakhovetski
0 siblings, 0 replies; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-01-27 20:45 UTC (permalink / raw)
To: Andrew Schulman; +Cc: Jamie Lenehan, linux-scsi
On Wed, 26 Jan 2005, Andrew Schulman wrote:
> > > > I could try to improve the highmem situation / sg-handling. Or do you
> > > > plan to do it, Jamie?
> > >
> > > It's on my list of things to do, but I doubt I'll have any time to do
> > > anything about in the next few months. So if you have the time and
> > > desire please go ahead! I'll can test any changes you make (with a
> > > CD-R/W, tape-drive and HDD), although it may take me a week or two to
> > > get around to it.
> >
> > Ok, less than 2 weeks and here comes the first attempt. It removes
> > page_to_virt and maps sg lists dynamically. Please, review, test. Slightly
> > tested here - without highmem.
>
> Guennadi and Jamie, thanks for your help on this. However, I'm afraid I have
> to bail out at this point. My tape drive was the only reason I was keeping
> my old DC395UW controller going, and it has now gone bad. So I've had to
> yank both the card and tape drive and install a different backup solution.
> So, I can't test any patches.
Thanks for your help.
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape)
2005-01-22 23:20 ` Guennadi Liakhovetski
2005-01-27 1:13 ` Andrew Schulman
@ 2005-02-06 22:11 ` Guennadi Liakhovetski
2005-02-21 22:01 ` Guennadi Liakhovetski
1 sibling, 1 reply; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-02-06 22:11 UTC (permalink / raw)
To: Jamie Lenehan; +Cc: linux-scsi
Hi again
Two weeks since I posted this patch - ping...
Regards
Guennadi
On Sun, 23 Jan 2005, Guennadi Liakhovetski wrote:
> On Sun, 9 Jan 2005, Jamie Lenehan wrote:
>
> > On Sun, Jan 09, 2005 at 12:42:26PM +0100, Guennadi Liakhovetski wrote:
> > [...]
> > > I could try to improve the highmem situation / sg-handling. Or do you plan
> > > to do it, Jamie?
> >
> > It's on my list of things to do, but I doubt I'll have any time to do
> > anything about in the next few months. So if you have the time and
> > desire please go ahead! I'll can test any changes you make (with a
> > CD-R/W, tape-drive and HDD), although it may take me a week or two to
> > get around to it.
>
> Ok, less than 2 weeks and here comes the first attempt. It removes
> page_to_virt and maps sg lists dynamically. Please, review, test. Slightly
> tested here - without highmem.
>
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>
> diff -u a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
> --- a/drivers/scsi/dc395x.c 17 Nov 2004 21:04:51
> +++ b/drivers/scsi/dc395x.c 22 Jan 2005 22:55:45
> @@ -182,7 +182,7 @@
> * cross a page boundy.
> */
> #define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
> -
> +#define VIRTX_LEN (sizeof(void *) * DC395x_MAX_SG_LISTENTRY)
>
> struct SGentry {
> u32 address; /* bus! address */
> @@ -234,6 +234,7 @@
> u8 sg_count; /* No of HW sg entries for this request */
> u8 sg_index; /* Index of HW sg entry for this request */
> u32 total_xfer_length; /* Total number of bytes remaining to be transfered */
> + void **virt_map;
> unsigned char *virt_addr; /* Virtual address of current transfer position */
>
> /*
> @@ -1020,14 +1021,14 @@
> reqlen, cmd->request_buffer, cmd->use_sg,
> srb->sg_count);
>
> - srb->virt_addr = page_address(sl->page);
> for (i = 0; i < srb->sg_count; i++) {
> - u32 busaddr = (u32)sg_dma_address(&sl[i]);
> - u32 seglen = (u32)sl[i].length;
> - sgp[i].address = busaddr;
> + u32 seglen = (u32)sg_dma_len(sl + i);
> + sgp[i].address = (u32)sg_dma_address(sl + i);
> sgp[i].length = seglen;
> srb->total_xfer_length += seglen;
> + srb->virt_map[i] = kmap(sl[i].page);
> }
> + srb->virt_addr = srb->virt_map[0];
> sgp += srb->sg_count - 1;
>
> /*
> @@ -1964,6 +1965,7 @@
> int segment = cmd->use_sg;
> u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
> struct SGentry *psge = srb->segment_x + srb->sg_index;
> + void **virt = srb->virt_map;
>
> dprintkdbg(DBG_0,
> "sg_update_list: Transfered %i of %i bytes, %i remain\n",
> @@ -2003,16 +2005,16 @@
>
> /* We have to walk the scatterlist to find it */
> sg = (struct scatterlist *)cmd->request_buffer;
> + idx = 0;
> while (segment--) {
> unsigned long mask =
> ~((unsigned long)sg->length - 1) & PAGE_MASK;
> if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
> - srb->virt_addr = (page_address(sg->page)
> - + psge->address -
> - (psge->address & PAGE_MASK));
> + srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK);
> return;
> }
> ++sg;
> + ++idx;
> }
>
> dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
> @@ -2138,7 +2140,7 @@
> DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
> }
> /*
> - * calculate all the residue data that not yet tranfered
> + * calculate all the residue data that not yet transfered
> * SCSI transfer counter + left in SCSI FIFO data
> *
> * .....TRM_S1040_SCSI_COUNTER (24bits)
> @@ -3256,6 +3258,7 @@
> struct scsi_cmnd *cmd = srb->cmd;
> enum dma_data_direction dir = cmd->sc_data_direction;
> if (cmd->use_sg && dir != PCI_DMA_NONE) {
> + int i;
> /* unmap DC395x SG list */
> dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
> srb->sg_bus_addr, SEGMENTX_LEN);
> @@ -3265,6 +3268,8 @@
> dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
> cmd->use_sg, cmd->request_buffer);
> /* unmap the sg segments */
> + for (i = 0; i < srb->sg_count; i++)
> + kunmap(virt_to_page(srb->virt_map[i]));
> pci_unmap_sg(acb->dev,
> (struct scatterlist *)cmd->request_buffer,
> cmd->use_sg, dir);
> @@ -3311,7 +3316,7 @@
>
> if (cmd->use_sg) {
> struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
> - ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
> + ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset);
> } else {
> ptr = (struct ScsiInqData *)(cmd->request_buffer);
> }
> @@ -4246,8 +4251,9 @@
> const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
>
> for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
> - if (acb->srb_array[i].segment_x)
> - kfree(acb->srb_array[i].segment_x);
> + kfree(acb->srb_array[i].segment_x);
> +
> + vfree(acb->srb_array[0].virt_map);
> }
>
>
> @@ -4263,9 +4269,12 @@
> int srb_idx = 0;
> unsigned i = 0;
> struct SGentry *ptr;
> + void **virt_array;
>
> - for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
> + for (i = 0; i < DC395x_MAX_SRB_CNT; i++) {
> acb->srb_array[i].segment_x = NULL;
> + acb->srb_array[i].virt_map = NULL;
> + }
>
> dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
> while (pages--) {
> @@ -4286,6 +4295,19 @@
> ptr + (i * DC395x_MAX_SG_LISTENTRY);
> else
> dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
> +
> + virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*));
> +
> + if (!virt_array) {
> + adapter_sg_tables_free(acb);
> + return 1;
> + }
> +
> + for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) {
> + acb->srb_array[i].virt_map = virt_array;
> + virt_array += DC395x_MAX_SG_LISTENTRY;
> + }
> +
> return 0;
> }
>
>
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape)
2005-02-06 22:11 ` [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape) Guennadi Liakhovetski
@ 2005-02-21 22:01 ` Guennadi Liakhovetski
2005-02-23 10:16 ` Jamie Lenehan
0 siblings, 1 reply; 17+ messages in thread
From: Guennadi Liakhovetski @ 2005-02-21 22:01 UTC (permalink / raw)
To: Jamie Lenehan; +Cc: linux-scsi
On Sun, 6 Feb 2005, Guennadi Liakhovetski wrote:
> Two weeks since I posted this patch - ping...
...and another two weeks since you, Jamie, replied to me privately. Just
wanted to say, it would be good to get this bug fixed for the post-2.6.11
SCSI patch.
Regards
Guennadi
>
> On Sun, 23 Jan 2005, Guennadi Liakhovetski wrote:
>
> > On Sun, 9 Jan 2005, Jamie Lenehan wrote:
> >
> > > On Sun, Jan 09, 2005 at 12:42:26PM +0100, Guennadi Liakhovetski wrote:
> > > [...]
> > > > I could try to improve the highmem situation / sg-handling. Or do you plan
> > > > to do it, Jamie?
> > >
> > > It's on my list of things to do, but I doubt I'll have any time to do
> > > anything about in the next few months. So if you have the time and
> > > desire please go ahead! I'll can test any changes you make (with a
> > > CD-R/W, tape-drive and HDD), although it may take me a week or two to
> > > get around to it.
> >
> > Ok, less than 2 weeks and here comes the first attempt. It removes
> > page_to_virt and maps sg lists dynamically. Please, review, test. Slightly
> > tested here - without highmem.
> >
> > Thanks
> > Guennadi
> > ---
> > Guennadi Liakhovetski
> >
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> >
> > diff -u a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
> > --- a/drivers/scsi/dc395x.c 17 Nov 2004 21:04:51
> > +++ b/drivers/scsi/dc395x.c 22 Jan 2005 22:55:45
> > @@ -182,7 +182,7 @@
> > * cross a page boundy.
> > */
> > #define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
> > -
> > +#define VIRTX_LEN (sizeof(void *) * DC395x_MAX_SG_LISTENTRY)
> >
> > struct SGentry {
> > u32 address; /* bus! address */
> > @@ -234,6 +234,7 @@
> > u8 sg_count; /* No of HW sg entries for this request */
> > u8 sg_index; /* Index of HW sg entry for this request */
> > u32 total_xfer_length; /* Total number of bytes remaining to be transfered */
> > + void **virt_map;
> > unsigned char *virt_addr; /* Virtual address of current transfer position */
> >
> > /*
> > @@ -1020,14 +1021,14 @@
> > reqlen, cmd->request_buffer, cmd->use_sg,
> > srb->sg_count);
> >
> > - srb->virt_addr = page_address(sl->page);
> > for (i = 0; i < srb->sg_count; i++) {
> > - u32 busaddr = (u32)sg_dma_address(&sl[i]);
> > - u32 seglen = (u32)sl[i].length;
> > - sgp[i].address = busaddr;
> > + u32 seglen = (u32)sg_dma_len(sl + i);
> > + sgp[i].address = (u32)sg_dma_address(sl + i);
> > sgp[i].length = seglen;
> > srb->total_xfer_length += seglen;
> > + srb->virt_map[i] = kmap(sl[i].page);
> > }
> > + srb->virt_addr = srb->virt_map[0];
> > sgp += srb->sg_count - 1;
> >
> > /*
> > @@ -1964,6 +1965,7 @@
> > int segment = cmd->use_sg;
> > u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
> > struct SGentry *psge = srb->segment_x + srb->sg_index;
> > + void **virt = srb->virt_map;
> >
> > dprintkdbg(DBG_0,
> > "sg_update_list: Transfered %i of %i bytes, %i remain\n",
> > @@ -2003,16 +2005,16 @@
> >
> > /* We have to walk the scatterlist to find it */
> > sg = (struct scatterlist *)cmd->request_buffer;
> > + idx = 0;
> > while (segment--) {
> > unsigned long mask =
> > ~((unsigned long)sg->length - 1) & PAGE_MASK;
> > if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
> > - srb->virt_addr = (page_address(sg->page)
> > - + psge->address -
> > - (psge->address & PAGE_MASK));
> > + srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK);
> > return;
> > }
> > ++sg;
> > + ++idx;
> > }
> >
> > dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
> > @@ -2138,7 +2140,7 @@
> > DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
> > }
> > /*
> > - * calculate all the residue data that not yet tranfered
> > + * calculate all the residue data that not yet transfered
> > * SCSI transfer counter + left in SCSI FIFO data
> > *
> > * .....TRM_S1040_SCSI_COUNTER (24bits)
> > @@ -3256,6 +3258,7 @@
> > struct scsi_cmnd *cmd = srb->cmd;
> > enum dma_data_direction dir = cmd->sc_data_direction;
> > if (cmd->use_sg && dir != PCI_DMA_NONE) {
> > + int i;
> > /* unmap DC395x SG list */
> > dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
> > srb->sg_bus_addr, SEGMENTX_LEN);
> > @@ -3265,6 +3268,8 @@
> > dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
> > cmd->use_sg, cmd->request_buffer);
> > /* unmap the sg segments */
> > + for (i = 0; i < srb->sg_count; i++)
> > + kunmap(virt_to_page(srb->virt_map[i]));
> > pci_unmap_sg(acb->dev,
> > (struct scatterlist *)cmd->request_buffer,
> > cmd->use_sg, dir);
> > @@ -3311,7 +3316,7 @@
> >
> > if (cmd->use_sg) {
> > struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
> > - ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
> > + ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset);
> > } else {
> > ptr = (struct ScsiInqData *)(cmd->request_buffer);
> > }
> > @@ -4246,8 +4251,9 @@
> > const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
> >
> > for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
> > - if (acb->srb_array[i].segment_x)
> > - kfree(acb->srb_array[i].segment_x);
> > + kfree(acb->srb_array[i].segment_x);
> > +
> > + vfree(acb->srb_array[0].virt_map);
> > }
> >
> >
> > @@ -4263,9 +4269,12 @@
> > int srb_idx = 0;
> > unsigned i = 0;
> > struct SGentry *ptr;
> > + void **virt_array;
> >
> > - for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
> > + for (i = 0; i < DC395x_MAX_SRB_CNT; i++) {
> > acb->srb_array[i].segment_x = NULL;
> > + acb->srb_array[i].virt_map = NULL;
> > + }
> >
> > dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
> > while (pages--) {
> > @@ -4286,6 +4295,19 @@
> > ptr + (i * DC395x_MAX_SG_LISTENTRY);
> > else
> > dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
> > +
> > + virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*));
> > +
> > + if (!virt_array) {
> > + adapter_sg_tables_free(acb);
> > + return 1;
> > + }
> > +
> > + for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) {
> > + acb->srb_array[i].virt_map = virt_array;
> > + virt_array += DC395x_MAX_SG_LISTENTRY;
> > + }
> > +
> > return 0;
> > }
> >
> >
>
> ---
> Guennadi Liakhovetski
>
>
---
Guennadi Liakhovetski
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape)
2005-02-21 22:01 ` Guennadi Liakhovetski
@ 2005-02-23 10:16 ` Jamie Lenehan
0 siblings, 0 replies; 17+ messages in thread
From: Jamie Lenehan @ 2005-02-23 10:16 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linux-scsi
On Mon, Feb 21, 2005 at 11:01:27PM +0100, Guennadi Liakhovetski wrote:
> On Sun, 6 Feb 2005, Guennadi Liakhovetski wrote:
>
> > Two weeks since I posted this patch - ping...
>
> ...and another two weeks since you, Jamie, replied to me privately. Just
> wanted to say, it would be good to get this bug fixed for the post-2.6.11
> SCSI patch.
Yep.
I've been rather busy and have not had any time to look at this. The patch
looks good and I've had no issues testing it now with highmem enabled on my
4G DAT drive.
I'll submit the patch in a minute.
Thanks.
Jamie.
--
Jamie Lenehan <lenehan@twibble.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2005-02-23 10:16 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-06 10:18 dc395x: can't write to tape Andrew Schulman
2005-01-06 21:48 ` Guennadi Liakhovetski
2005-01-07 10:52 ` Andrew Schulman
2005-01-07 20:13 ` Guennadi Liakhovetski
2005-01-08 21:42 ` Guennadi Liakhovetski
2005-01-11 15:19 ` Andrew Schulman
2005-01-11 22:16 ` Guennadi Liakhovetski
2005-01-12 8:58 ` Andrew Schulman
2005-01-09 5:33 ` Jamie Lenehan
2005-01-09 11:42 ` Guennadi Liakhovetski
2005-01-09 12:51 ` Jamie Lenehan
2005-01-22 23:20 ` Guennadi Liakhovetski
2005-01-27 1:13 ` Andrew Schulman
2005-01-27 20:45 ` Guennadi Liakhovetski
2005-02-06 22:11 ` [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape) Guennadi Liakhovetski
2005-02-21 22:01 ` Guennadi Liakhovetski
2005-02-23 10:16 ` Jamie Lenehan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox