diff options
author | Nick Piggin <npiggin@suse.de> | 2008-02-07 21:46:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 22:09:22 -0500 |
commit | a13ff0bb3feda8b1fcffc69951320277ed7c4101 (patch) | |
tree | e9f1179086614b5c435d7a81e19f99746da17214 /drivers/scsi/sg.c | |
parent | c00f08d705e149fbfaf7a252b4d4fbb7affdcc96 (diff) |
Convert SG from nopage to fault.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Douglas Gilbert <dougg@torque.net>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index aba28f335b88..e5156aa6dd20 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1160,23 +1160,22 @@ sg_fasync(int fd, struct file *filp, int mode) | |||
1160 | return (retval < 0) ? retval : 0; | 1160 | return (retval < 0) ? retval : 0; |
1161 | } | 1161 | } |
1162 | 1162 | ||
1163 | static struct page * | 1163 | static int |
1164 | sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) | 1164 | sg_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
1165 | { | 1165 | { |
1166 | Sg_fd *sfp; | 1166 | Sg_fd *sfp; |
1167 | struct page *page = NOPAGE_SIGBUS; | ||
1168 | unsigned long offset, len, sa; | 1167 | unsigned long offset, len, sa; |
1169 | Sg_scatter_hold *rsv_schp; | 1168 | Sg_scatter_hold *rsv_schp; |
1170 | struct scatterlist *sg; | 1169 | struct scatterlist *sg; |
1171 | int k; | 1170 | int k; |
1172 | 1171 | ||
1173 | if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data))) | 1172 | if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data))) |
1174 | return page; | 1173 | return VM_FAULT_SIGBUS; |
1175 | rsv_schp = &sfp->reserve; | 1174 | rsv_schp = &sfp->reserve; |
1176 | offset = addr - vma->vm_start; | 1175 | offset = vmf->pgoff << PAGE_SHIFT; |
1177 | if (offset >= rsv_schp->bufflen) | 1176 | if (offset >= rsv_schp->bufflen) |
1178 | return page; | 1177 | return VM_FAULT_SIGBUS; |
1179 | SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n", | 1178 | SCSI_LOG_TIMEOUT(3, printk("sg_vma_fault: offset=%lu, scatg=%d\n", |
1180 | offset, rsv_schp->k_use_sg)); | 1179 | offset, rsv_schp->k_use_sg)); |
1181 | sg = rsv_schp->buffer; | 1180 | sg = rsv_schp->buffer; |
1182 | sa = vma->vm_start; | 1181 | sa = vma->vm_start; |
@@ -1185,21 +1184,21 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) | |||
1185 | len = vma->vm_end - sa; | 1184 | len = vma->vm_end - sa; |
1186 | len = (len < sg->length) ? len : sg->length; | 1185 | len = (len < sg->length) ? len : sg->length; |
1187 | if (offset < len) { | 1186 | if (offset < len) { |
1187 | struct page *page; | ||
1188 | page = virt_to_page(page_address(sg_page(sg)) + offset); | 1188 | page = virt_to_page(page_address(sg_page(sg)) + offset); |
1189 | get_page(page); /* increment page count */ | 1189 | get_page(page); /* increment page count */ |
1190 | break; | 1190 | vmf->page = page; |
1191 | return 0; /* success */ | ||
1191 | } | 1192 | } |
1192 | sa += len; | 1193 | sa += len; |
1193 | offset -= len; | 1194 | offset -= len; |
1194 | } | 1195 | } |
1195 | 1196 | ||
1196 | if (type) | 1197 | return VM_FAULT_SIGBUS; |
1197 | *type = VM_FAULT_MINOR; | ||
1198 | return page; | ||
1199 | } | 1198 | } |
1200 | 1199 | ||
1201 | static struct vm_operations_struct sg_mmap_vm_ops = { | 1200 | static struct vm_operations_struct sg_mmap_vm_ops = { |
1202 | .nopage = sg_vma_nopage, | 1201 | .fault = sg_vma_fault, |
1203 | }; | 1202 | }; |
1204 | 1203 | ||
1205 | static int | 1204 | static int |