Re: [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape)

2005-02-23 Thread Jamie Lenehan
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 [EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape)

2005-02-21 Thread Guennadi Liakhovetski
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 [EMAIL PROTECTED]
  
  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]));
  

Re: dc395x: can't write to tape

2005-01-27 Thread Guennadi Liakhovetski
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

-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: dc395x: can't write to tape

2005-01-26 Thread Andrew Schulman
   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.
-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: dc395x: can't write to tape

2005-01-22 Thread Guennadi Liakhovetski
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 [EMAIL PROTECTED]

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