Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "dc395x: Fix support for highmem"

It introduces a repeatable oops in the driver, which is a bigger problem
than the patch tries to solve. From the original description:

Author: Jamie Lenehan <lenehan@twibble.org>
Date: Thu Mar 3 14:41:40 2005 +0200

[PATCH] dc395x: Fix support for highmem

From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Removes the page_to_virt and maps sg lists dynamically.
This makes the driver work with highmem pages.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Jamie Lenehan <lenehan@twibble.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+13 -35
+13 -35
drivers/scsi/dc395x.c
··· 183 183 * cross a page boundy. 184 184 */ 185 185 #define SEGMENTX_LEN (sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY) 186 - #define VIRTX_LEN (sizeof(void *) * DC395x_MAX_SG_LISTENTRY) 186 + 187 187 188 188 struct SGentry { 189 189 u32 address; /* bus! address */ ··· 235 235 u8 sg_count; /* No of HW sg entries for this request */ 236 236 u8 sg_index; /* Index of HW sg entry for this request */ 237 237 u32 total_xfer_length; /* Total number of bytes remaining to be transfered */ 238 - void **virt_map; 239 238 unsigned char *virt_addr; /* Virtual address of current transfer position */ 240 239 241 240 /* ··· 1021 1022 reqlen, cmd->request_buffer, cmd->use_sg, 1022 1023 srb->sg_count); 1023 1024 1025 + srb->virt_addr = page_address(sl->page); 1024 1026 for (i = 0; i < srb->sg_count; i++) { 1025 - u32 seglen = (u32)sg_dma_len(sl + i); 1026 - sgp[i].address = (u32)sg_dma_address(sl + i); 1027 + u32 busaddr = (u32)sg_dma_address(&sl[i]); 1028 + u32 seglen = (u32)sl[i].length; 1029 + sgp[i].address = busaddr; 1027 1030 sgp[i].length = seglen; 1028 1031 srb->total_xfer_length += seglen; 1029 - srb->virt_map[i] = kmap(sl[i].page); 1030 1032 } 1031 - srb->virt_addr = srb->virt_map[0]; 1032 1033 sgp += srb->sg_count - 1; 1033 1034 1034 1035 /* ··· 1975 1976 int segment = cmd->use_sg; 1976 1977 u32 xferred = srb->total_xfer_length - left; /* bytes transfered */ 1977 1978 struct SGentry *psge = srb->segment_x + srb->sg_index; 1978 - void **virt = srb->virt_map; 1979 1979 1980 1980 dprintkdbg(DBG_0, 1981 1981 "sg_update_list: Transfered %i of %i bytes, %i remain\n", ··· 2014 2016 2015 2017 /* We have to walk the scatterlist to find it */ 2016 2018 sg = (struct scatterlist *)cmd->request_buffer; 2017 - idx = 0; 2018 2019 while (segment--) { 2019 2020 unsigned long mask = 2020 2021 ~((unsigned long)sg->length - 1) & PAGE_MASK; 2021 2022 if ((sg_dma_address(sg) & mask) == (psge->address & mask)) { 2022 - srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK); 2023 + srb->virt_addr = (page_address(sg->page) 2024 + + psge->address - 2025 + (psge->address & PAGE_MASK)); 2023 2026 return; 2024 2027 } 2025 2028 ++sg; 2026 - ++idx; 2027 2029 } 2028 2030 2029 2031 dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n"); ··· 2149 2151 DC395x_read32(acb, TRM_S1040_DMA_CXCNT)); 2150 2152 } 2151 2153 /* 2152 - * calculate all the residue data that not yet transfered 2154 + * calculate all the residue data that not yet tranfered 2153 2155 * SCSI transfer counter + left in SCSI FIFO data 2154 2156 * 2155 2157 * .....TRM_S1040_SCSI_COUNTER (24bits) ··· 3267 3269 struct scsi_cmnd *cmd = srb->cmd; 3268 3270 enum dma_data_direction dir = cmd->sc_data_direction; 3269 3271 if (cmd->use_sg && dir != PCI_DMA_NONE) { 3270 - int i; 3271 3272 /* unmap DC395x SG list */ 3272 3273 dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n", 3273 3274 srb->sg_bus_addr, SEGMENTX_LEN); ··· 3276 3279 dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n", 3277 3280 cmd->use_sg, cmd->request_buffer); 3278 3281 /* unmap the sg segments */ 3279 - for (i = 0; i < srb->sg_count; i++) 3280 - kunmap(virt_to_page(srb->virt_map[i])); 3281 3282 pci_unmap_sg(acb->dev, 3282 3283 (struct scatterlist *)cmd->request_buffer, 3283 3284 cmd->use_sg, dir); ··· 3322 3327 3323 3328 if (cmd->use_sg) { 3324 3329 struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer; 3325 - ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset); 3330 + ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset); 3326 3331 } else { 3327 3332 ptr = (struct ScsiInqData *)(cmd->request_buffer); 3328 3333 } ··· 4257 4262 const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN; 4258 4263 4259 4264 for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page) 4260 - kfree(acb->srb_array[i].segment_x); 4261 - 4262 - vfree(acb->srb_array[0].virt_map); 4265 + if (acb->srb_array[i].segment_x) 4266 + kfree(acb->srb_array[i].segment_x); 4263 4267 } 4264 4268 4265 4269 ··· 4274 4280 int srb_idx = 0; 4275 4281 unsigned i = 0; 4276 4282 struct SGentry *ptr; 4277 - void **virt_array; 4278 4283 4279 - for (i = 0; i < DC395x_MAX_SRB_CNT; i++) { 4284 + for (i = 0; i < DC395x_MAX_SRB_CNT; i++) 4280 4285 acb->srb_array[i].segment_x = NULL; 4281 - acb->srb_array[i].virt_map = NULL; 4282 - } 4283 4286 4284 4287 dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages); 4285 4288 while (pages--) { ··· 4297 4306 ptr + (i * DC395x_MAX_SG_LISTENTRY); 4298 4307 else 4299 4308 dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n"); 4300 - 4301 - virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*)); 4302 - 4303 - if (!virt_array) { 4304 - adapter_sg_tables_free(acb); 4305 - return 1; 4306 - } 4307 - 4308 - for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) { 4309 - acb->srb_array[i].virt_map = virt_array; 4310 - virt_array += DC395x_MAX_SG_LISTENTRY; 4311 - } 4312 - 4313 4309 return 0; 4314 4310 } 4315 4311