diff options
| -rw-r--r-- | Documentation/cdrom/cdrom-standard.tex | 2 | ||||
| -rw-r--r-- | block/Kconfig | 65 | ||||
| -rw-r--r-- | block/blk-map.c | 46 | ||||
| -rw-r--r-- | block/blk-merge.c | 9 | ||||
| -rw-r--r-- | block/blk-sysfs.c | 10 | ||||
| -rw-r--r-- | drivers/block/cciss.c | 17 | ||||
| -rw-r--r-- | drivers/block/cciss_scsi.c | 2 | ||||
| -rw-r--r-- | drivers/block/loop.c | 26 | ||||
| -rw-r--r-- | drivers/block/sx8.c | 6 | ||||
| -rw-r--r-- | drivers/cdrom/cdrom.c | 328 | ||||
| -rw-r--r-- | drivers/cdrom/gdrom.c | 4 | ||||
| -rw-r--r-- | drivers/cdrom/viocd.c | 5 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.c | 5 | ||||
| -rw-r--r-- | drivers/scsi/scsi.c | 2 | ||||
| -rw-r--r-- | fs/bio.c | 158 | ||||
| -rw-r--r-- | include/linux/bio.h | 2 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 9 | ||||
| -rw-r--r-- | include/linux/cdrom.h | 5 |
18 files changed, 462 insertions, 239 deletions
diff --git a/Documentation/cdrom/cdrom-standard.tex b/Documentation/cdrom/cdrom-standard.tex index c713aeb020c4..c06233fe52ac 100644 --- a/Documentation/cdrom/cdrom-standard.tex +++ b/Documentation/cdrom/cdrom-standard.tex | |||
| @@ -777,7 +777,7 @@ Note that a driver must have one static structure, $<device>_dops$, while | |||
| 777 | it may have as many structures $<device>_info$ as there are minor devices | 777 | it may have as many structures $<device>_info$ as there are minor devices |
| 778 | active. $Register_cdrom()$ builds a linked list from these. | 778 | active. $Register_cdrom()$ builds a linked list from these. |
| 779 | 779 | ||
| 780 | \subsection{$Int\ unregister_cdrom(struct\ cdrom_device_info * cdi)$} | 780 | \subsection{$Void\ unregister_cdrom(struct\ cdrom_device_info * cdi)$} |
| 781 | 781 | ||
| 782 | Unregistering device $cdi$ with minor number $MINOR(cdi\to dev)$ removes | 782 | Unregistering device $cdi$ with minor number $MINOR(cdi\to dev)$ removes |
| 783 | the minor device from the list. If it was the last registered minor for | 783 | the minor device from the list. If it was the last registered minor for |
diff --git a/block/Kconfig b/block/Kconfig index 7db9a411649d..3e97f2bc446f 100644 --- a/block/Kconfig +++ b/block/Kconfig | |||
| @@ -5,14 +5,18 @@ menuconfig BLOCK | |||
| 5 | bool "Enable the block layer" if EMBEDDED | 5 | bool "Enable the block layer" if EMBEDDED |
| 6 | default y | 6 | default y |
| 7 | help | 7 | help |
| 8 | This permits the block layer to be removed from the kernel if it's not | 8 | Provide block layer support for the kernel. |
| 9 | needed (on some embedded devices for example). If this option is | ||
| 10 | disabled, then blockdev files will become unusable and some | ||
| 11 | filesystems (such as ext3) will become unavailable. | ||
| 12 | 9 | ||
| 13 | This option will also disable SCSI character devices and USB storage | 10 | Disable this option to remove the block layer support from the |
| 14 | since they make use of various block layer definitions and | 11 | kernel. This may be useful for embedded devices. |
| 15 | facilities. | 12 | |
| 13 | If this option is disabled: | ||
| 14 | |||
| 15 | - block device files will become unusable | ||
| 16 | - some filesystems (such as ext3) will become unavailable. | ||
| 17 | |||
| 18 | Also, SCSI character devices and USB storage will be disabled since | ||
| 19 | they make use of various block layer definitions and facilities. | ||
| 16 | 20 | ||
| 17 | Say Y here unless you know you really don't want to mount disks and | 21 | Say Y here unless you know you really don't want to mount disks and |
| 18 | suchlike. | 22 | suchlike. |
| @@ -23,9 +27,20 @@ config LBD | |||
| 23 | bool "Support for Large Block Devices" | 27 | bool "Support for Large Block Devices" |
| 24 | depends on !64BIT | 28 | depends on !64BIT |
| 25 | help | 29 | help |
| 26 | Say Y here if you want to attach large (bigger than 2TB) discs to | 30 | Enable block devices of size 2TB and larger. |
| 27 | your machine, or if you want to have a raid or loopback device | 31 | |
| 28 | bigger than 2TB. Otherwise say N. | 32 | This option is required to support the full capacity of large |
| 33 | (2TB+) block devices, including RAID, disk, Network Block Device, | ||
| 34 | Logical Volume Manager (LVM) and loopback. | ||
| 35 | |||
| 36 | For example, RAID devices are frequently bigger than the capacity | ||
| 37 | of the largest individual hard drive. | ||
| 38 | |||
| 39 | This option is not required if you have individual disk drives | ||
| 40 | which total 2TB+ and you are not aggregating the capacity into | ||
| 41 | a large block device (e.g. using RAID or LVM). | ||
| 42 | |||
| 43 | If unsure, say N. | ||
| 29 | 44 | ||
| 30 | config BLK_DEV_IO_TRACE | 45 | config BLK_DEV_IO_TRACE |
| 31 | bool "Support for tracing block io actions" | 46 | bool "Support for tracing block io actions" |
| @@ -33,19 +48,21 @@ config BLK_DEV_IO_TRACE | |||
| 33 | select RELAY | 48 | select RELAY |
| 34 | select DEBUG_FS | 49 | select DEBUG_FS |
| 35 | help | 50 | help |
| 36 | Say Y here, if you want to be able to trace the block layer actions | 51 | Say Y here if you want to be able to trace the block layer actions |
| 37 | on a given queue. Tracing allows you to see any traffic happening | 52 | on a given queue. Tracing allows you to see any traffic happening |
| 38 | on a block device queue. For more information (and the user space | 53 | on a block device queue. For more information (and the userspace |
| 39 | support tools needed), fetch the blktrace app from: | 54 | support tools needed), fetch the blktrace tools from: |
| 40 | 55 | ||
| 41 | git://git.kernel.dk/blktrace.git | 56 | git://git.kernel.dk/blktrace.git |
| 42 | 57 | ||
| 58 | If unsure, say N. | ||
| 59 | |||
| 43 | config LSF | 60 | config LSF |
| 44 | bool "Support for Large Single Files" | 61 | bool "Support for Large Single Files" |
| 45 | depends on !64BIT | 62 | depends on !64BIT |
| 46 | help | 63 | help |
| 47 | Say Y here if you want to be able to handle very large files (bigger | 64 | Say Y here if you want to be able to handle very large files (2TB |
| 48 | than 2TB), otherwise say N. | 65 | and larger), otherwise say N. |
| 49 | 66 | ||
| 50 | If unsure, say Y. | 67 | If unsure, say Y. |
| 51 | 68 | ||
| @@ -53,14 +70,16 @@ config BLK_DEV_BSG | |||
| 53 | bool "Block layer SG support v4 (EXPERIMENTAL)" | 70 | bool "Block layer SG support v4 (EXPERIMENTAL)" |
| 54 | depends on EXPERIMENTAL | 71 | depends on EXPERIMENTAL |
| 55 | ---help--- | 72 | ---help--- |
| 56 | Saying Y here will enable generic SG (SCSI generic) v4 support | 73 | Saying Y here will enable generic SG (SCSI generic) v4 support |
| 57 | for any block device. | 74 | for any block device. |
| 58 | 75 | ||
| 59 | Unlike SG v3 (aka block/scsi_ioctl.c drivers/scsi/sg.c), SG v4 | 76 | Unlike SG v3 (aka block/scsi_ioctl.c drivers/scsi/sg.c), SG v4 |
| 60 | can handle complicated SCSI commands: tagged variable length cdbs | 77 | can handle complicated SCSI commands: tagged variable length cdbs |
| 61 | with bidirectional data transfers and generic request/response | 78 | with bidirectional data transfers and generic request/response |
| 62 | protocols (e.g. Task Management Functions and SMP in Serial | 79 | protocols (e.g. Task Management Functions and SMP in Serial |
| 63 | Attached SCSI). | 80 | Attached SCSI). |
| 81 | |||
| 82 | If unsure, say N. | ||
| 64 | 83 | ||
| 65 | endif # BLOCK | 84 | endif # BLOCK |
| 66 | 85 | ||
diff --git a/block/blk-map.c b/block/blk-map.c index c07d9c8317f4..3c942bd6422a 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| 6 | #include <linux/bio.h> | 6 | #include <linux/bio.h> |
| 7 | #include <linux/blkdev.h> | 7 | #include <linux/blkdev.h> |
| 8 | #include <scsi/sg.h> /* for struct sg_iovec */ | ||
| 8 | 9 | ||
| 9 | #include "blk.h" | 10 | #include "blk.h" |
| 10 | 11 | ||
| @@ -140,25 +141,8 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, | |||
| 140 | ubuf += ret; | 141 | ubuf += ret; |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | /* | 144 | if (!bio_flagged(bio, BIO_USER_MAPPED)) |
| 144 | * __blk_rq_map_user() copies the buffers if starting address | 145 | rq->cmd_flags |= REQ_COPY_USER; |
| 145 | * or length isn't aligned to dma_pad_mask. As the copied | ||
| 146 | * buffer is always page aligned, we know that there's enough | ||
| 147 | * room for padding. Extend the last bio and update | ||
| 148 | * rq->data_len accordingly. | ||
| 149 | * | ||
| 150 | * On unmap, bio_uncopy_user() will use unmodified | ||
| 151 | * bio_map_data pointed to by bio->bi_private. | ||
| 152 | */ | ||
| 153 | if (len & q->dma_pad_mask) { | ||
| 154 | unsigned int pad_len = (q->dma_pad_mask & ~len) + 1; | ||
| 155 | struct bio *tail = rq->biotail; | ||
| 156 | |||
| 157 | tail->bi_io_vec[tail->bi_vcnt - 1].bv_len += pad_len; | ||
| 158 | tail->bi_size += pad_len; | ||
| 159 | |||
| 160 | rq->extra_len += pad_len; | ||
| 161 | } | ||
| 162 | 146 | ||
| 163 | rq->buffer = rq->data = NULL; | 147 | rq->buffer = rq->data = NULL; |
| 164 | return 0; | 148 | return 0; |
| @@ -194,15 +178,26 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, | |||
| 194 | struct sg_iovec *iov, int iov_count, unsigned int len) | 178 | struct sg_iovec *iov, int iov_count, unsigned int len) |
| 195 | { | 179 | { |
| 196 | struct bio *bio; | 180 | struct bio *bio; |
| 181 | int i, read = rq_data_dir(rq) == READ; | ||
| 182 | int unaligned = 0; | ||
| 197 | 183 | ||
| 198 | if (!iov || iov_count <= 0) | 184 | if (!iov || iov_count <= 0) |
| 199 | return -EINVAL; | 185 | return -EINVAL; |
| 200 | 186 | ||
| 201 | /* we don't allow misaligned data like bio_map_user() does. If the | 187 | for (i = 0; i < iov_count; i++) { |
| 202 | * user is using sg, they're expected to know the alignment constraints | 188 | unsigned long uaddr = (unsigned long)iov[i].iov_base; |
| 203 | * and respect them accordingly */ | 189 | |
| 204 | bio = bio_map_user_iov(q, NULL, iov, iov_count, | 190 | if (uaddr & queue_dma_alignment(q)) { |
| 205 | rq_data_dir(rq) == READ); | 191 | unaligned = 1; |
| 192 | break; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | if (unaligned || (q->dma_pad_mask & len)) | ||
| 197 | bio = bio_copy_user_iov(q, iov, iov_count, read); | ||
| 198 | else | ||
| 199 | bio = bio_map_user_iov(q, NULL, iov, iov_count, read); | ||
| 200 | |||
| 206 | if (IS_ERR(bio)) | 201 | if (IS_ERR(bio)) |
| 207 | return PTR_ERR(bio); | 202 | return PTR_ERR(bio); |
| 208 | 203 | ||
| @@ -212,6 +207,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, | |||
| 212 | return -EINVAL; | 207 | return -EINVAL; |
| 213 | } | 208 | } |
| 214 | 209 | ||
| 210 | if (!bio_flagged(bio, BIO_USER_MAPPED)) | ||
| 211 | rq->cmd_flags |= REQ_COPY_USER; | ||
| 212 | |||
| 215 | bio_get(bio); | 213 | bio_get(bio); |
| 216 | blk_rq_bio_prep(q, rq, bio); | 214 | blk_rq_bio_prep(q, rq, bio); |
| 217 | rq->buffer = rq->data = NULL; | 215 | rq->buffer = rq->data = NULL; |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 0f58616bcd7f..b5c5c4a9e3f0 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
| @@ -220,6 +220,15 @@ new_segment: | |||
| 220 | bvprv = bvec; | 220 | bvprv = bvec; |
| 221 | } /* segments in rq */ | 221 | } /* segments in rq */ |
| 222 | 222 | ||
| 223 | |||
| 224 | if (unlikely(rq->cmd_flags & REQ_COPY_USER) && | ||
| 225 | (rq->data_len & q->dma_pad_mask)) { | ||
| 226 | unsigned int pad_len = (q->dma_pad_mask & ~rq->data_len) + 1; | ||
| 227 | |||
| 228 | sg->length += pad_len; | ||
| 229 | rq->extra_len += pad_len; | ||
| 230 | } | ||
| 231 | |||
| 223 | if (q->dma_drain_size && q->dma_drain_needed(rq)) { | 232 | if (q->dma_drain_size && q->dma_drain_needed(rq)) { |
| 224 | if (rq->cmd_flags & REQ_RW) | 233 | if (rq->cmd_flags & REQ_RW) |
| 225 | memset(q->dma_drain_buffer, 0, q->dma_drain_size); | 234 | memset(q->dma_drain_buffer, 0, q->dma_drain_size); |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 54d0db116153..fc41d83be22b 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
| @@ -276,9 +276,12 @@ int blk_register_queue(struct gendisk *disk) | |||
| 276 | 276 | ||
| 277 | struct request_queue *q = disk->queue; | 277 | struct request_queue *q = disk->queue; |
| 278 | 278 | ||
| 279 | if (!q || !q->request_fn) | 279 | if (WARN_ON(!q)) |
| 280 | return -ENXIO; | 280 | return -ENXIO; |
| 281 | 281 | ||
| 282 | if (!q->request_fn) | ||
| 283 | return 0; | ||
| 284 | |||
| 282 | ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj), | 285 | ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj), |
| 283 | "%s", "queue"); | 286 | "%s", "queue"); |
| 284 | if (ret < 0) | 287 | if (ret < 0) |
| @@ -300,7 +303,10 @@ void blk_unregister_queue(struct gendisk *disk) | |||
| 300 | { | 303 | { |
| 301 | struct request_queue *q = disk->queue; | 304 | struct request_queue *q = disk->queue; |
| 302 | 305 | ||
| 303 | if (q && q->request_fn) { | 306 | if (WARN_ON(!q)) |
| 307 | return; | ||
| 308 | |||
| 309 | if (q->request_fn) { | ||
| 304 | elv_unregister_queue(q); | 310 | elv_unregister_queue(q); |
| 305 | 311 | ||
| 306 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 312 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 9c9627e8e334..cf6083a1f928 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -1349,6 +1349,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1349 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1349 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1350 | h->drv[drv_index].busy_configuring = 1; | 1350 | h->drv[drv_index].busy_configuring = 1; |
| 1351 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1351 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
| 1352 | |||
| 1353 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | ||
| 1354 | /* which keeps the interrupt handler from starting */ | ||
| 1355 | /* the queue. */ | ||
| 1352 | ret = deregister_disk(h->gendisk[drv_index], | 1356 | ret = deregister_disk(h->gendisk[drv_index], |
| 1353 | &h->drv[drv_index], 0); | 1357 | &h->drv[drv_index], 0); |
| 1354 | h->drv[drv_index].busy_configuring = 0; | 1358 | h->drv[drv_index].busy_configuring = 0; |
| @@ -1419,6 +1423,10 @@ geo_inq: | |||
| 1419 | blk_queue_hardsect_size(disk->queue, | 1423 | blk_queue_hardsect_size(disk->queue, |
| 1420 | hba[ctlr]->drv[drv_index].block_size); | 1424 | hba[ctlr]->drv[drv_index].block_size); |
| 1421 | 1425 | ||
| 1426 | /* Make sure all queue data is written out before */ | ||
| 1427 | /* setting h->drv[drv_index].queue, as setting this */ | ||
| 1428 | /* allows the interrupt handler to start the queue */ | ||
| 1429 | wmb(); | ||
| 1422 | h->drv[drv_index].queue = disk->queue; | 1430 | h->drv[drv_index].queue = disk->queue; |
| 1423 | add_disk(disk); | 1431 | add_disk(disk); |
| 1424 | } | 1432 | } |
| @@ -3520,10 +3528,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3520 | continue; | 3528 | continue; |
| 3521 | blk_queue_hardsect_size(q, drv->block_size); | 3529 | blk_queue_hardsect_size(q, drv->block_size); |
| 3522 | set_capacity(disk, drv->nr_blocks); | 3530 | set_capacity(disk, drv->nr_blocks); |
| 3523 | add_disk(disk); | ||
| 3524 | j++; | 3531 | j++; |
| 3525 | } while (j <= hba[i]->highest_lun); | 3532 | } while (j <= hba[i]->highest_lun); |
| 3526 | 3533 | ||
| 3534 | /* Make sure all queue data is written out before */ | ||
| 3535 | /* interrupt handler, triggered by add_disk, */ | ||
| 3536 | /* is allowed to start them. */ | ||
| 3537 | wmb(); | ||
| 3538 | |||
| 3539 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
| 3540 | add_disk(hba[i]->gendisk[j]); | ||
| 3541 | |||
| 3527 | return 1; | 3542 | return 1; |
| 3528 | 3543 | ||
| 3529 | clean4: | 3544 | clean4: |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 45ac09300eb3..e4bf9a11ca0d 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
| @@ -1349,9 +1349,9 @@ cciss_unregister_scsi(int ctlr) | |||
| 1349 | /* set scsi_host to NULL so our detect routine will | 1349 | /* set scsi_host to NULL so our detect routine will |
| 1350 | find us on register */ | 1350 | find us on register */ |
| 1351 | sa->scsi_host = NULL; | 1351 | sa->scsi_host = NULL; |
| 1352 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
| 1352 | scsi_cmd_stack_free(ctlr); | 1353 | scsi_cmd_stack_free(ctlr); |
| 1353 | kfree(sa); | 1354 | kfree(sa); |
| 1354 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
| 1355 | } | 1355 | } |
| 1356 | 1356 | ||
| 1357 | static int | 1357 | static int |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 91ebb007416c..f7f163557aa0 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -82,6 +82,9 @@ | |||
| 82 | static LIST_HEAD(loop_devices); | 82 | static LIST_HEAD(loop_devices); |
| 83 | static DEFINE_MUTEX(loop_devices_mutex); | 83 | static DEFINE_MUTEX(loop_devices_mutex); |
| 84 | 84 | ||
| 85 | static int max_part; | ||
| 86 | static int part_shift; | ||
| 87 | |||
| 85 | /* | 88 | /* |
| 86 | * Transfer functions | 89 | * Transfer functions |
| 87 | */ | 90 | */ |
| @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file, | |||
| 692 | goto out_putf; | 695 | goto out_putf; |
| 693 | 696 | ||
| 694 | fput(old_file); | 697 | fput(old_file); |
| 698 | if (max_part > 0) | ||
| 699 | ioctl_by_bdev(bdev, BLKRRPART, 0); | ||
| 695 | return 0; | 700 | return 0; |
| 696 | 701 | ||
| 697 | out_putf: | 702 | out_putf: |
| @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
| 819 | } | 824 | } |
| 820 | lo->lo_state = Lo_bound; | 825 | lo->lo_state = Lo_bound; |
| 821 | wake_up_process(lo->lo_thread); | 826 | wake_up_process(lo->lo_thread); |
| 827 | if (max_part > 0) | ||
| 828 | ioctl_by_bdev(bdev, BLKRRPART, 0); | ||
| 822 | return 0; | 829 | return 0; |
| 823 | 830 | ||
| 824 | out_clr: | 831 | out_clr: |
| @@ -919,6 +926,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
| 919 | fput(filp); | 926 | fput(filp); |
| 920 | /* This is safe: open() is still holding a reference. */ | 927 | /* This is safe: open() is still holding a reference. */ |
| 921 | module_put(THIS_MODULE); | 928 | module_put(THIS_MODULE); |
| 929 | if (max_part > 0) | ||
| 930 | ioctl_by_bdev(bdev, BLKRRPART, 0); | ||
| 922 | return 0; | 931 | return 0; |
| 923 | } | 932 | } |
| 924 | 933 | ||
| @@ -1360,6 +1369,8 @@ static struct block_device_operations lo_fops = { | |||
| 1360 | static int max_loop; | 1369 | static int max_loop; |
| 1361 | module_param(max_loop, int, 0); | 1370 | module_param(max_loop, int, 0); |
| 1362 | MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); | 1371 | MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); |
| 1372 | module_param(max_part, int, 0); | ||
| 1373 | MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device"); | ||
| 1363 | MODULE_LICENSE("GPL"); | 1374 | MODULE_LICENSE("GPL"); |
| 1364 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); | 1375 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); |
| 1365 | 1376 | ||
| @@ -1412,7 +1423,7 @@ static struct loop_device *loop_alloc(int i) | |||
| 1412 | if (!lo->lo_queue) | 1423 | if (!lo->lo_queue) |
| 1413 | goto out_free_dev; | 1424 | goto out_free_dev; |
| 1414 | 1425 | ||
| 1415 | disk = lo->lo_disk = alloc_disk(1); | 1426 | disk = lo->lo_disk = alloc_disk(1 << part_shift); |
| 1416 | if (!disk) | 1427 | if (!disk) |
| 1417 | goto out_free_queue; | 1428 | goto out_free_queue; |
| 1418 | 1429 | ||
| @@ -1422,7 +1433,7 @@ static struct loop_device *loop_alloc(int i) | |||
| 1422 | init_waitqueue_head(&lo->lo_event); | 1433 | init_waitqueue_head(&lo->lo_event); |
| 1423 | spin_lock_init(&lo->lo_lock); | 1434 | spin_lock_init(&lo->lo_lock); |
| 1424 | disk->major = LOOP_MAJOR; | 1435 | disk->major = LOOP_MAJOR; |
| 1425 | disk->first_minor = i; | 1436 | disk->first_minor = i << part_shift; |
| 1426 | disk->fops = &lo_fops; | 1437 | disk->fops = &lo_fops; |
| 1427 | disk->private_data = lo; | 1438 | disk->private_data = lo; |
| 1428 | disk->queue = lo->lo_queue; | 1439 | disk->queue = lo->lo_queue; |
| @@ -1502,7 +1513,12 @@ static int __init loop_init(void) | |||
| 1502 | * themselves and have kernel automatically instantiate actual | 1513 | * themselves and have kernel automatically instantiate actual |
| 1503 | * device on-demand. | 1514 | * device on-demand. |
| 1504 | */ | 1515 | */ |
| 1505 | if (max_loop > 1UL << MINORBITS) | 1516 | |
| 1517 | part_shift = 0; | ||
| 1518 | if (max_part > 0) | ||
| 1519 | part_shift = fls(max_part); | ||
| 1520 | |||
| 1521 | if (max_loop > 1UL << (MINORBITS - part_shift)) | ||
| 1506 | return -EINVAL; | 1522 | return -EINVAL; |
| 1507 | 1523 | ||
| 1508 | if (max_loop) { | 1524 | if (max_loop) { |
| @@ -1510,7 +1526,7 @@ static int __init loop_init(void) | |||
| 1510 | range = max_loop; | 1526 | range = max_loop; |
| 1511 | } else { | 1527 | } else { |
| 1512 | nr = 8; | 1528 | nr = 8; |
| 1513 | range = 1UL << MINORBITS; | 1529 | range = 1UL << (MINORBITS - part_shift); |
| 1514 | } | 1530 | } |
| 1515 | 1531 | ||
| 1516 | if (register_blkdev(LOOP_MAJOR, "loop")) | 1532 | if (register_blkdev(LOOP_MAJOR, "loop")) |
| @@ -1549,7 +1565,7 @@ static void __exit loop_exit(void) | |||
| 1549 | unsigned long range; | 1565 | unsigned long range; |
| 1550 | struct loop_device *lo, *next; | 1566 | struct loop_device *lo, *next; |
| 1551 | 1567 | ||
| 1552 | range = max_loop ? max_loop : 1UL << MINORBITS; | 1568 | range = max_loop ? max_loop : 1UL << (MINORBITS - part_shift); |
| 1553 | 1569 | ||
| 1554 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) | 1570 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) |
| 1555 | loop_del_one(lo); | 1571 | loop_del_one(lo); |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index cd5674b63faf..a18e1ca0f761 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
| @@ -79,9 +79,9 @@ MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30 | |||
| 79 | 79 | ||
| 80 | /* note: prints function name for you */ | 80 | /* note: prints function name for you */ |
| 81 | #ifdef CARM_DEBUG | 81 | #ifdef CARM_DEBUG |
| 82 | #define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) | 82 | #define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) |
| 83 | #ifdef CARM_VERBOSE_DEBUG | 83 | #ifdef CARM_VERBOSE_DEBUG |
| 84 | #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) | 84 | #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) |
| 85 | #else | 85 | #else |
| 86 | #define VPRINTK(fmt, args...) | 86 | #define VPRINTK(fmt, args...) |
| 87 | #endif /* CARM_VERBOSE_DEBUG */ | 87 | #endif /* CARM_VERBOSE_DEBUG */ |
| @@ -96,7 +96,7 @@ MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30 | |||
| 96 | #define assert(expr) \ | 96 | #define assert(expr) \ |
| 97 | if(unlikely(!(expr))) { \ | 97 | if(unlikely(!(expr))) { \ |
| 98 | printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ | 98 | printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \ |
| 99 | #expr,__FILE__,__FUNCTION__,__LINE__); \ | 99 | #expr, __FILE__, __func__, __LINE__); \ |
| 100 | } | 100 | } |
| 101 | #endif | 101 | #endif |
| 102 | 102 | ||
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 12f5baea439b..ac3829030ac5 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
| @@ -360,10 +360,9 @@ static int cdrom_mrw_exit(struct cdrom_device_info *cdi); | |||
| 360 | 360 | ||
| 361 | static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di); | 361 | static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di); |
| 362 | 362 | ||
| 363 | #ifdef CONFIG_SYSCTL | ||
| 364 | static void cdrom_sysctl_register(void); | 363 | static void cdrom_sysctl_register(void); |
| 365 | #endif /* CONFIG_SYSCTL */ | 364 | |
| 366 | static struct cdrom_device_info *topCdromPtr; | 365 | static LIST_HEAD(cdrom_list); |
| 367 | 366 | ||
| 368 | static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, | 367 | static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, |
| 369 | struct packet_command *cgc) | 368 | struct packet_command *cgc) |
| @@ -394,13 +393,11 @@ int register_cdrom(struct cdrom_device_info *cdi) | |||
| 394 | cdinfo(CD_OPEN, "entering register_cdrom\n"); | 393 | cdinfo(CD_OPEN, "entering register_cdrom\n"); |
| 395 | 394 | ||
| 396 | if (cdo->open == NULL || cdo->release == NULL) | 395 | if (cdo->open == NULL || cdo->release == NULL) |
| 397 | return -2; | 396 | return -EINVAL; |
| 398 | if (!banner_printed) { | 397 | if (!banner_printed) { |
| 399 | printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n"); | 398 | printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n"); |
| 400 | banner_printed = 1; | 399 | banner_printed = 1; |
| 401 | #ifdef CONFIG_SYSCTL | ||
| 402 | cdrom_sysctl_register(); | 400 | cdrom_sysctl_register(); |
| 403 | #endif /* CONFIG_SYSCTL */ | ||
| 404 | } | 401 | } |
| 405 | 402 | ||
| 406 | ENSURE(drive_status, CDC_DRIVE_STATUS ); | 403 | ENSURE(drive_status, CDC_DRIVE_STATUS ); |
| @@ -439,35 +436,18 @@ int register_cdrom(struct cdrom_device_info *cdi) | |||
| 439 | 436 | ||
| 440 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); | 437 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); |
| 441 | mutex_lock(&cdrom_mutex); | 438 | mutex_lock(&cdrom_mutex); |
| 442 | cdi->next = topCdromPtr; | 439 | list_add(&cdi->list, &cdrom_list); |
| 443 | topCdromPtr = cdi; | ||
| 444 | mutex_unlock(&cdrom_mutex); | 440 | mutex_unlock(&cdrom_mutex); |
| 445 | return 0; | 441 | return 0; |
| 446 | } | 442 | } |
| 447 | #undef ENSURE | 443 | #undef ENSURE |
| 448 | 444 | ||
| 449 | int unregister_cdrom(struct cdrom_device_info *unreg) | 445 | void unregister_cdrom(struct cdrom_device_info *cdi) |
| 450 | { | 446 | { |
| 451 | struct cdrom_device_info *cdi, *prev; | ||
| 452 | cdinfo(CD_OPEN, "entering unregister_cdrom\n"); | 447 | cdinfo(CD_OPEN, "entering unregister_cdrom\n"); |
| 453 | 448 | ||
| 454 | prev = NULL; | ||
| 455 | mutex_lock(&cdrom_mutex); | 449 | mutex_lock(&cdrom_mutex); |
| 456 | cdi = topCdromPtr; | 450 | list_del(&cdi->list); |
| 457 | while (cdi && cdi != unreg) { | ||
| 458 | prev = cdi; | ||
| 459 | cdi = cdi->next; | ||
| 460 | } | ||
| 461 | |||
| 462 | if (cdi == NULL) { | ||
| 463 | mutex_unlock(&cdrom_mutex); | ||
| 464 | return -2; | ||
| 465 | } | ||
| 466 | if (prev) | ||
| 467 | prev->next = cdi->next; | ||
| 468 | else | ||
| 469 | topCdromPtr = cdi->next; | ||
| 470 | |||
| 471 | mutex_unlock(&cdrom_mutex); | 451 | mutex_unlock(&cdrom_mutex); |
| 472 | 452 | ||
| 473 | if (cdi->exit) | 453 | if (cdi->exit) |
| @@ -475,34 +455,43 @@ int unregister_cdrom(struct cdrom_device_info *unreg) | |||
| 475 | 455 | ||
| 476 | cdi->ops->n_minors--; | 456 | cdi->ops->n_minors--; |
| 477 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); | 457 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); |
| 478 | return 0; | ||
| 479 | } | 458 | } |
| 480 | 459 | ||
| 481 | int cdrom_get_media_event(struct cdrom_device_info *cdi, | 460 | int cdrom_get_media_event(struct cdrom_device_info *cdi, |
| 482 | struct media_event_desc *med) | 461 | struct media_event_desc *med) |
| 483 | { | 462 | { |
| 484 | struct packet_command cgc; | 463 | struct packet_command cgc; |
| 485 | unsigned char buffer[8]; | 464 | unsigned char *buffer; |
| 486 | struct event_header *eh = (struct event_header *) buffer; | 465 | struct event_header *eh; |
| 466 | int ret = 1; | ||
| 487 | 467 | ||
| 488 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 468 | buffer = kmalloc(8, GFP_KERNEL); |
| 469 | if (!buffer) | ||
| 470 | return -ENOMEM; | ||
| 471 | |||
| 472 | eh = (struct event_header *)buffer; | ||
| 473 | |||
| 474 | init_cdrom_command(&cgc, buffer, 8, CGC_DATA_READ); | ||
| 489 | cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; | 475 | cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; |
| 490 | cgc.cmd[1] = 1; /* IMMED */ | 476 | cgc.cmd[1] = 1; /* IMMED */ |
| 491 | cgc.cmd[4] = 1 << 4; /* media event */ | 477 | cgc.cmd[4] = 1 << 4; /* media event */ |
| 492 | cgc.cmd[8] = sizeof(buffer); | 478 | cgc.cmd[8] = 8; |
| 493 | cgc.quiet = 1; | 479 | cgc.quiet = 1; |
| 494 | 480 | ||
| 495 | if (cdi->ops->generic_packet(cdi, &cgc)) | 481 | if (cdi->ops->generic_packet(cdi, &cgc)) |
| 496 | return 1; | 482 | goto err; |
| 497 | 483 | ||
| 498 | if (be16_to_cpu(eh->data_len) < sizeof(*med)) | 484 | if (be16_to_cpu(eh->data_len) < sizeof(*med)) |
| 499 | return 1; | 485 | goto err; |
| 500 | 486 | ||
| 501 | if (eh->nea || eh->notification_class != 0x4) | 487 | if (eh->nea || eh->notification_class != 0x4) |
| 502 | return 1; | 488 | goto err; |
| 503 | 489 | ||
| 504 | memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); | 490 | memcpy(med, buffer + sizeof(*eh), sizeof(*med)); |
| 505 | return 0; | 491 | ret = 0; |
| 492 | err: | ||
| 493 | kfree(buffer); | ||
| 494 | return ret; | ||
| 506 | } | 495 | } |
| 507 | 496 | ||
| 508 | /* | 497 | /* |
| @@ -512,68 +501,82 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi, | |||
| 512 | static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) | 501 | static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) |
| 513 | { | 502 | { |
| 514 | struct packet_command cgc; | 503 | struct packet_command cgc; |
| 515 | char buffer[16]; | 504 | char *buffer; |
| 505 | int ret = 1; | ||
| 516 | 506 | ||
| 517 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 507 | buffer = kmalloc(16, GFP_KERNEL); |
| 508 | if (!buffer) | ||
| 509 | return -ENOMEM; | ||
| 510 | |||
| 511 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | ||
| 518 | 512 | ||
| 519 | cgc.timeout = HZ; | 513 | cgc.timeout = HZ; |
| 520 | cgc.quiet = 1; | 514 | cgc.quiet = 1; |
| 521 | 515 | ||
| 522 | if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { | 516 | if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { |
| 523 | cdi->mrw_mode_page = MRW_MODE_PC; | 517 | cdi->mrw_mode_page = MRW_MODE_PC; |
| 524 | return 0; | 518 | ret = 0; |
| 525 | } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { | 519 | } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { |
| 526 | cdi->mrw_mode_page = MRW_MODE_PC_PRE1; | 520 | cdi->mrw_mode_page = MRW_MODE_PC_PRE1; |
| 527 | return 0; | 521 | ret = 0; |
| 528 | } | 522 | } |
| 529 | 523 | kfree(buffer); | |
| 530 | return 1; | 524 | return ret; |
| 531 | } | 525 | } |
| 532 | 526 | ||
| 533 | static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) | 527 | static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) |
| 534 | { | 528 | { |
| 535 | struct packet_command cgc; | 529 | struct packet_command cgc; |
| 536 | struct mrw_feature_desc *mfd; | 530 | struct mrw_feature_desc *mfd; |
| 537 | unsigned char buffer[16]; | 531 | unsigned char *buffer; |
| 538 | int ret; | 532 | int ret; |
| 539 | 533 | ||
| 540 | *write = 0; | 534 | *write = 0; |
| 535 | buffer = kmalloc(16, GFP_KERNEL); | ||
| 536 | if (!buffer) | ||
| 537 | return -ENOMEM; | ||
| 541 | 538 | ||
| 542 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 539 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); |
| 543 | 540 | ||
| 544 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | 541 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
| 545 | cgc.cmd[3] = CDF_MRW; | 542 | cgc.cmd[3] = CDF_MRW; |
| 546 | cgc.cmd[8] = sizeof(buffer); | 543 | cgc.cmd[8] = 16; |
| 547 | cgc.quiet = 1; | 544 | cgc.quiet = 1; |
| 548 | 545 | ||
| 549 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 546 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
| 550 | return ret; | 547 | goto err; |
| 551 | 548 | ||
| 552 | mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; | 549 | mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; |
| 553 | if (be16_to_cpu(mfd->feature_code) != CDF_MRW) | 550 | if (be16_to_cpu(mfd->feature_code) != CDF_MRW) { |
| 554 | return 1; | 551 | ret = 1; |
| 552 | goto err; | ||
| 553 | } | ||
| 555 | *write = mfd->write; | 554 | *write = mfd->write; |
| 556 | 555 | ||
| 557 | if ((ret = cdrom_mrw_probe_pc(cdi))) { | 556 | if ((ret = cdrom_mrw_probe_pc(cdi))) { |
| 558 | *write = 0; | 557 | *write = 0; |
| 559 | return ret; | ||
| 560 | } | 558 | } |
| 561 | 559 | err: | |
| 562 | return 0; | 560 | kfree(buffer); |
| 561 | return ret; | ||
| 563 | } | 562 | } |
| 564 | 563 | ||
| 565 | static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) | 564 | static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) |
| 566 | { | 565 | { |
| 567 | struct packet_command cgc; | 566 | struct packet_command cgc; |
| 568 | unsigned char buffer[12]; | 567 | unsigned char *buffer; |
| 569 | int ret; | 568 | int ret; |
| 570 | 569 | ||
| 571 | printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : ""); | 570 | printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : ""); |
| 572 | 571 | ||
| 572 | buffer = kmalloc(12, GFP_KERNEL); | ||
| 573 | if (!buffer) | ||
| 574 | return -ENOMEM; | ||
| 575 | |||
| 573 | /* | 576 | /* |
| 574 | * FmtData bit set (bit 4), format type is 1 | 577 | * FmtData bit set (bit 4), format type is 1 |
| 575 | */ | 578 | */ |
| 576 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE); | 579 | init_cdrom_command(&cgc, buffer, 12, CGC_DATA_WRITE); |
| 577 | cgc.cmd[0] = GPCMD_FORMAT_UNIT; | 580 | cgc.cmd[0] = GPCMD_FORMAT_UNIT; |
| 578 | cgc.cmd[1] = (1 << 4) | 1; | 581 | cgc.cmd[1] = (1 << 4) | 1; |
| 579 | 582 | ||
| @@ -600,6 +603,7 @@ static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) | |||
| 600 | if (ret) | 603 | if (ret) |
| 601 | printk(KERN_INFO "cdrom: bgformat failed\n"); | 604 | printk(KERN_INFO "cdrom: bgformat failed\n"); |
| 602 | 605 | ||
| 606 | kfree(buffer); | ||
| 603 | return ret; | 607 | return ret; |
| 604 | } | 608 | } |
| 605 | 609 | ||
| @@ -659,16 +663,17 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |||
| 659 | { | 663 | { |
| 660 | struct packet_command cgc; | 664 | struct packet_command cgc; |
| 661 | struct mode_page_header *mph; | 665 | struct mode_page_header *mph; |
| 662 | char buffer[16]; | 666 | char *buffer; |
| 663 | int ret, offset, size; | 667 | int ret, offset, size; |
| 664 | 668 | ||
| 665 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 669 | buffer = kmalloc(16, GFP_KERNEL); |
| 670 | if (!buffer) | ||
| 671 | return -ENOMEM; | ||
| 666 | 672 | ||
| 667 | cgc.buffer = buffer; | 673 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); |
| 668 | cgc.buflen = sizeof(buffer); | ||
| 669 | 674 | ||
| 670 | if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) | 675 | if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) |
| 671 | return ret; | 676 | goto err; |
| 672 | 677 | ||
| 673 | mph = (struct mode_page_header *) buffer; | 678 | mph = (struct mode_page_header *) buffer; |
| 674 | offset = be16_to_cpu(mph->desc_length); | 679 | offset = be16_to_cpu(mph->desc_length); |
| @@ -678,55 +683,70 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |||
| 678 | cgc.buflen = size; | 683 | cgc.buflen = size; |
| 679 | 684 | ||
| 680 | if ((ret = cdrom_mode_select(cdi, &cgc))) | 685 | if ((ret = cdrom_mode_select(cdi, &cgc))) |
| 681 | return ret; | 686 | goto err; |
| 682 | 687 | ||
| 683 | printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); | 688 | printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); |
| 684 | return 0; | 689 | ret = 0; |
| 690 | err: | ||
| 691 | kfree(buffer); | ||
| 692 | return ret; | ||
| 685 | } | 693 | } |
| 686 | 694 | ||
| 687 | static int cdrom_get_random_writable(struct cdrom_device_info *cdi, | 695 | static int cdrom_get_random_writable(struct cdrom_device_info *cdi, |
| 688 | struct rwrt_feature_desc *rfd) | 696 | struct rwrt_feature_desc *rfd) |
| 689 | { | 697 | { |
| 690 | struct packet_command cgc; | 698 | struct packet_command cgc; |
| 691 | char buffer[24]; | 699 | char *buffer; |
| 692 | int ret; | 700 | int ret; |
| 693 | 701 | ||
| 694 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 702 | buffer = kmalloc(24, GFP_KERNEL); |
| 703 | if (!buffer) | ||
| 704 | return -ENOMEM; | ||
| 705 | |||
| 706 | init_cdrom_command(&cgc, buffer, 24, CGC_DATA_READ); | ||
| 695 | 707 | ||
| 696 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ | 708 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ |
| 697 | cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ | 709 | cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ |
| 698 | cgc.cmd[8] = sizeof(buffer); /* often 0x18 */ | 710 | cgc.cmd[8] = 24; /* often 0x18 */ |
| 699 | cgc.quiet = 1; | 711 | cgc.quiet = 1; |
| 700 | 712 | ||
| 701 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 713 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
| 702 | return ret; | 714 | goto err; |
| 703 | 715 | ||
| 704 | memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); | 716 | memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); |
| 705 | return 0; | 717 | ret = 0; |
| 718 | err: | ||
| 719 | kfree(buffer); | ||
| 720 | return ret; | ||
| 706 | } | 721 | } |
| 707 | 722 | ||
| 708 | static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) | 723 | static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) |
| 709 | { | 724 | { |
| 710 | struct packet_command cgc; | 725 | struct packet_command cgc; |
| 711 | char buffer[16]; | 726 | char *buffer; |
| 712 | __be16 *feature_code; | 727 | __be16 *feature_code; |
| 713 | int ret; | 728 | int ret; |
| 714 | 729 | ||
| 715 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 730 | buffer = kmalloc(16, GFP_KERNEL); |
| 731 | if (!buffer) | ||
| 732 | return -ENOMEM; | ||
| 733 | |||
| 734 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | ||
| 716 | 735 | ||
| 717 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | 736 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
| 718 | cgc.cmd[3] = CDF_HWDM; | 737 | cgc.cmd[3] = CDF_HWDM; |
| 719 | cgc.cmd[8] = sizeof(buffer); | 738 | cgc.cmd[8] = 16; |
| 720 | cgc.quiet = 1; | 739 | cgc.quiet = 1; |
| 721 | 740 | ||
| 722 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 741 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
| 723 | return ret; | 742 | goto err; |
| 724 | 743 | ||
| 725 | feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; | 744 | feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; |
| 726 | if (be16_to_cpu(*feature_code) == CDF_HWDM) | 745 | if (be16_to_cpu(*feature_code) == CDF_HWDM) |
| 727 | return 0; | 746 | ret = 0; |
| 728 | 747 | err: | |
| 729 | return 1; | 748 | kfree(buffer); |
| 749 | return ret; | ||
| 730 | } | 750 | } |
| 731 | 751 | ||
| 732 | 752 | ||
| @@ -817,10 +837,14 @@ static int cdrom_mrw_open_write(struct cdrom_device_info *cdi) | |||
| 817 | static int mo_open_write(struct cdrom_device_info *cdi) | 837 | static int mo_open_write(struct cdrom_device_info *cdi) |
| 818 | { | 838 | { |
| 819 | struct packet_command cgc; | 839 | struct packet_command cgc; |
| 820 | char buffer[255]; | 840 | char *buffer; |
| 821 | int ret; | 841 | int ret; |
| 822 | 842 | ||
| 823 | init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ); | 843 | buffer = kmalloc(255, GFP_KERNEL); |
| 844 | if (!buffer) | ||
| 845 | return -ENOMEM; | ||
| 846 | |||
| 847 | init_cdrom_command(&cgc, buffer, 4, CGC_DATA_READ); | ||
| 824 | cgc.quiet = 1; | 848 | cgc.quiet = 1; |
| 825 | 849 | ||
| 826 | /* | 850 | /* |
| @@ -837,10 +861,15 @@ static int mo_open_write(struct cdrom_device_info *cdi) | |||
| 837 | } | 861 | } |
| 838 | 862 | ||
| 839 | /* drive gave us no info, let the user go ahead */ | 863 | /* drive gave us no info, let the user go ahead */ |
| 840 | if (ret) | 864 | if (ret) { |
| 841 | return 0; | 865 | ret = 0; |
| 866 | goto err; | ||
| 867 | } | ||
| 842 | 868 | ||
| 843 | return buffer[3] & 0x80; | 869 | ret = buffer[3] & 0x80; |
| 870 | err: | ||
| 871 | kfree(buffer); | ||
| 872 | return ret; | ||
| 844 | } | 873 | } |
| 845 | 874 | ||
| 846 | static int cdrom_ram_open_write(struct cdrom_device_info *cdi) | 875 | static int cdrom_ram_open_write(struct cdrom_device_info *cdi) |
| @@ -863,15 +892,19 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi) | |||
| 863 | static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) | 892 | static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) |
| 864 | { | 893 | { |
| 865 | struct packet_command cgc; | 894 | struct packet_command cgc; |
| 866 | char buffer[32]; | 895 | char *buffer; |
| 867 | int ret, mmc3_profile; | 896 | int ret, mmc3_profile; |
| 868 | 897 | ||
| 869 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | 898 | buffer = kmalloc(32, GFP_KERNEL); |
| 899 | if (!buffer) | ||
| 900 | return; | ||
| 901 | |||
| 902 | init_cdrom_command(&cgc, buffer, 32, CGC_DATA_READ); | ||
| 870 | 903 | ||
| 871 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | 904 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
| 872 | cgc.cmd[1] = 0; | 905 | cgc.cmd[1] = 0; |
| 873 | cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */ | 906 | cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */ |
| 874 | cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ | 907 | cgc.cmd[8] = 32; /* Allocation Length */ |
| 875 | cgc.quiet = 1; | 908 | cgc.quiet = 1; |
| 876 | 909 | ||
| 877 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 910 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
| @@ -880,6 +913,7 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) | |||
| 880 | mmc3_profile = (buffer[6] << 8) | buffer[7]; | 913 | mmc3_profile = (buffer[6] << 8) | buffer[7]; |
| 881 | 914 | ||
| 882 | cdi->mmc3_profile = mmc3_profile; | 915 | cdi->mmc3_profile = mmc3_profile; |
| 916 | kfree(buffer); | ||
| 883 | } | 917 | } |
| 884 | 918 | ||
| 885 | static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) | 919 | static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) |
| @@ -1594,12 +1628,15 @@ static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned t | |||
| 1594 | static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | 1628 | static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) |
| 1595 | { | 1629 | { |
| 1596 | int ret; | 1630 | int ret; |
| 1597 | u_char buf[20]; | 1631 | u_char *buf; |
| 1598 | struct packet_command cgc; | 1632 | struct packet_command cgc; |
| 1599 | struct cdrom_device_ops *cdo = cdi->ops; | 1633 | struct cdrom_device_ops *cdo = cdi->ops; |
| 1600 | rpc_state_t rpc_state; | 1634 | rpc_state_t *rpc_state; |
| 1635 | |||
| 1636 | buf = kzalloc(20, GFP_KERNEL); | ||
| 1637 | if (!buf) | ||
| 1638 | return -ENOMEM; | ||
| 1601 | 1639 | ||
| 1602 | memset(buf, 0, sizeof(buf)); | ||
| 1603 | init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); | 1640 | init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); |
| 1604 | 1641 | ||
| 1605 | switch (ai->type) { | 1642 | switch (ai->type) { |
| @@ -1610,7 +1647,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1610 | setup_report_key(&cgc, ai->lsa.agid, 0); | 1647 | setup_report_key(&cgc, ai->lsa.agid, 0); |
| 1611 | 1648 | ||
| 1612 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1649 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1613 | return ret; | 1650 | goto err; |
| 1614 | 1651 | ||
| 1615 | ai->lsa.agid = buf[7] >> 6; | 1652 | ai->lsa.agid = buf[7] >> 6; |
| 1616 | /* Returning data, let host change state */ | 1653 | /* Returning data, let host change state */ |
| @@ -1621,7 +1658,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1621 | setup_report_key(&cgc, ai->lsk.agid, 2); | 1658 | setup_report_key(&cgc, ai->lsk.agid, 2); |
| 1622 | 1659 | ||
| 1623 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1660 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1624 | return ret; | 1661 | goto err; |
| 1625 | 1662 | ||
| 1626 | copy_key(ai->lsk.key, &buf[4]); | 1663 | copy_key(ai->lsk.key, &buf[4]); |
| 1627 | /* Returning data, let host change state */ | 1664 | /* Returning data, let host change state */ |
| @@ -1632,7 +1669,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1632 | setup_report_key(&cgc, ai->lsc.agid, 1); | 1669 | setup_report_key(&cgc, ai->lsc.agid, 1); |
| 1633 | 1670 | ||
| 1634 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1671 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1635 | return ret; | 1672 | goto err; |
| 1636 | 1673 | ||
| 1637 | copy_chal(ai->lsc.chal, &buf[4]); | 1674 | copy_chal(ai->lsc.chal, &buf[4]); |
| 1638 | /* Returning data, let host change state */ | 1675 | /* Returning data, let host change state */ |
| @@ -1649,7 +1686,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1649 | cgc.cmd[2] = ai->lstk.lba >> 24; | 1686 | cgc.cmd[2] = ai->lstk.lba >> 24; |
| 1650 | 1687 | ||
| 1651 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1688 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1652 | return ret; | 1689 | goto err; |
| 1653 | 1690 | ||
| 1654 | ai->lstk.cpm = (buf[4] >> 7) & 1; | 1691 | ai->lstk.cpm = (buf[4] >> 7) & 1; |
| 1655 | ai->lstk.cp_sec = (buf[4] >> 6) & 1; | 1692 | ai->lstk.cp_sec = (buf[4] >> 6) & 1; |
| @@ -1663,7 +1700,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1663 | setup_report_key(&cgc, ai->lsasf.agid, 5); | 1700 | setup_report_key(&cgc, ai->lsasf.agid, 5); |
| 1664 | 1701 | ||
| 1665 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1702 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1666 | return ret; | 1703 | goto err; |
| 1667 | 1704 | ||
| 1668 | ai->lsasf.asf = buf[7] & 1; | 1705 | ai->lsasf.asf = buf[7] & 1; |
| 1669 | break; | 1706 | break; |
| @@ -1676,7 +1713,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1676 | copy_chal(&buf[4], ai->hsc.chal); | 1713 | copy_chal(&buf[4], ai->hsc.chal); |
| 1677 | 1714 | ||
| 1678 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1715 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1679 | return ret; | 1716 | goto err; |
| 1680 | 1717 | ||
| 1681 | ai->type = DVD_LU_SEND_KEY1; | 1718 | ai->type = DVD_LU_SEND_KEY1; |
| 1682 | break; | 1719 | break; |
| @@ -1689,7 +1726,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1689 | 1726 | ||
| 1690 | if ((ret = cdo->generic_packet(cdi, &cgc))) { | 1727 | if ((ret = cdo->generic_packet(cdi, &cgc))) { |
| 1691 | ai->type = DVD_AUTH_FAILURE; | 1728 | ai->type = DVD_AUTH_FAILURE; |
| 1692 | return ret; | 1729 | goto err; |
| 1693 | } | 1730 | } |
| 1694 | ai->type = DVD_AUTH_ESTABLISHED; | 1731 | ai->type = DVD_AUTH_ESTABLISHED; |
| 1695 | break; | 1732 | break; |
| @@ -1700,24 +1737,23 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1700 | cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); | 1737 | cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); |
| 1701 | setup_report_key(&cgc, ai->lsa.agid, 0x3f); | 1738 | setup_report_key(&cgc, ai->lsa.agid, 0x3f); |
| 1702 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1739 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1703 | return ret; | 1740 | goto err; |
| 1704 | break; | 1741 | break; |
| 1705 | 1742 | ||
| 1706 | /* Get region settings */ | 1743 | /* Get region settings */ |
| 1707 | case DVD_LU_SEND_RPC_STATE: | 1744 | case DVD_LU_SEND_RPC_STATE: |
| 1708 | cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); | 1745 | cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); |
| 1709 | setup_report_key(&cgc, 0, 8); | 1746 | setup_report_key(&cgc, 0, 8); |
| 1710 | memset(&rpc_state, 0, sizeof(rpc_state_t)); | ||
| 1711 | cgc.buffer = (char *) &rpc_state; | ||
| 1712 | 1747 | ||
| 1713 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1748 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1714 | return ret; | 1749 | goto err; |
| 1715 | 1750 | ||
| 1716 | ai->lrpcs.type = rpc_state.type_code; | 1751 | rpc_state = (rpc_state_t *)buf; |
| 1717 | ai->lrpcs.vra = rpc_state.vra; | 1752 | ai->lrpcs.type = rpc_state->type_code; |
| 1718 | ai->lrpcs.ucca = rpc_state.ucca; | 1753 | ai->lrpcs.vra = rpc_state->vra; |
| 1719 | ai->lrpcs.region_mask = rpc_state.region_mask; | 1754 | ai->lrpcs.ucca = rpc_state->ucca; |
| 1720 | ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme; | 1755 | ai->lrpcs.region_mask = rpc_state->region_mask; |
| 1756 | ai->lrpcs.rpc_scheme = rpc_state->rpc_scheme; | ||
| 1721 | break; | 1757 | break; |
| 1722 | 1758 | ||
| 1723 | /* Set region settings */ | 1759 | /* Set region settings */ |
| @@ -1728,20 +1764,23 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
| 1728 | buf[4] = ai->hrpcs.pdrc; | 1764 | buf[4] = ai->hrpcs.pdrc; |
| 1729 | 1765 | ||
| 1730 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1766 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1731 | return ret; | 1767 | goto err; |
| 1732 | break; | 1768 | break; |
| 1733 | 1769 | ||
| 1734 | default: | 1770 | default: |
| 1735 | cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); | 1771 | cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); |
| 1736 | return -ENOTTY; | 1772 | ret = -ENOTTY; |
| 1773 | goto err; | ||
| 1737 | } | 1774 | } |
| 1738 | 1775 | ret = 0; | |
| 1739 | return 0; | 1776 | err: |
| 1777 | kfree(buf); | ||
| 1778 | return ret; | ||
| 1740 | } | 1779 | } |
| 1741 | 1780 | ||
| 1742 | static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | 1781 | static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) |
| 1743 | { | 1782 | { |
| 1744 | unsigned char buf[21], *base; | 1783 | unsigned char *buf, *base; |
| 1745 | struct dvd_layer *layer; | 1784 | struct dvd_layer *layer; |
| 1746 | struct packet_command cgc; | 1785 | struct packet_command cgc; |
| 1747 | struct cdrom_device_ops *cdo = cdi->ops; | 1786 | struct cdrom_device_ops *cdo = cdi->ops; |
| @@ -1750,7 +1789,11 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | |||
| 1750 | if (layer_num >= DVD_LAYERS) | 1789 | if (layer_num >= DVD_LAYERS) |
| 1751 | return -EINVAL; | 1790 | return -EINVAL; |
| 1752 | 1791 | ||
| 1753 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); | 1792 | buf = kmalloc(21, GFP_KERNEL); |
| 1793 | if (!buf) | ||
| 1794 | return -ENOMEM; | ||
| 1795 | |||
| 1796 | init_cdrom_command(&cgc, buf, 21, CGC_DATA_READ); | ||
| 1754 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; | 1797 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; |
| 1755 | cgc.cmd[6] = layer_num; | 1798 | cgc.cmd[6] = layer_num; |
| 1756 | cgc.cmd[7] = s->type; | 1799 | cgc.cmd[7] = s->type; |
| @@ -1762,7 +1805,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | |||
| 1762 | cgc.quiet = 1; | 1805 | cgc.quiet = 1; |
| 1763 | 1806 | ||
| 1764 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1807 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1765 | return ret; | 1808 | goto err; |
| 1766 | 1809 | ||
| 1767 | base = &buf[4]; | 1810 | base = &buf[4]; |
| 1768 | layer = &s->physical.layer[layer_num]; | 1811 | layer = &s->physical.layer[layer_num]; |
| @@ -1786,17 +1829,24 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | |||
| 1786 | layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; | 1829 | layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; |
| 1787 | layer->bca = base[16] >> 7; | 1830 | layer->bca = base[16] >> 7; |
| 1788 | 1831 | ||
| 1789 | return 0; | 1832 | ret = 0; |
| 1833 | err: | ||
| 1834 | kfree(buf); | ||
| 1835 | return ret; | ||
| 1790 | } | 1836 | } |
| 1791 | 1837 | ||
| 1792 | static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) | 1838 | static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) |
| 1793 | { | 1839 | { |
| 1794 | int ret; | 1840 | int ret; |
| 1795 | u_char buf[8]; | 1841 | u_char *buf; |
| 1796 | struct packet_command cgc; | 1842 | struct packet_command cgc; |
| 1797 | struct cdrom_device_ops *cdo = cdi->ops; | 1843 | struct cdrom_device_ops *cdo = cdi->ops; |
| 1798 | 1844 | ||
| 1799 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); | 1845 | buf = kmalloc(8, GFP_KERNEL); |
| 1846 | if (!buf) | ||
| 1847 | return -ENOMEM; | ||
| 1848 | |||
| 1849 | init_cdrom_command(&cgc, buf, 8, CGC_DATA_READ); | ||
| 1800 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; | 1850 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; |
| 1801 | cgc.cmd[6] = s->copyright.layer_num; | 1851 | cgc.cmd[6] = s->copyright.layer_num; |
| 1802 | cgc.cmd[7] = s->type; | 1852 | cgc.cmd[7] = s->type; |
| @@ -1804,12 +1854,15 @@ static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) | |||
| 1804 | cgc.cmd[9] = cgc.buflen & 0xff; | 1854 | cgc.cmd[9] = cgc.buflen & 0xff; |
| 1805 | 1855 | ||
| 1806 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1856 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1807 | return ret; | 1857 | goto err; |
| 1808 | 1858 | ||
| 1809 | s->copyright.cpst = buf[4]; | 1859 | s->copyright.cpst = buf[4]; |
| 1810 | s->copyright.rmi = buf[5]; | 1860 | s->copyright.rmi = buf[5]; |
| 1811 | 1861 | ||
| 1812 | return 0; | 1862 | ret = 0; |
| 1863 | err: | ||
| 1864 | kfree(buf); | ||
| 1865 | return ret; | ||
| 1813 | } | 1866 | } |
| 1814 | 1867 | ||
| 1815 | static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) | 1868 | static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) |
| @@ -1841,26 +1894,33 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) | |||
| 1841 | static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) | 1894 | static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) |
| 1842 | { | 1895 | { |
| 1843 | int ret; | 1896 | int ret; |
| 1844 | u_char buf[4 + 188]; | 1897 | u_char *buf; |
| 1845 | struct packet_command cgc; | 1898 | struct packet_command cgc; |
| 1846 | struct cdrom_device_ops *cdo = cdi->ops; | 1899 | struct cdrom_device_ops *cdo = cdi->ops; |
| 1847 | 1900 | ||
| 1848 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); | 1901 | buf = kmalloc(4 + 188, GFP_KERNEL); |
| 1902 | if (!buf) | ||
| 1903 | return -ENOMEM; | ||
| 1904 | |||
| 1905 | init_cdrom_command(&cgc, buf, 4 + 188, CGC_DATA_READ); | ||
| 1849 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; | 1906 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; |
| 1850 | cgc.cmd[7] = s->type; | 1907 | cgc.cmd[7] = s->type; |
| 1851 | cgc.cmd[9] = cgc.buflen & 0xff; | 1908 | cgc.cmd[9] = cgc.buflen & 0xff; |
| 1852 | 1909 | ||
| 1853 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1910 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1854 | return ret; | 1911 | goto err; |
| 1855 | 1912 | ||
| 1856 | s->bca.len = buf[0] << 8 | buf[1]; | 1913 | s->bca.len = buf[0] << 8 | buf[1]; |
| 1857 | if (s->bca.len < 12 || s->bca.len > 188) { | 1914 | if (s->bca.len < 12 || s->bca.len > 188) { |
| 1858 | cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); | 1915 | cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); |
| 1859 | return -EIO; | 1916 | ret = -EIO; |
| 1917 | goto err; | ||
| 1860 | } | 1918 | } |
| 1861 | memcpy(s->bca.value, &buf[4], s->bca.len); | 1919 | memcpy(s->bca.value, &buf[4], s->bca.len); |
| 1862 | 1920 | ret = 0; | |
| 1863 | return 0; | 1921 | err: |
| 1922 | kfree(buf); | ||
| 1923 | return ret; | ||
| 1864 | } | 1924 | } |
| 1865 | 1925 | ||
| 1866 | static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) | 1926 | static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) |
| @@ -1960,9 +2020,13 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, | |||
| 1960 | { | 2020 | { |
| 1961 | struct cdrom_device_ops *cdo = cdi->ops; | 2021 | struct cdrom_device_ops *cdo = cdi->ops; |
| 1962 | struct packet_command cgc; | 2022 | struct packet_command cgc; |
| 1963 | char buffer[32]; | 2023 | char *buffer; |
| 1964 | int ret; | 2024 | int ret; |
| 1965 | 2025 | ||
| 2026 | buffer = kmalloc(32, GFP_KERNEL); | ||
| 2027 | if (!buffer) | ||
| 2028 | return -ENOMEM; | ||
| 2029 | |||
| 1966 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | 2030 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); |
| 1967 | cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; | 2031 | cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; |
| 1968 | cgc.cmd[1] = 2; /* MSF addressing */ | 2032 | cgc.cmd[1] = 2; /* MSF addressing */ |
| @@ -1971,7 +2035,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, | |||
| 1971 | cgc.cmd[8] = 16; | 2035 | cgc.cmd[8] = 16; |
| 1972 | 2036 | ||
| 1973 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 2037 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
| 1974 | return ret; | 2038 | goto err; |
| 1975 | 2039 | ||
| 1976 | subchnl->cdsc_audiostatus = cgc.buffer[1]; | 2040 | subchnl->cdsc_audiostatus = cgc.buffer[1]; |
| 1977 | subchnl->cdsc_format = CDROM_MSF; | 2041 | subchnl->cdsc_format = CDROM_MSF; |
| @@ -1986,7 +2050,10 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, | |||
| 1986 | subchnl->cdsc_absaddr.msf.second = cgc.buffer[10]; | 2050 | subchnl->cdsc_absaddr.msf.second = cgc.buffer[10]; |
| 1987 | subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11]; | 2051 | subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11]; |
| 1988 | 2052 | ||
| 1989 | return 0; | 2053 | ret = 0; |
| 2054 | err: | ||
| 2055 | kfree(buffer); | ||
| 2056 | return ret; | ||
| 1990 | } | 2057 | } |
| 1991 | 2058 | ||
| 1992 | /* | 2059 | /* |
| @@ -3309,7 +3376,7 @@ static int cdrom_print_info(const char *header, int val, char *info, | |||
| 3309 | 3376 | ||
| 3310 | *pos += ret; | 3377 | *pos += ret; |
| 3311 | 3378 | ||
| 3312 | for (cdi = topCdromPtr; cdi; cdi = cdi->next) { | 3379 | list_for_each_entry(cdi, &cdrom_list, list) { |
| 3313 | switch (option) { | 3380 | switch (option) { |
| 3314 | case CTL_NAME: | 3381 | case CTL_NAME: |
| 3315 | ret = scnprintf(info + *pos, max_size - *pos, | 3382 | ret = scnprintf(info + *pos, max_size - *pos, |
| @@ -3430,7 +3497,8 @@ static void cdrom_update_settings(void) | |||
| 3430 | { | 3497 | { |
| 3431 | struct cdrom_device_info *cdi; | 3498 | struct cdrom_device_info *cdi; |
| 3432 | 3499 | ||
| 3433 | for (cdi = topCdromPtr; cdi != NULL; cdi = cdi->next) { | 3500 | mutex_lock(&cdrom_mutex); |
| 3501 | list_for_each_entry(cdi, &cdrom_list, list) { | ||
| 3434 | if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY)) | 3502 | if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY)) |
| 3435 | cdi->options |= CDO_AUTO_CLOSE; | 3503 | cdi->options |= CDO_AUTO_CLOSE; |
| 3436 | else if (!autoclose) | 3504 | else if (!autoclose) |
| @@ -3448,6 +3516,7 @@ static void cdrom_update_settings(void) | |||
| 3448 | else | 3516 | else |
| 3449 | cdi->options &= ~CDO_CHECK_TYPE; | 3517 | cdi->options &= ~CDO_CHECK_TYPE; |
| 3450 | } | 3518 | } |
| 3519 | mutex_unlock(&cdrom_mutex); | ||
| 3451 | } | 3520 | } |
| 3452 | 3521 | ||
| 3453 | static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, | 3522 | static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, |
| @@ -3571,22 +3640,29 @@ static void cdrom_sysctl_unregister(void) | |||
| 3571 | unregister_sysctl_table(cdrom_sysctl_header); | 3640 | unregister_sysctl_table(cdrom_sysctl_header); |
| 3572 | } | 3641 | } |
| 3573 | 3642 | ||
| 3643 | #else /* CONFIG_SYSCTL */ | ||
| 3644 | |||
| 3645 | static void cdrom_sysctl_register(void) | ||
| 3646 | { | ||
| 3647 | } | ||
| 3648 | |||
| 3649 | static void cdrom_sysctl_unregister(void) | ||
| 3650 | { | ||
| 3651 | } | ||
| 3652 | |||
| 3574 | #endif /* CONFIG_SYSCTL */ | 3653 | #endif /* CONFIG_SYSCTL */ |
| 3575 | 3654 | ||
| 3576 | static int __init cdrom_init(void) | 3655 | static int __init cdrom_init(void) |
| 3577 | { | 3656 | { |
| 3578 | #ifdef CONFIG_SYSCTL | ||
| 3579 | cdrom_sysctl_register(); | 3657 | cdrom_sysctl_register(); |
| 3580 | #endif | 3658 | |
| 3581 | return 0; | 3659 | return 0; |
| 3582 | } | 3660 | } |
| 3583 | 3661 | ||
| 3584 | static void __exit cdrom_exit(void) | 3662 | static void __exit cdrom_exit(void) |
| 3585 | { | 3663 | { |
| 3586 | printk(KERN_INFO "Uniform CD-ROM driver unloaded\n"); | 3664 | printk(KERN_INFO "Uniform CD-ROM driver unloaded\n"); |
| 3587 | #ifdef CONFIG_SYSCTL | ||
| 3588 | cdrom_sysctl_unregister(); | 3665 | cdrom_sysctl_unregister(); |
| 3589 | #endif | ||
| 3590 | } | 3666 | } |
| 3591 | 3667 | ||
| 3592 | module_init(cdrom_init); | 3668 | module_init(cdrom_init); |
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 4e2bbcccc064..71ec426ecffc 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c | |||
| @@ -827,7 +827,9 @@ static int __devexit remove_gdrom(struct platform_device *devptr) | |||
| 827 | del_gendisk(gd.disk); | 827 | del_gendisk(gd.disk); |
| 828 | if (gdrom_major) | 828 | if (gdrom_major) |
| 829 | unregister_blkdev(gdrom_major, GDROM_DEV_NAME); | 829 | unregister_blkdev(gdrom_major, GDROM_DEV_NAME); |
| 830 | return unregister_cdrom(gd.cd_info); | 830 | unregister_cdrom(gd.cd_info); |
| 831 | |||
| 832 | return 0; | ||
| 831 | } | 833 | } |
| 832 | 834 | ||
| 833 | static struct platform_driver gdrom_driver = { | 835 | static struct platform_driver gdrom_driver = { |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index cac06bc1754b..b74b6c2768a8 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
| @@ -650,10 +650,7 @@ static int viocd_remove(struct vio_dev *vdev) | |||
| 650 | { | 650 | { |
| 651 | struct disk_info *d = &viocd_diskinfo[vdev->unit_address]; | 651 | struct disk_info *d = &viocd_diskinfo[vdev->unit_address]; |
| 652 | 652 | ||
| 653 | if (unregister_cdrom(&d->viocd_info) != 0) | 653 | unregister_cdrom(&d->viocd_info); |
| 654 | printk(VIOCD_KERN_WARNING | ||
| 655 | "Cannot unregister viocd CD-ROM %s!\n", | ||
| 656 | d->viocd_info.name); | ||
| 657 | del_gendisk(d->viocd_disk); | 654 | del_gendisk(d->viocd_disk); |
| 658 | blk_cleanup_queue(d->viocd_disk->queue); | 655 | blk_cleanup_queue(d->viocd_disk->queue); |
| 659 | put_disk(d->viocd_disk); | 656 | put_disk(d->viocd_disk); |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 396000208f81..fe5aefbf8339 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -2032,9 +2032,8 @@ static void ide_cd_release(struct kref *kref) | |||
| 2032 | 2032 | ||
| 2033 | kfree(info->buffer); | 2033 | kfree(info->buffer); |
| 2034 | kfree(info->toc); | 2034 | kfree(info->toc); |
| 2035 | if (devinfo->handle == drive && unregister_cdrom(devinfo)) | 2035 | if (devinfo->handle == drive) |
| 2036 | printk(KERN_ERR "%s: %s failed to unregister device from the cdrom " | 2036 | unregister_cdrom(devinfo); |
| 2037 | "driver.\n", __FUNCTION__, drive->name); | ||
| 2038 | drive->dsc_overlap = 0; | 2037 | drive->dsc_overlap = 0; |
| 2039 | drive->driver_data = NULL; | 2038 | drive->driver_data = NULL; |
| 2040 | blk_queue_prep_rq(drive->queue, NULL); | 2039 | blk_queue_prep_rq(drive->queue, NULL); |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index f6980bd9d8f9..12d69d7c8577 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
| @@ -852,7 +852,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
| 852 | "Notifying upper driver of completion " | 852 | "Notifying upper driver of completion " |
| 853 | "(result %x)\n", cmd->result)); | 853 | "(result %x)\n", cmd->result)); |
| 854 | 854 | ||
| 855 | good_bytes = scsi_bufflen(cmd) + cmd->request->extra_len; | 855 | good_bytes = scsi_bufflen(cmd); |
| 856 | if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { | 856 | if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { |
| 857 | drv = scsi_cmd_to_driver(cmd); | 857 | drv = scsi_cmd_to_driver(cmd); |
| 858 | if (drv->done) | 858 | if (drv->done) |
| @@ -444,22 +444,27 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | |||
| 444 | 444 | ||
| 445 | struct bio_map_data { | 445 | struct bio_map_data { |
| 446 | struct bio_vec *iovecs; | 446 | struct bio_vec *iovecs; |
| 447 | void __user *userptr; | 447 | int nr_sgvecs; |
| 448 | struct sg_iovec *sgvecs; | ||
| 448 | }; | 449 | }; |
| 449 | 450 | ||
| 450 | static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio) | 451 | static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio, |
| 452 | struct sg_iovec *iov, int iov_count) | ||
| 451 | { | 453 | { |
| 452 | memcpy(bmd->iovecs, bio->bi_io_vec, sizeof(struct bio_vec) * bio->bi_vcnt); | 454 | memcpy(bmd->iovecs, bio->bi_io_vec, sizeof(struct bio_vec) * bio->bi_vcnt); |
| 455 | memcpy(bmd->sgvecs, iov, sizeof(struct sg_iovec) * iov_count); | ||
| 456 | bmd->nr_sgvecs = iov_count; | ||
| 453 | bio->bi_private = bmd; | 457 | bio->bi_private = bmd; |
| 454 | } | 458 | } |
| 455 | 459 | ||
| 456 | static void bio_free_map_data(struct bio_map_data *bmd) | 460 | static void bio_free_map_data(struct bio_map_data *bmd) |
| 457 | { | 461 | { |
| 458 | kfree(bmd->iovecs); | 462 | kfree(bmd->iovecs); |
| 463 | kfree(bmd->sgvecs); | ||
| 459 | kfree(bmd); | 464 | kfree(bmd); |
| 460 | } | 465 | } |
| 461 | 466 | ||
| 462 | static struct bio_map_data *bio_alloc_map_data(int nr_segs) | 467 | static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count) |
| 463 | { | 468 | { |
| 464 | struct bio_map_data *bmd = kmalloc(sizeof(*bmd), GFP_KERNEL); | 469 | struct bio_map_data *bmd = kmalloc(sizeof(*bmd), GFP_KERNEL); |
| 465 | 470 | ||
| @@ -467,13 +472,71 @@ static struct bio_map_data *bio_alloc_map_data(int nr_segs) | |||
| 467 | return NULL; | 472 | return NULL; |
| 468 | 473 | ||
| 469 | bmd->iovecs = kmalloc(sizeof(struct bio_vec) * nr_segs, GFP_KERNEL); | 474 | bmd->iovecs = kmalloc(sizeof(struct bio_vec) * nr_segs, GFP_KERNEL); |
| 470 | if (bmd->iovecs) | 475 | if (!bmd->iovecs) { |
| 476 | kfree(bmd); | ||
| 477 | return NULL; | ||
| 478 | } | ||
| 479 | |||
| 480 | bmd->sgvecs = kmalloc(sizeof(struct sg_iovec) * iov_count, GFP_KERNEL); | ||
| 481 | if (bmd->sgvecs) | ||
| 471 | return bmd; | 482 | return bmd; |
| 472 | 483 | ||
| 484 | kfree(bmd->iovecs); | ||
| 473 | kfree(bmd); | 485 | kfree(bmd); |
| 474 | return NULL; | 486 | return NULL; |
| 475 | } | 487 | } |
| 476 | 488 | ||
| 489 | static int __bio_copy_iov(struct bio *bio, struct sg_iovec *iov, int iov_count, | ||
| 490 | int uncopy) | ||
| 491 | { | ||
| 492 | int ret = 0, i; | ||
| 493 | struct bio_vec *bvec; | ||
| 494 | int iov_idx = 0; | ||
| 495 | unsigned int iov_off = 0; | ||
| 496 | int read = bio_data_dir(bio) == READ; | ||
| 497 | |||
| 498 | __bio_for_each_segment(bvec, bio, i, 0) { | ||
| 499 | char *bv_addr = page_address(bvec->bv_page); | ||
| 500 | unsigned int bv_len = bvec->bv_len; | ||
| 501 | |||
| 502 | while (bv_len && iov_idx < iov_count) { | ||
| 503 | unsigned int bytes; | ||
| 504 | char *iov_addr; | ||
| 505 | |||
| 506 | bytes = min_t(unsigned int, | ||
| 507 | iov[iov_idx].iov_len - iov_off, bv_len); | ||
| 508 | iov_addr = iov[iov_idx].iov_base + iov_off; | ||
| 509 | |||
| 510 | if (!ret) { | ||
| 511 | if (!read && !uncopy) | ||
| 512 | ret = copy_from_user(bv_addr, iov_addr, | ||
| 513 | bytes); | ||
| 514 | if (read && uncopy) | ||
| 515 | ret = copy_to_user(iov_addr, bv_addr, | ||
| 516 | bytes); | ||
| 517 | |||
| 518 | if (ret) | ||
| 519 | ret = -EFAULT; | ||
| 520 | } | ||
| 521 | |||
| 522 | bv_len -= bytes; | ||
| 523 | bv_addr += bytes; | ||
| 524 | iov_addr += bytes; | ||
| 525 | iov_off += bytes; | ||
| 526 | |||
| 527 | if (iov[iov_idx].iov_len == iov_off) { | ||
| 528 | iov_idx++; | ||
| 529 | iov_off = 0; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | if (uncopy) | ||
| 534 | __free_page(bvec->bv_page); | ||
| 535 | } | ||
| 536 | |||
| 537 | return ret; | ||
| 538 | } | ||
| 539 | |||
| 477 | /** | 540 | /** |
| 478 | * bio_uncopy_user - finish previously mapped bio | 541 | * bio_uncopy_user - finish previously mapped bio |
| 479 | * @bio: bio being terminated | 542 | * @bio: bio being terminated |
| @@ -484,55 +547,56 @@ static struct bio_map_data *bio_alloc_map_data(int nr_segs) | |||
| 484 | int bio_uncopy_user(struct bio *bio) | 547 | int bio_uncopy_user(struct bio *bio) |
| 485 | { | 548 | { |
| 486 | struct bio_map_data *bmd = bio->bi_private; | 549 | struct bio_map_data *bmd = bio->bi_private; |
| 487 | const int read = bio_data_dir(bio) == READ; | 550 | int ret; |
| 488 | struct bio_vec *bvec; | ||
| 489 | int i, ret = 0; | ||
| 490 | 551 | ||
| 491 | __bio_for_each_segment(bvec, bio, i, 0) { | 552 | ret = __bio_copy_iov(bio, bmd->sgvecs, bmd->nr_sgvecs, 1); |
| 492 | char *addr = page_address(bvec->bv_page); | ||
| 493 | unsigned int len = bmd->iovecs[i].bv_len; | ||
| 494 | 553 | ||
| 495 | if (read && !ret && copy_to_user(bmd->userptr, addr, len)) | ||
| 496 | ret = -EFAULT; | ||
| 497 | |||
| 498 | __free_page(bvec->bv_page); | ||
| 499 | bmd->userptr += len; | ||
| 500 | } | ||
| 501 | bio_free_map_data(bmd); | 554 | bio_free_map_data(bmd); |
| 502 | bio_put(bio); | 555 | bio_put(bio); |
| 503 | return ret; | 556 | return ret; |
| 504 | } | 557 | } |
| 505 | 558 | ||
| 506 | /** | 559 | /** |
| 507 | * bio_copy_user - copy user data to bio | 560 | * bio_copy_user_iov - copy user data to bio |
| 508 | * @q: destination block queue | 561 | * @q: destination block queue |
| 509 | * @uaddr: start of user address | 562 | * @iov: the iovec. |
| 510 | * @len: length in bytes | 563 | * @iov_count: number of elements in the iovec |
| 511 | * @write_to_vm: bool indicating writing to pages or not | 564 | * @write_to_vm: bool indicating writing to pages or not |
| 512 | * | 565 | * |
| 513 | * Prepares and returns a bio for indirect user io, bouncing data | 566 | * Prepares and returns a bio for indirect user io, bouncing data |
| 514 | * to/from kernel pages as necessary. Must be paired with | 567 | * to/from kernel pages as necessary. Must be paired with |
| 515 | * call bio_uncopy_user() on io completion. | 568 | * call bio_uncopy_user() on io completion. |
| 516 | */ | 569 | */ |
| 517 | struct bio *bio_copy_user(struct request_queue *q, unsigned long uaddr, | 570 | struct bio *bio_copy_user_iov(struct request_queue *q, struct sg_iovec *iov, |
| 518 | unsigned int len, int write_to_vm) | 571 | int iov_count, int write_to_vm) |
| 519 | { | 572 | { |
| 520 | unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 521 | unsigned long start = uaddr >> PAGE_SHIFT; | ||
| 522 | struct bio_map_data *bmd; | 573 | struct bio_map_data *bmd; |
| 523 | struct bio_vec *bvec; | 574 | struct bio_vec *bvec; |
| 524 | struct page *page; | 575 | struct page *page; |
| 525 | struct bio *bio; | 576 | struct bio *bio; |
| 526 | int i, ret; | 577 | int i, ret; |
| 578 | int nr_pages = 0; | ||
| 579 | unsigned int len = 0; | ||
| 527 | 580 | ||
| 528 | bmd = bio_alloc_map_data(end - start); | 581 | for (i = 0; i < iov_count; i++) { |
| 582 | unsigned long uaddr; | ||
| 583 | unsigned long end; | ||
| 584 | unsigned long start; | ||
| 585 | |||
| 586 | uaddr = (unsigned long)iov[i].iov_base; | ||
| 587 | end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 588 | start = uaddr >> PAGE_SHIFT; | ||
| 589 | |||
| 590 | nr_pages += end - start; | ||
| 591 | len += iov[i].iov_len; | ||
| 592 | } | ||
| 593 | |||
| 594 | bmd = bio_alloc_map_data(nr_pages, iov_count); | ||
| 529 | if (!bmd) | 595 | if (!bmd) |
| 530 | return ERR_PTR(-ENOMEM); | 596 | return ERR_PTR(-ENOMEM); |
| 531 | 597 | ||
| 532 | bmd->userptr = (void __user *) uaddr; | ||
| 533 | |||
| 534 | ret = -ENOMEM; | 598 | ret = -ENOMEM; |
| 535 | bio = bio_alloc(GFP_KERNEL, end - start); | 599 | bio = bio_alloc(GFP_KERNEL, nr_pages); |
| 536 | if (!bio) | 600 | if (!bio) |
| 537 | goto out_bmd; | 601 | goto out_bmd; |
| 538 | 602 | ||
| @@ -564,22 +628,12 @@ struct bio *bio_copy_user(struct request_queue *q, unsigned long uaddr, | |||
| 564 | * success | 628 | * success |
| 565 | */ | 629 | */ |
| 566 | if (!write_to_vm) { | 630 | if (!write_to_vm) { |
| 567 | char __user *p = (char __user *) uaddr; | 631 | ret = __bio_copy_iov(bio, iov, iov_count, 0); |
| 568 | 632 | if (ret) | |
| 569 | /* | 633 | goto cleanup; |
| 570 | * for a write, copy in data to kernel pages | ||
| 571 | */ | ||
| 572 | ret = -EFAULT; | ||
| 573 | bio_for_each_segment(bvec, bio, i) { | ||
| 574 | char *addr = page_address(bvec->bv_page); | ||
| 575 | |||
| 576 | if (copy_from_user(addr, p, bvec->bv_len)) | ||
| 577 | goto cleanup; | ||
| 578 | p += bvec->bv_len; | ||
| 579 | } | ||
| 580 | } | 634 | } |
| 581 | 635 | ||
| 582 | bio_set_map_data(bmd, bio); | 636 | bio_set_map_data(bmd, bio, iov, iov_count); |
| 583 | return bio; | 637 | return bio; |
| 584 | cleanup: | 638 | cleanup: |
| 585 | bio_for_each_segment(bvec, bio, i) | 639 | bio_for_each_segment(bvec, bio, i) |
| @@ -591,6 +645,28 @@ out_bmd: | |||
| 591 | return ERR_PTR(ret); | 645 | return ERR_PTR(ret); |
| 592 | } | 646 | } |
| 593 | 647 | ||
| 648 | /** | ||
| 649 | * bio_copy_user - copy user data to bio | ||
| 650 | * @q: destination block queue | ||
| 651 | * @uaddr: start of user address | ||
| 652 | * @len: length in bytes | ||
| 653 | * @write_to_vm: bool indicating writing to pages or not | ||
| 654 | * | ||
| 655 | * Prepares and returns a bio for indirect user io, bouncing data | ||
| 656 | * to/from kernel pages as necessary. Must be paired with | ||
| 657 | * call bio_uncopy_user() on io completion. | ||
| 658 | */ | ||
| 659 | struct bio *bio_copy_user(struct request_queue *q, unsigned long uaddr, | ||
| 660 | unsigned int len, int write_to_vm) | ||
| 661 | { | ||
| 662 | struct sg_iovec iov; | ||
| 663 | |||
| 664 | iov.iov_base = (void __user *)uaddr; | ||
| 665 | iov.iov_len = len; | ||
| 666 | |||
| 667 | return bio_copy_user_iov(q, &iov, 1, write_to_vm); | ||
| 668 | } | ||
| 669 | |||
| 594 | static struct bio *__bio_map_user_iov(struct request_queue *q, | 670 | static struct bio *__bio_map_user_iov(struct request_queue *q, |
| 595 | struct block_device *bdev, | 671 | struct block_device *bdev, |
| 596 | struct sg_iovec *iov, int iov_count, | 672 | struct sg_iovec *iov, int iov_count, |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 4c59bdccd3ee..d259690863fb 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
| @@ -327,6 +327,8 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int, | |||
| 327 | extern void bio_set_pages_dirty(struct bio *bio); | 327 | extern void bio_set_pages_dirty(struct bio *bio); |
| 328 | extern void bio_check_pages_dirty(struct bio *bio); | 328 | extern void bio_check_pages_dirty(struct bio *bio); |
| 329 | extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int); | 329 | extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int); |
| 330 | extern struct bio *bio_copy_user_iov(struct request_queue *, struct sg_iovec *, | ||
| 331 | int, int); | ||
| 330 | extern int bio_uncopy_user(struct bio *); | 332 | extern int bio_uncopy_user(struct bio *); |
| 331 | void zero_fill_bio(struct bio *bio); | 333 | void zero_fill_bio(struct bio *bio); |
| 332 | 334 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 6f79d40dd3c0..c5065e3d2ca9 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -112,6 +112,7 @@ enum rq_flag_bits { | |||
| 112 | __REQ_RW_SYNC, /* request is sync (O_DIRECT) */ | 112 | __REQ_RW_SYNC, /* request is sync (O_DIRECT) */ |
| 113 | __REQ_ALLOCED, /* request came from our alloc pool */ | 113 | __REQ_ALLOCED, /* request came from our alloc pool */ |
| 114 | __REQ_RW_META, /* metadata io request */ | 114 | __REQ_RW_META, /* metadata io request */ |
| 115 | __REQ_COPY_USER, /* contains copies of user pages */ | ||
| 115 | __REQ_NR_BITS, /* stops here */ | 116 | __REQ_NR_BITS, /* stops here */ |
| 116 | }; | 117 | }; |
| 117 | 118 | ||
| @@ -133,6 +134,7 @@ enum rq_flag_bits { | |||
| 133 | #define REQ_RW_SYNC (1 << __REQ_RW_SYNC) | 134 | #define REQ_RW_SYNC (1 << __REQ_RW_SYNC) |
| 134 | #define REQ_ALLOCED (1 << __REQ_ALLOCED) | 135 | #define REQ_ALLOCED (1 << __REQ_ALLOCED) |
| 135 | #define REQ_RW_META (1 << __REQ_RW_META) | 136 | #define REQ_RW_META (1 << __REQ_RW_META) |
| 137 | #define REQ_COPY_USER (1 << __REQ_COPY_USER) | ||
| 136 | 138 | ||
| 137 | #define BLK_MAX_CDB 16 | 139 | #define BLK_MAX_CDB 16 |
| 138 | 140 | ||
| @@ -533,8 +535,13 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn; | |||
| 533 | * BLK_BOUNCE_ANY : don't bounce anything | 535 | * BLK_BOUNCE_ANY : don't bounce anything |
| 534 | * BLK_BOUNCE_ISA : bounce pages above ISA DMA boundary | 536 | * BLK_BOUNCE_ISA : bounce pages above ISA DMA boundary |
| 535 | */ | 537 | */ |
| 538 | |||
| 539 | #if BITS_PER_LONG == 32 | ||
| 536 | #define BLK_BOUNCE_HIGH ((u64)blk_max_low_pfn << PAGE_SHIFT) | 540 | #define BLK_BOUNCE_HIGH ((u64)blk_max_low_pfn << PAGE_SHIFT) |
| 537 | #define BLK_BOUNCE_ANY ((u64)blk_max_pfn << PAGE_SHIFT) | 541 | #else |
| 542 | #define BLK_BOUNCE_HIGH -1ULL | ||
| 543 | #endif | ||
| 544 | #define BLK_BOUNCE_ANY (-1ULL) | ||
| 538 | #define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD) | 545 | #define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD) |
| 539 | 546 | ||
| 540 | /* | 547 | /* |
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index a5cd2047624e..5db265ea60f6 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h | |||
| @@ -910,6 +910,7 @@ struct mode_page_header { | |||
| 910 | #ifdef __KERNEL__ | 910 | #ifdef __KERNEL__ |
| 911 | #include <linux/fs.h> /* not really needed, later.. */ | 911 | #include <linux/fs.h> /* not really needed, later.. */ |
| 912 | #include <linux/device.h> | 912 | #include <linux/device.h> |
| 913 | #include <linux/list.h> | ||
| 913 | 914 | ||
| 914 | struct packet_command | 915 | struct packet_command |
| 915 | { | 916 | { |
| @@ -934,7 +935,7 @@ struct packet_command | |||
| 934 | /* Uniform cdrom data structures for cdrom.c */ | 935 | /* Uniform cdrom data structures for cdrom.c */ |
| 935 | struct cdrom_device_info { | 936 | struct cdrom_device_info { |
| 936 | struct cdrom_device_ops *ops; /* link to device_ops */ | 937 | struct cdrom_device_ops *ops; /* link to device_ops */ |
| 937 | struct cdrom_device_info *next; /* next device_info for this major */ | 938 | struct list_head list; /* linked list of all device_info */ |
| 938 | struct gendisk *disk; /* matching block layer disk */ | 939 | struct gendisk *disk; /* matching block layer disk */ |
| 939 | void *handle; /* driver-dependent data */ | 940 | void *handle; /* driver-dependent data */ |
| 940 | /* specifications */ | 941 | /* specifications */ |
| @@ -994,7 +995,7 @@ extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi, | |||
| 994 | extern int cdrom_media_changed(struct cdrom_device_info *); | 995 | extern int cdrom_media_changed(struct cdrom_device_info *); |
| 995 | 996 | ||
| 996 | extern int register_cdrom(struct cdrom_device_info *cdi); | 997 | extern int register_cdrom(struct cdrom_device_info *cdi); |
| 997 | extern int unregister_cdrom(struct cdrom_device_info *cdi); | 998 | extern void unregister_cdrom(struct cdrom_device_info *cdi); |
| 998 | 999 | ||
| 999 | typedef struct { | 1000 | typedef struct { |
| 1000 | int data; | 1001 | int data; |
