diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 16:15:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-14 16:15:14 -0400 |
commit | dddec01eb8e2b56267b37a6f9f0997a64b4e0b2a (patch) | |
tree | b6d8bfbce9abd105384b9d116499afbe306b9c22 /drivers/scsi | |
parent | 7daf705f362e349983e92037a198b8821db198af (diff) | |
parent | 32502b8413a77b54b9e19809404109590c32dfb7 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: (37 commits)
splice: fix generic_file_splice_read() race with page invalidation
ramfs: enable splice write
drivers/block/pktcdvd.c: avoid useless memset
cdrom: revert commit 22a9189 (cdrom: use kmalloced buffers instead of buffers on stack)
scsi: sr avoids useless buffer allocation
block: blk_rq_map_kern uses the bounce buffers for stack buffers
block: add blk_queue_update_dma_pad
DAC960: push down BKL
pktcdvd: push BKL down into driver
paride: push ioctl down into driver
block: use get_unaligned_* helpers
block: extend queue_flag bitops
block: request_module(): use format string
Add bvec_merge_data to handle stacked devices and ->merge_bvec()
block: integrity flags can't use bit ops on unsigned short
cmdfilter: extend default read filter
sg: fix odd style (extra parenthesis) introduced by cmd filter patch
block: add bounce support to blk_rq_map_user_iov
cfq-iosched: get rid of enable_idle being unused warning
allow userspace to modify scsi command filter on per device basis
...
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sg.c | 44 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 20 |
2 files changed, 15 insertions, 49 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ea0edd1b2e76..fe694f0ee19a 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -182,8 +182,9 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, | |||
182 | int tablesize); | 182 | int tablesize); |
183 | static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, | 183 | static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, |
184 | Sg_request * srp); | 184 | Sg_request * srp); |
185 | static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | 185 | static ssize_t sg_new_write(Sg_fd *sfp, struct file *file, |
186 | int blocking, int read_only, Sg_request ** o_srp); | 186 | const char __user *buf, size_t count, int blocking, |
187 | int read_only, Sg_request **o_srp); | ||
187 | static int sg_common_write(Sg_fd * sfp, Sg_request * srp, | 188 | static int sg_common_write(Sg_fd * sfp, Sg_request * srp, |
188 | unsigned char *cmnd, int timeout, int blocking); | 189 | unsigned char *cmnd, int timeout, int blocking); |
189 | static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, | 190 | static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, |
@@ -204,7 +205,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); | |||
204 | static Sg_request *sg_add_request(Sg_fd * sfp); | 205 | static Sg_request *sg_add_request(Sg_fd * sfp); |
205 | static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); | 206 | static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); |
206 | static int sg_res_in_use(Sg_fd * sfp); | 207 | static int sg_res_in_use(Sg_fd * sfp); |
207 | static int sg_allow_access(unsigned char opcode, char dev_type); | ||
208 | static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); | 208 | static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); |
209 | static Sg_device *sg_get_dev(int dev); | 209 | static Sg_device *sg_get_dev(int dev); |
210 | #ifdef CONFIG_SCSI_PROC_FS | 210 | #ifdef CONFIG_SCSI_PROC_FS |
@@ -544,7 +544,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
544 | return -EFAULT; | 544 | return -EFAULT; |
545 | blocking = !(filp->f_flags & O_NONBLOCK); | 545 | blocking = !(filp->f_flags & O_NONBLOCK); |
546 | if (old_hdr.reply_len < 0) | 546 | if (old_hdr.reply_len < 0) |
547 | return sg_new_write(sfp, buf, count, blocking, 0, NULL); | 547 | return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL); |
548 | if (count < (SZ_SG_HEADER + 6)) | 548 | if (count < (SZ_SG_HEADER + 6)) |
549 | return -EIO; /* The minimum scsi command length is 6 bytes. */ | 549 | return -EIO; /* The minimum scsi command length is 6 bytes. */ |
550 | 550 | ||
@@ -621,8 +621,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
621 | } | 621 | } |
622 | 622 | ||
623 | static ssize_t | 623 | static ssize_t |
624 | sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | 624 | sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, |
625 | int blocking, int read_only, Sg_request ** o_srp) | 625 | size_t count, int blocking, int read_only, |
626 | Sg_request **o_srp) | ||
626 | { | 627 | { |
627 | int k; | 628 | int k; |
628 | Sg_request *srp; | 629 | Sg_request *srp; |
@@ -678,8 +679,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | |||
678 | sg_remove_request(sfp, srp); | 679 | sg_remove_request(sfp, srp); |
679 | return -EFAULT; | 680 | return -EFAULT; |
680 | } | 681 | } |
681 | if (read_only && | 682 | if (read_only && !blk_verify_command(file, cmnd)) { |
682 | (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) { | ||
683 | sg_remove_request(sfp, srp); | 683 | sg_remove_request(sfp, srp); |
684 | return -EPERM; | 684 | return -EPERM; |
685 | } | 685 | } |
@@ -799,7 +799,7 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
799 | if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) | 799 | if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) |
800 | return -EFAULT; | 800 | return -EFAULT; |
801 | result = | 801 | result = |
802 | sg_new_write(sfp, p, SZ_SG_IO_HDR, | 802 | sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, |
803 | blocking, read_only, &srp); | 803 | blocking, read_only, &srp); |
804 | if (result < 0) | 804 | if (result < 0) |
805 | return result; | 805 | return result; |
@@ -1048,7 +1048,7 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
1048 | 1048 | ||
1049 | if (copy_from_user(&opcode, siocp->data, 1)) | 1049 | if (copy_from_user(&opcode, siocp->data, 1)) |
1050 | return -EFAULT; | 1050 | return -EFAULT; |
1051 | if (!sg_allow_access(opcode, sdp->device->type)) | 1051 | if (!blk_verify_command(filp, &opcode)) |
1052 | return -EPERM; | 1052 | return -EPERM; |
1053 | } | 1053 | } |
1054 | return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); | 1054 | return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); |
@@ -2502,30 +2502,6 @@ sg_page_free(struct page *page, int size) | |||
2502 | __free_pages(page, order); | 2502 | __free_pages(page, order); |
2503 | } | 2503 | } |
2504 | 2504 | ||
2505 | #ifndef MAINTENANCE_IN_CMD | ||
2506 | #define MAINTENANCE_IN_CMD 0xa3 | ||
2507 | #endif | ||
2508 | |||
2509 | static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE, | ||
2510 | INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12, | ||
2511 | READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS, | ||
2512 | SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD | ||
2513 | }; | ||
2514 | |||
2515 | static int | ||
2516 | sg_allow_access(unsigned char opcode, char dev_type) | ||
2517 | { | ||
2518 | int k; | ||
2519 | |||
2520 | if (TYPE_SCANNER == dev_type) /* TYPE_ROM maybe burner */ | ||
2521 | return 1; | ||
2522 | for (k = 0; k < sizeof (allow_ops); ++k) { | ||
2523 | if (opcode == allow_ops[k]) | ||
2524 | return 1; | ||
2525 | } | ||
2526 | return 0; | ||
2527 | } | ||
2528 | |||
2529 | #ifdef CONFIG_SCSI_PROC_FS | 2505 | #ifdef CONFIG_SCSI_PROC_FS |
2530 | static int | 2506 | static int |
2531 | sg_idr_max_id(int id, void *p, void *data) | 2507 | sg_idr_max_id(int id, void *p, void *data) |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c82df8bd4d89..27f5bfd1def3 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -673,24 +673,20 @@ fail: | |||
673 | static void get_sectorsize(struct scsi_cd *cd) | 673 | static void get_sectorsize(struct scsi_cd *cd) |
674 | { | 674 | { |
675 | unsigned char cmd[10]; | 675 | unsigned char cmd[10]; |
676 | unsigned char *buffer; | 676 | unsigned char buffer[8]; |
677 | int the_result, retries = 3; | 677 | int the_result, retries = 3; |
678 | int sector_size; | 678 | int sector_size; |
679 | struct request_queue *queue; | 679 | struct request_queue *queue; |
680 | 680 | ||
681 | buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); | ||
682 | if (!buffer) | ||
683 | goto Enomem; | ||
684 | |||
685 | do { | 681 | do { |
686 | cmd[0] = READ_CAPACITY; | 682 | cmd[0] = READ_CAPACITY; |
687 | memset((void *) &cmd[1], 0, 9); | 683 | memset((void *) &cmd[1], 0, 9); |
688 | memset(buffer, 0, 8); | 684 | memset(buffer, 0, sizeof(buffer)); |
689 | 685 | ||
690 | /* Do the command and wait.. */ | 686 | /* Do the command and wait.. */ |
691 | the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, | 687 | the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, |
692 | buffer, 8, NULL, SR_TIMEOUT, | 688 | buffer, sizeof(buffer), NULL, |
693 | MAX_RETRIES); | 689 | SR_TIMEOUT, MAX_RETRIES); |
694 | 690 | ||
695 | retries--; | 691 | retries--; |
696 | 692 | ||
@@ -745,14 +741,8 @@ static void get_sectorsize(struct scsi_cd *cd) | |||
745 | 741 | ||
746 | queue = cd->device->request_queue; | 742 | queue = cd->device->request_queue; |
747 | blk_queue_hardsect_size(queue, sector_size); | 743 | blk_queue_hardsect_size(queue, sector_size); |
748 | out: | ||
749 | kfree(buffer); | ||
750 | return; | ||
751 | 744 | ||
752 | Enomem: | 745 | return; |
753 | cd->capacity = 0x1fffff; | ||
754 | cd->device->sector_size = 2048; /* A guess, just in case */ | ||
755 | goto out; | ||
756 | } | 746 | } |
757 | 747 | ||
758 | static void get_capabilities(struct scsi_cd *cd) | 748 | static void get_capabilities(struct scsi_cd *cd) |