Re: [PATCH] dc395x fix memory mapping (was Re: dc395x: can't write to tape)
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)
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
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
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
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; -