* 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-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-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-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