diff --git a/[refs] b/[refs] index bf8a45b77312..d3bad0093c57 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 42c59208219a2d43f0dde94bebc68c20b95b13ce +refs/heads/master: 9689b336e193680fc0fcaa33829dc670637e9c98 diff --git a/trunk/Documentation/ABI/testing/sysfs-block b/trunk/Documentation/ABI/testing/sysfs-block index 44f52a4f5903..4bd9ea539129 100644 --- a/trunk/Documentation/ABI/testing/sysfs-block +++ b/trunk/Documentation/ABI/testing/sysfs-block @@ -26,37 +26,3 @@ Description: I/O statistics of partition . The format is the same as the above-written /sys/block//stat format. - - -What: /sys/block//integrity/format -Date: June 2008 -Contact: Martin K. Petersen -Description: - Metadata format for integrity capable block device. - E.g. T10-DIF-TYPE1-CRC. - - -What: /sys/block//integrity/read_verify -Date: June 2008 -Contact: Martin K. Petersen -Description: - Indicates whether the block layer should verify the - integrity of read requests serviced by devices that - support sending integrity metadata. - - -What: /sys/block//integrity/tag_size -Date: June 2008 -Contact: Martin K. Petersen -Description: - Number of bytes of integrity tag space available per - 512 bytes of data. - - -What: /sys/block//integrity/write_generate -Date: June 2008 -Contact: Martin K. Petersen -Description: - Indicates whether the block layer should automatically - generate checksums for write requests bound for - devices that support receiving integrity metadata. diff --git a/trunk/Documentation/block/data-integrity.txt b/trunk/Documentation/block/data-integrity.txt deleted file mode 100644 index e9dc8d86adc7..000000000000 --- a/trunk/Documentation/block/data-integrity.txt +++ /dev/null @@ -1,327 +0,0 @@ ----------------------------------------------------------------------- -1. INTRODUCTION - -Modern filesystems feature checksumming of data and metadata to -protect against data corruption. However, the detection of the -corruption is done at read time which could potentially be months -after the data was written. At that point the original data that the -application tried to write is most likely lost. - -The solution is to ensure that the disk is actually storing what the -application meant it to. Recent additions to both the SCSI family -protocols (SBC Data Integrity Field, SCC protection proposal) as well -as SATA/T13 (External Path Protection) try to remedy this by adding -support for appending integrity metadata to an I/O. The integrity -metadata (or protection information in SCSI terminology) includes a -checksum for each sector as well as an incrementing counter that -ensures the individual sectors are written in the right order. And -for some protection schemes also that the I/O is written to the right -place on disk. - -Current storage controllers and devices implement various protective -measures, for instance checksumming and scrubbing. But these -technologies are working in their own isolated domains or at best -between adjacent nodes in the I/O path. The interesting thing about -DIF and the other integrity extensions is that the protection format -is well defined and every node in the I/O path can verify the -integrity of the I/O and reject it if corruption is detected. This -allows not only corruption prevention but also isolation of the point -of failure. - ----------------------------------------------------------------------- -2. THE DATA INTEGRITY EXTENSIONS - -As written, the protocol extensions only protect the path between -controller and storage device. However, many controllers actually -allow the operating system to interact with the integrity metadata -(IMD). We have been working with several FC/SAS HBA vendors to enable -the protection information to be transferred to and from their -controllers. - -The SCSI Data Integrity Field works by appending 8 bytes of protection -information to each sector. The data + integrity metadata is stored -in 520 byte sectors on disk. Data + IMD are interleaved when -transferred between the controller and target. The T13 proposal is -similar. - -Because it is highly inconvenient for operating systems to deal with -520 (and 4104) byte sectors, we approached several HBA vendors and -encouraged them to allow separation of the data and integrity metadata -scatter-gather lists. - -The controller will interleave the buffers on write and split them on -read. This means that the Linux can DMA the data buffers to and from -host memory without changes to the page cache. - -Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs -is somewhat heavy to compute in software. Benchmarks found that -calculating this checksum had a significant impact on system -performance for a number of workloads. Some controllers allow a -lighter-weight checksum to be used when interfacing with the operating -system. Emulex, for instance, supports the TCP/IP checksum instead. -The IP checksum received from the OS is converted to the 16-bit CRC -when writing and vice versa. This allows the integrity metadata to be -generated by Linux or the application at very low cost (comparable to -software RAID5). - -The IP checksum is weaker than the CRC in terms of detecting bit -errors. However, the strength is really in the separation of the data -buffers and the integrity metadata. These two distinct buffers much -match up for an I/O to complete. - -The separation of the data and integrity metadata buffers as well as -the choice in checksums is referred to as the Data Integrity -Extensions. As these extensions are outside the scope of the protocol -bodies (T10, T13), Oracle and its partners are trying to standardize -them within the Storage Networking Industry Association. - ----------------------------------------------------------------------- -3. KERNEL CHANGES - -The data integrity framework in Linux enables protection information -to be pinned to I/Os and sent to/received from controllers that -support it. - -The advantage to the integrity extensions in SCSI and SATA is that -they enable us to protect the entire path from application to storage -device. However, at the same time this is also the biggest -disadvantage. It means that the protection information must be in a -format that can be understood by the disk. - -Generally Linux/POSIX applications are agnostic to the intricacies of -the storage devices they are accessing. The virtual filesystem switch -and the block layer make things like hardware sector size and -transport protocols completely transparent to the application. - -However, this level of detail is required when preparing the -protection information to send to a disk. Consequently, the very -concept of an end-to-end protection scheme is a layering violation. -It is completely unreasonable for an application to be aware whether -it is accessing a SCSI or SATA disk. - -The data integrity support implemented in Linux attempts to hide this -from the application. As far as the application (and to some extent -the kernel) is concerned, the integrity metadata is opaque information -that's attached to the I/O. - -The current implementation allows the block layer to automatically -generate the protection information for any I/O. Eventually the -intent is to move the integrity metadata calculation to userspace for -user data. Metadata and other I/O that originates within the kernel -will still use the automatic generation interface. - -Some storage devices allow each hardware sector to be tagged with a -16-bit value. The owner of this tag space is the owner of the block -device. I.e. the filesystem in most cases. The filesystem can use -this extra space to tag sectors as they see fit. Because the tag -space is limited, the block interface allows tagging bigger chunks by -way of interleaving. This way, 8*16 bits of information can be -attached to a typical 4KB filesystem block. - -This also means that applications such as fsck and mkfs will need -access to manipulate the tags from user space. A passthrough -interface for this is being worked on. - - ----------------------------------------------------------------------- -4. BLOCK LAYER IMPLEMENTATION DETAILS - -4.1 BIO - -The data integrity patches add a new field to struct bio when -CONFIG_BLK_DEV_INTEGRITY is enabled. bio->bi_integrity is a pointer -to a struct bip which contains the bio integrity payload. Essentially -a bip is a trimmed down struct bio which holds a bio_vec containing -the integrity metadata and the required housekeeping information (bvec -pool, vector count, etc.) - -A kernel subsystem can enable data integrity protection on a bio by -calling bio_integrity_alloc(bio). This will allocate and attach the -bip to the bio. - -Individual pages containing integrity metadata can subsequently be -attached using bio_integrity_add_page(). - -bio_free() will automatically free the bip. - - -4.2 BLOCK DEVICE - -Because the format of the protection data is tied to the physical -disk, each block device has been extended with a block integrity -profile (struct blk_integrity). This optional profile is registered -with the block layer using blk_integrity_register(). - -The profile contains callback functions for generating and verifying -the protection data, as well as getting and setting application tags. -The profile also contains a few constants to aid in completing, -merging and splitting the integrity metadata. - -Layered block devices will need to pick a profile that's appropriate -for all subdevices. blk_integrity_compare() can help with that. DM -and MD linear, RAID0 and RAID1 are currently supported. RAID4/5/6 -will require extra work due to the application tag. - - ----------------------------------------------------------------------- -5.0 BLOCK LAYER INTEGRITY API - -5.1 NORMAL FILESYSTEM - - The normal filesystem is unaware that the underlying block device - is capable of sending/receiving integrity metadata. The IMD will - be automatically generated by the block layer at submit_bio() time - in case of a WRITE. A READ request will cause the I/O integrity - to be verified upon completion. - - IMD generation and verification can be toggled using the - - /sys/block//integrity/write_generate - - and - - /sys/block//integrity/read_verify - - flags. - - -5.2 INTEGRITY-AWARE FILESYSTEM - - A filesystem that is integrity-aware can prepare I/Os with IMD - attached. It can also use the application tag space if this is - supported by the block device. - - - int bdev_integrity_enabled(block_device, int rw); - - bdev_integrity_enabled() will return 1 if the block device - supports integrity metadata transfer for the data direction - specified in 'rw'. - - bdev_integrity_enabled() honors the write_generate and - read_verify flags in sysfs and will respond accordingly. - - - int bio_integrity_prep(bio); - - To generate IMD for WRITE and to set up buffers for READ, the - filesystem must call bio_integrity_prep(bio). - - Prior to calling this function, the bio data direction and start - sector must be set, and the bio should have all data pages - added. It is up to the caller to ensure that the bio does not - change while I/O is in progress. - - bio_integrity_prep() should only be called if - bio_integrity_enabled() returned 1. - - - int bio_integrity_tag_size(bio); - - If the filesystem wants to use the application tag space it will - first have to find out how much storage space is available. - Because tag space is generally limited (usually 2 bytes per - sector regardless of sector size), the integrity framework - supports interleaving the information between the sectors in an - I/O. - - Filesystems can call bio_integrity_tag_size(bio) to find out how - many bytes of storage are available for that particular bio. - - Another option is bdev_get_tag_size(block_device) which will - return the number of available bytes per hardware sector. - - - int bio_integrity_set_tag(bio, void *tag_buf, len); - - After a successful return from bio_integrity_prep(), - bio_integrity_set_tag() can be used to attach an opaque tag - buffer to a bio. Obviously this only makes sense if the I/O is - a WRITE. - - - int bio_integrity_get_tag(bio, void *tag_buf, len); - - Similarly, at READ I/O completion time the filesystem can - retrieve the tag buffer using bio_integrity_get_tag(). - - -6.3 PASSING EXISTING INTEGRITY METADATA - - Filesystems that either generate their own integrity metadata or - are capable of transferring IMD from user space can use the - following calls: - - - struct bip * bio_integrity_alloc(bio, gfp_mask, nr_pages); - - Allocates the bio integrity payload and hangs it off of the bio. - nr_pages indicate how many pages of protection data need to be - stored in the integrity bio_vec list (similar to bio_alloc()). - - The integrity payload will be freed at bio_free() time. - - - int bio_integrity_add_page(bio, page, len, offset); - - Attaches a page containing integrity metadata to an existing - bio. The bio must have an existing bip, - i.e. bio_integrity_alloc() must have been called. For a WRITE, - the integrity metadata in the pages must be in a format - understood by the target device with the notable exception that - the sector numbers will be remapped as the request traverses the - I/O stack. This implies that the pages added using this call - will be modified during I/O! The first reference tag in the - integrity metadata must have a value of bip->bip_sector. - - Pages can be added using bio_integrity_add_page() as long as - there is room in the bip bio_vec array (nr_pages). - - Upon completion of a READ operation, the attached pages will - contain the integrity metadata received from the storage device. - It is up to the receiver to process them and verify data - integrity upon completion. - - -6.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY - METADATA - - To enable integrity exchange on a block device the gendisk must be - registered as capable: - - int blk_integrity_register(gendisk, blk_integrity); - - The blk_integrity struct is a template and should contain the - following: - - static struct blk_integrity my_profile = { - .name = "STANDARDSBODY-TYPE-VARIANT-CSUM", - .generate_fn = my_generate_fn, - .verify_fn = my_verify_fn, - .get_tag_fn = my_get_tag_fn, - .set_tag_fn = my_set_tag_fn, - .tuple_size = sizeof(struct my_tuple_size), - .tag_size = , - }; - - 'name' is a text string which will be visible in sysfs. This is - part of the userland API so chose it carefully and never change - it. The format is standards body-type-variant. - E.g. T10-DIF-TYPE1-IP or T13-EPP-0-CRC. - - 'generate_fn' generates appropriate integrity metadata (for WRITE). - - 'verify_fn' verifies that the data buffer matches the integrity - metadata. - - 'tuple_size' must be set to match the size of the integrity - metadata per sector. I.e. 8 for DIF and EPP. - - 'tag_size' must be set to identify how many bytes of tag space - are available per hardware sector. For DIF this is either 2 or - 0 depending on the value of the Control Mode Page ATO bit. - - See 6.2 for a description of get_tag_fn and set_tag_fn. - ----------------------------------------------------------------------- -2007-12-24 Martin K. Petersen diff --git a/trunk/arch/x86/kernel/traps_64.c b/trunk/arch/x86/kernel/traps_64.c index f1a95d105953..adff76ea97c4 100644 --- a/trunk/arch/x86/kernel/traps_64.c +++ b/trunk/arch/x86/kernel/traps_64.c @@ -104,7 +104,30 @@ int kstack_depth_to_print = 12; void printk_address(unsigned long address, int reliable) { - printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address); +#ifdef CONFIG_KALLSYMS + unsigned long offset = 0, symsize; + const char *symname; + char *modname; + char *delim = ":"; + char namebuf[KSYM_NAME_LEN]; + char reliab[4] = ""; + + symname = kallsyms_lookup(address, &symsize, &offset, + &modname, namebuf); + if (!symname) { + printk(" [<%016lx>]\n", address); + return; + } + if (!reliable) + strcpy(reliab, "? "); + + if (!modname) + modname = delim = ""; + printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n", + address, reliab, delim, modname, delim, symname, offset, symsize); +#else + printk(" [<%016lx>]\n", address); +#endif } static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, diff --git a/trunk/block/Kconfig b/trunk/block/Kconfig index 1ab7c15c8d7a..3e97f2bc446f 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -81,18 +81,6 @@ config BLK_DEV_BSG If unsure, say N. -config BLK_DEV_INTEGRITY - bool "Block layer data integrity support" - ---help--- - Some storage devices allow extra information to be - stored/retrieved to help protect the data. The block layer - data integrity option provides hooks which can be used by - filesystems to ensure better data integrity. - - Say yes here if you have a storage device that provides the - T10/SCSI Data Integrity Field or the T13/ATA External Path - Protection. If in doubt, say N. - endif # BLOCK config BLOCK_COMPAT diff --git a/trunk/block/Makefile b/trunk/block/Makefile index 208000b0750d..5a43c7d79594 100644 --- a/trunk/block/Makefile +++ b/trunk/block/Makefile @@ -4,8 +4,7 @@ obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ - blk-exec.o blk-merge.o ioctl.o genhd.o scsi_ioctl.o \ - cmd-filter.o + blk-exec.o blk-merge.o ioctl.o genhd.o scsi_ioctl.o obj-$(CONFIG_BLK_DEV_BSG) += bsg.o obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o @@ -15,4 +14,3 @@ obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o -obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 9735acb5b4f5..743f33a01a07 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -151,7 +151,6 @@ enum arq_state { static DEFINE_PER_CPU(unsigned long, ioc_count); static struct completion *ioc_gone; -static DEFINE_SPINLOCK(ioc_gone_lock); static void as_move_to_dispatch(struct as_data *ad, struct request *rq); static void as_antic_stop(struct as_data *ad); @@ -165,19 +164,8 @@ static void free_as_io_context(struct as_io_context *aic) { kfree(aic); elv_ioc_count_dec(ioc_count); - if (ioc_gone) { - /* - * AS scheduler is exiting, grab exit lock and check - * the pending io context count. If it hits zero, - * complete ioc_gone and set it back to NULL. - */ - spin_lock(&ioc_gone_lock); - if (ioc_gone && !elv_ioc_count_read(ioc_count)) { - complete(ioc_gone); - ioc_gone = NULL; - } - spin_unlock(&ioc_gone_lock); - } + if (ioc_gone && !elv_ioc_count_read(ioc_count)) + complete(ioc_gone); } static void as_trim(struct io_context *ioc) @@ -1505,7 +1493,7 @@ static void __exit as_exit(void) /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); if (elv_ioc_count_read(ioc_count)) - wait_for_completion(&all_gone); + wait_for_completion(ioc_gone); synchronize_rcu(); } diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index dbc7f42b5d2b..1905aaba49fb 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -143,10 +143,6 @@ static void req_bio_endio(struct request *rq, struct bio *bio, bio->bi_size -= nbytes; bio->bi_sector += (nbytes >> 9); - - if (bio_integrity(bio)) - bio_integrity_advance(bio, nbytes); - if (bio->bi_size == 0) bio_endio(bio, error); } else { @@ -205,7 +201,8 @@ void blk_plug_device(struct request_queue *q) if (blk_queue_stopped(q)) return; - if (!queue_flag_test_and_set(QUEUE_FLAG_PLUGGED, q)) { + if (!test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) { + __set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags); mod_timer(&q->unplug_timer, jiffies + q->unplug_delay); blk_add_trace_generic(q, NULL, 0, BLK_TA_PLUG); } @@ -220,9 +217,10 @@ int blk_remove_plug(struct request_queue *q) { WARN_ON(!irqs_disabled()); - if (!queue_flag_test_and_clear(QUEUE_FLAG_PLUGGED, q)) + if (!test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) return 0; + queue_flag_clear(QUEUE_FLAG_PLUGGED, q); del_timer(&q->unplug_timer); return 1; } @@ -326,7 +324,8 @@ void blk_start_queue(struct request_queue *q) * one level of recursion is ok and is much faster than kicking * the unplug handling */ - if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { + if (!test_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) { + queue_flag_set(QUEUE_FLAG_REENTER, q); q->request_fn(q); queue_flag_clear(QUEUE_FLAG_REENTER, q); } else { @@ -391,7 +390,8 @@ void __blk_run_queue(struct request_queue *q) * handling reinvoke the handler shortly if we already got there. */ if (!elv_queue_empty(q)) { - if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { + if (!test_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) { + queue_flag_set(QUEUE_FLAG_REENTER, q); q->request_fn(q); queue_flag_clear(QUEUE_FLAG_REENTER, q); } else { @@ -1381,9 +1381,6 @@ static inline void __generic_make_request(struct bio *bio) */ blk_partition_remap(bio); - if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) - goto end_io; - if (old_sector != -1) blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, old_sector); diff --git a/trunk/block/blk-integrity.c b/trunk/block/blk-integrity.c deleted file mode 100644 index 3f1a8478cc38..000000000000 --- a/trunk/block/blk-integrity.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * blk-integrity.c - Block layer data integrity extensions - * - * Copyright (C) 2007, 2008 Oracle Corporation - * Written by: Martin K. Petersen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - */ - -#include -#include -#include -#include - -#include "blk.h" - -static struct kmem_cache *integrity_cachep; - -/** - * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements - * @rq: request with integrity metadata attached - * - * Description: Returns the number of elements required in a - * scatterlist corresponding to the integrity metadata in a request. - */ -int blk_rq_count_integrity_sg(struct request *rq) -{ - struct bio_vec *iv, *ivprv; - struct req_iterator iter; - unsigned int segments; - - ivprv = NULL; - segments = 0; - - rq_for_each_integrity_segment(iv, rq, iter) { - - if (!ivprv || !BIOVEC_PHYS_MERGEABLE(ivprv, iv)) - segments++; - - ivprv = iv; - } - - return segments; -} -EXPORT_SYMBOL(blk_rq_count_integrity_sg); - -/** - * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist - * @rq: request with integrity metadata attached - * @sglist: target scatterlist - * - * Description: Map the integrity vectors in request into a - * scatterlist. The scatterlist must be big enough to hold all - * elements. I.e. sized using blk_rq_count_integrity_sg(). - */ -int blk_rq_map_integrity_sg(struct request *rq, struct scatterlist *sglist) -{ - struct bio_vec *iv, *ivprv; - struct req_iterator iter; - struct scatterlist *sg; - unsigned int segments; - - ivprv = NULL; - sg = NULL; - segments = 0; - - rq_for_each_integrity_segment(iv, rq, iter) { - - if (ivprv) { - if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv)) - goto new_segment; - - sg->length += iv->bv_len; - } else { -new_segment: - if (!sg) - sg = sglist; - else { - sg->page_link &= ~0x02; - sg = sg_next(sg); - } - - sg_set_page(sg, iv->bv_page, iv->bv_len, iv->bv_offset); - segments++; - } - - ivprv = iv; - } - - if (sg) - sg_mark_end(sg); - - return segments; -} -EXPORT_SYMBOL(blk_rq_map_integrity_sg); - -/** - * blk_integrity_compare - Compare integrity profile of two block devices - * @b1: Device to compare - * @b2: Device to compare - * - * Description: Meta-devices like DM and MD need to verify that all - * sub-devices use the same integrity format before advertising to - * upper layers that they can send/receive integrity metadata. This - * function can be used to check whether two block devices have - * compatible integrity formats. - */ -int blk_integrity_compare(struct block_device *bd1, struct block_device *bd2) -{ - struct blk_integrity *b1 = bd1->bd_disk->integrity; - struct blk_integrity *b2 = bd2->bd_disk->integrity; - - BUG_ON(bd1->bd_disk == NULL); - BUG_ON(bd2->bd_disk == NULL); - - if (!b1 || !b2) - return 0; - - if (b1->sector_size != b2->sector_size) { - printk(KERN_ERR "%s: %s/%s sector sz %u != %u\n", __func__, - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, - b1->sector_size, b2->sector_size); - return -1; - } - - if (b1->tuple_size != b2->tuple_size) { - printk(KERN_ERR "%s: %s/%s tuple sz %u != %u\n", __func__, - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, - b1->tuple_size, b2->tuple_size); - return -1; - } - - if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) { - printk(KERN_ERR "%s: %s/%s tag sz %u != %u\n", __func__, - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, - b1->tag_size, b2->tag_size); - return -1; - } - - if (strcmp(b1->name, b2->name)) { - printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__, - bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, - b1->name, b2->name); - return -1; - } - - return 0; -} -EXPORT_SYMBOL(blk_integrity_compare); - -struct integrity_sysfs_entry { - struct attribute attr; - ssize_t (*show)(struct blk_integrity *, char *); - ssize_t (*store)(struct blk_integrity *, const char *, size_t); -}; - -static ssize_t integrity_attr_show(struct kobject *kobj, struct attribute *attr, - char *page) -{ - struct blk_integrity *bi = - container_of(kobj, struct blk_integrity, kobj); - struct integrity_sysfs_entry *entry = - container_of(attr, struct integrity_sysfs_entry, attr); - - return entry->show(bi, page); -} - -static ssize_t integrity_attr_store(struct kobject *kobj, - struct attribute *attr, const char *page, - size_t count) -{ - struct blk_integrity *bi = - container_of(kobj, struct blk_integrity, kobj); - struct integrity_sysfs_entry *entry = - container_of(attr, struct integrity_sysfs_entry, attr); - ssize_t ret = 0; - - if (entry->store) - ret = entry->store(bi, page, count); - - return ret; -} - -static ssize_t integrity_format_show(struct blk_integrity *bi, char *page) -{ - if (bi != NULL && bi->name != NULL) - return sprintf(page, "%s\n", bi->name); - else - return sprintf(page, "none\n"); -} - -static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page) -{ - if (bi != NULL) - return sprintf(page, "%u\n", bi->tag_size); - else - return sprintf(page, "0\n"); -} - -static ssize_t integrity_read_store(struct blk_integrity *bi, - const char *page, size_t count) -{ - char *p = (char *) page; - unsigned long val = simple_strtoul(p, &p, 10); - - if (val) - bi->flags |= INTEGRITY_FLAG_READ; - else - bi->flags &= ~INTEGRITY_FLAG_READ; - - return count; -} - -static ssize_t integrity_read_show(struct blk_integrity *bi, char *page) -{ - return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_READ) != 0); -} - -static ssize_t integrity_write_store(struct blk_integrity *bi, - const char *page, size_t count) -{ - char *p = (char *) page; - unsigned long val = simple_strtoul(p, &p, 10); - - if (val) - bi->flags |= INTEGRITY_FLAG_WRITE; - else - bi->flags &= ~INTEGRITY_FLAG_WRITE; - - return count; -} - -static ssize_t integrity_write_show(struct blk_integrity *bi, char *page) -{ - return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_WRITE) != 0); -} - -static struct integrity_sysfs_entry integrity_format_entry = { - .attr = { .name = "format", .mode = S_IRUGO }, - .show = integrity_format_show, -}; - -static struct integrity_sysfs_entry integrity_tag_size_entry = { - .attr = { .name = "tag_size", .mode = S_IRUGO }, - .show = integrity_tag_size_show, -}; - -static struct integrity_sysfs_entry integrity_read_entry = { - .attr = { .name = "read_verify", .mode = S_IRUGO | S_IWUSR }, - .show = integrity_read_show, - .store = integrity_read_store, -}; - -static struct integrity_sysfs_entry integrity_write_entry = { - .attr = { .name = "write_generate", .mode = S_IRUGO | S_IWUSR }, - .show = integrity_write_show, - .store = integrity_write_store, -}; - -static struct attribute *integrity_attrs[] = { - &integrity_format_entry.attr, - &integrity_tag_size_entry.attr, - &integrity_read_entry.attr, - &integrity_write_entry.attr, - NULL, -}; - -static struct sysfs_ops integrity_ops = { - .show = &integrity_attr_show, - .store = &integrity_attr_store, -}; - -static int __init blk_dev_integrity_init(void) -{ - integrity_cachep = kmem_cache_create("blkdev_integrity", - sizeof(struct blk_integrity), - 0, SLAB_PANIC, NULL); - return 0; -} -subsys_initcall(blk_dev_integrity_init); - -static void blk_integrity_release(struct kobject *kobj) -{ - struct blk_integrity *bi = - container_of(kobj, struct blk_integrity, kobj); - - kmem_cache_free(integrity_cachep, bi); -} - -static struct kobj_type integrity_ktype = { - .default_attrs = integrity_attrs, - .sysfs_ops = &integrity_ops, - .release = blk_integrity_release, -}; - -/** - * blk_integrity_register - Register a gendisk as being integrity-capable - * @disk: struct gendisk pointer to make integrity-aware - * @template: integrity profile - * - * Description: When a device needs to advertise itself as being able - * to send/receive integrity metadata it must use this function to - * register the capability with the block layer. The template is a - * blk_integrity struct with values appropriate for the underlying - * hardware. See Documentation/block/data-integrity.txt. - */ -int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template) -{ - struct blk_integrity *bi; - - BUG_ON(disk == NULL); - BUG_ON(template == NULL); - - if (disk->integrity == NULL) { - bi = kmem_cache_alloc(integrity_cachep, - GFP_KERNEL | __GFP_ZERO); - if (!bi) - return -1; - - if (kobject_init_and_add(&bi->kobj, &integrity_ktype, - &disk->dev.kobj, "%s", "integrity")) { - kmem_cache_free(integrity_cachep, bi); - return -1; - } - - kobject_uevent(&bi->kobj, KOBJ_ADD); - - bi->flags |= INTEGRITY_FLAG_READ | INTEGRITY_FLAG_WRITE; - bi->sector_size = disk->queue->hardsect_size; - disk->integrity = bi; - } else - bi = disk->integrity; - - /* Use the provided profile as template */ - bi->name = template->name; - bi->generate_fn = template->generate_fn; - bi->verify_fn = template->verify_fn; - bi->tuple_size = template->tuple_size; - bi->set_tag_fn = template->set_tag_fn; - bi->get_tag_fn = template->get_tag_fn; - bi->tag_size = template->tag_size; - - return 0; -} -EXPORT_SYMBOL(blk_integrity_register); - -/** - * blk_integrity_unregister - Remove block integrity profile - * @disk: disk whose integrity profile to deallocate - * - * Description: This function frees all memory used by the block - * integrity profile. To be called at device teardown. - */ -void blk_integrity_unregister(struct gendisk *disk) -{ - struct blk_integrity *bi; - - if (!disk || !disk->integrity) - return; - - bi = disk->integrity; - - kobject_uevent(&bi->kobj, KOBJ_REMOVE); - kobject_del(&bi->kobj); - kobject_put(&disk->dev.kobj); - kmem_cache_free(integrity_cachep, bi); -} -EXPORT_SYMBOL(blk_integrity_unregister); diff --git a/trunk/block/blk-map.c b/trunk/block/blk-map.c index ddd96fb11a7d..0b1af5a3537c 100644 --- a/trunk/block/blk-map.c +++ b/trunk/block/blk-map.c @@ -210,7 +210,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, if (!bio_flagged(bio, BIO_USER_MAPPED)) rq->cmd_flags |= REQ_COPY_USER; - blk_queue_bounce(q, &bio); bio_get(bio); blk_rq_bio_prep(q, rq, bio); rq->buffer = rq->data = NULL; @@ -269,7 +268,6 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, int reading = rq_data_dir(rq) == READ; int do_copy = 0; struct bio *bio; - unsigned long stack_mask = ~(THREAD_SIZE - 1); if (len > (q->max_hw_sectors << 9)) return -EINVAL; @@ -280,10 +278,6 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, alignment = queue_dma_alignment(q) | q->dma_pad_mask; do_copy = ((kaddr & alignment) || (len & alignment)); - if (!((kaddr & stack_mask) ^ - ((unsigned long)current->stack & stack_mask))) - do_copy = 1; - if (do_copy) bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); else diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index 5efc9e7a68b7..651136aae76e 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -441,9 +441,6 @@ static int attempt_merge(struct request_queue *q, struct request *req, || next->special) return 0; - if (blk_integrity_rq(req) != blk_integrity_rq(next)) - return 0; - /* * If we are allowed to merge, then append bio list * from next to rq and release next. merge_requests_fn diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index dfc77012843f..8dd86418f35d 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -302,10 +302,11 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * @q: the request queue for the device * @mask: pad mask * - * Set dma pad mask. + * Set pad mask. Direct IO requests are padded to the mask specified. * - * Appending pad buffer to a request modifies the last entry of a - * scatter list such that it includes the pad buffer. + * Appending pad buffer to a request modifies ->data_len such that it + * includes the pad buffer. The original requested data length can be + * obtained using blk_rq_raw_data_len(). **/ void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) { @@ -313,23 +314,6 @@ void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) } EXPORT_SYMBOL(blk_queue_dma_pad); -/** - * blk_queue_update_dma_pad - update pad mask - * @q: the request queue for the device - * @mask: pad mask - * - * Update dma pad mask. - * - * Appending pad buffer to a request modifies the last entry of a - * scatter list such that it includes the pad buffer. - **/ -void blk_queue_update_dma_pad(struct request_queue *q, unsigned int mask) -{ - if (mask > q->dma_pad_mask) - q->dma_pad_mask = mask; -} -EXPORT_SYMBOL(blk_queue_update_dma_pad); - /** * blk_queue_dma_drain - Set up a drain buffer for excess dma. * @q: the request queue for the device diff --git a/trunk/block/blk.h b/trunk/block/blk.h index c79f30e1df52..59776ab4742a 100644 --- a/trunk/block/blk.h +++ b/trunk/block/blk.h @@ -51,12 +51,4 @@ static inline int queue_congestion_off_threshold(struct request_queue *q) return q->nr_congestion_off; } -#if defined(CONFIG_BLK_DEV_INTEGRITY) - -#define rq_for_each_integrity_segment(bvl, _rq, _iter) \ - __rq_for_each_bio(_iter.bio, _rq) \ - bip_for_each_vec(bvl, _iter.bio->bi_integrity, _iter.i) - -#endif /* BLK_DEV_INTEGRITY */ - #endif diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index eb9651ccb241..8d3a27780260 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -244,7 +244,6 @@ static struct dentry *blk_create_tree(const char *blk_name) static void blk_trace_cleanup(struct blk_trace *bt) { relay_close(bt->rchan); - debugfs_remove(bt->msg_file); debugfs_remove(bt->dropped_file); blk_remove_tree(bt->dir); free_percpu(bt->sequence); @@ -292,44 +291,6 @@ static const struct file_operations blk_dropped_fops = { .read = blk_dropped_read, }; -static int blk_msg_open(struct inode *inode, struct file *filp) -{ - filp->private_data = inode->i_private; - - return 0; -} - -static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, - size_t count, loff_t *ppos) -{ - char *msg; - struct blk_trace *bt; - - if (count > BLK_TN_MAX_MSG) - return -EINVAL; - - msg = kmalloc(count, GFP_KERNEL); - if (msg == NULL) - return -ENOMEM; - - if (copy_from_user(msg, buffer, count)) { - kfree(msg); - return -EFAULT; - } - - bt = filp->private_data; - __trace_note_message(bt, "%s", msg); - kfree(msg); - - return count; -} - -static const struct file_operations blk_msg_fops = { - .owner = THIS_MODULE, - .open = blk_msg_open, - .write = blk_msg_write, -}; - /* * Keep track of how many times we encountered a full subbuffer, to aid * the user space app in telling how many lost events there were. @@ -419,10 +380,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (!bt->dropped_file) goto err; - bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops); - if (!bt->msg_file) - goto err; - bt->rchan = relay_open("trace", dir, buts->buf_size, buts->buf_nr, &blk_relay_callbacks, bt); if (!bt->rchan) @@ -452,8 +409,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (dir) blk_remove_tree(dir); if (bt) { - if (bt->msg_file) - debugfs_remove(bt->msg_file); if (bt->dropped_file) debugfs_remove(bt->dropped_file); free_percpu(bt->sequence); diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 93e757d7174b..54d617f7df3e 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -44,12 +44,11 @@ struct bsg_device { char name[BUS_ID_SIZE]; int max_queue; unsigned long flags; - struct blk_scsi_cmd_filter *cmd_filter; - mode_t *f_mode; }; enum { BSG_F_BLOCK = 1, + BSG_F_WRITE_PERM = 2, }; #define BSG_DEFAULT_CMDS 64 @@ -173,7 +172,7 @@ static int bsg_io_schedule(struct bsg_device *bd) } static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, - struct sg_io_v4 *hdr, struct bsg_device *bd) + struct sg_io_v4 *hdr, int has_write_perm) { if (hdr->request_len > BLK_MAX_CDB) { rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); @@ -186,8 +185,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, return -EFAULT; if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { - if (blk_cmd_filter_verify_command(bd->cmd_filter, rq->cmd, - bd->f_mode)) + if (blk_verify_command(rq->cmd, has_write_perm)) return -EPERM; } else if (!capable(CAP_SYS_RAWIO)) return -EPERM; @@ -265,7 +263,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) rq = blk_get_request(q, rw, GFP_KERNEL); if (!rq) return ERR_PTR(-ENOMEM); - ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd); + ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, + &bd->flags)); if (ret) goto out; @@ -567,23 +566,12 @@ static inline void bsg_set_block(struct bsg_device *bd, struct file *file) set_bit(BSG_F_BLOCK, &bd->flags); } -static void bsg_set_cmd_filter(struct bsg_device *bd, - struct file *file) +static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) { - struct inode *inode; - struct gendisk *disk; - - if (!file) - return; - - inode = file->f_dentry->d_inode; - if (!inode) - return; - - disk = inode->i_bdev->bd_disk; - - bd->cmd_filter = &disk->cmd_filter; - bd->f_mode = &file->f_mode; + if (file->f_mode & FMODE_WRITE) + set_bit(BSG_F_WRITE_PERM, &bd->flags); + else + clear_bit(BSG_F_WRITE_PERM, &bd->flags); } /* @@ -607,8 +595,6 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) dprintk("%s: read %Zd bytes\n", bd->name, count); bsg_set_block(bd, file); - bsg_set_cmd_filter(bd, file); - bytes_read = 0; ret = __bsg_read(buf, count, bd, NULL, &bytes_read); *ppos = bytes_read; @@ -682,7 +668,7 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) dprintk("%s: write %Zd bytes\n", bd->name, count); bsg_set_block(bd, file); - bsg_set_cmd_filter(bd, file); + bsg_set_write_perm(bd, file); bytes_written = 0; ret = __bsg_write(bd, buf, count, &bytes_written); @@ -786,9 +772,7 @@ static struct bsg_device *bsg_add_device(struct inode *inode, } bd->queue = rq; - bsg_set_block(bd, file); - bsg_set_cmd_filter(bd, file); atomic_set(&bd->ref_count, 1); mutex_lock(&bsg_mutex); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 1e2aff812ee2..d01b411c72f0 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -11,7 +11,6 @@ #include #include #include -#include /* * tunables @@ -42,14 +41,13 @@ static int cfq_slice_idle = HZ / 125; #define RQ_CIC(rq) \ ((struct cfq_io_context *) (rq)->elevator_private) -#define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) +#define RQ_CFQQ(rq) ((rq)->elevator_private2) static struct kmem_cache *cfq_pool; static struct kmem_cache *cfq_ioc_pool; static DEFINE_PER_CPU(unsigned long, ioc_count); static struct completion *ioc_gone; -static DEFINE_SPINLOCK(ioc_gone_lock); #define CFQ_PRIO_LISTS IOPRIO_BE_NR #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) @@ -157,7 +155,6 @@ struct cfq_queue { unsigned short ioprio, org_ioprio; unsigned short ioprio_class, org_ioprio_class; - pid_t pid; }; enum cfqq_state_flags { @@ -201,11 +198,6 @@ CFQ_CFQQ_FNS(slice_new); CFQ_CFQQ_FNS(sync); #undef CFQ_CFQQ_FNS -#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ - blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args) -#define cfq_log(cfqd, fmt, args...) \ - blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args) - static void cfq_dispatch_insert(struct request_queue *, struct request *); static struct cfq_queue *cfq_get_queue(struct cfq_data *, int, struct io_context *, gfp_t); @@ -242,10 +234,8 @@ static inline int cfq_bio_sync(struct bio *bio) */ static inline void cfq_schedule_dispatch(struct cfq_data *cfqd) { - if (cfqd->busy_queues) { - cfq_log(cfqd, "schedule dispatch"); + if (cfqd->busy_queues) kblockd_schedule_work(&cfqd->unplug_work); - } } static int cfq_queue_empty(struct request_queue *q) @@ -280,7 +270,6 @@ static inline void cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) { cfqq->slice_end = cfq_prio_to_slice(cfqd, cfqq) + jiffies; - cfq_log_cfqq(cfqd, cfqq, "set_slice=%lu", cfqq->slice_end - jiffies); } /* @@ -550,7 +539,6 @@ static void cfq_resort_rr_list(struct cfq_data *cfqd, struct cfq_queue *cfqq) */ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - cfq_log_cfqq(cfqd, cfqq, "add_to_rr"); BUG_ON(cfq_cfqq_on_rr(cfqq)); cfq_mark_cfqq_on_rr(cfqq); cfqd->busy_queues++; @@ -564,7 +552,6 @@ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) */ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - cfq_log_cfqq(cfqd, cfqq, "del_from_rr"); BUG_ON(!cfq_cfqq_on_rr(cfqq)); cfq_clear_cfqq_on_rr(cfqq); @@ -651,8 +638,6 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) struct cfq_data *cfqd = q->elevator->elevator_data; cfqd->rq_in_driver++; - cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d", - cfqd->rq_in_driver); /* * If the depth is larger 1, it really could be queueing. But lets @@ -672,8 +657,6 @@ static void cfq_deactivate_request(struct request_queue *q, struct request *rq) WARN_ON(!cfqd->rq_in_driver); cfqd->rq_in_driver--; - cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", - cfqd->rq_in_driver); } static void cfq_remove_request(struct request *rq) @@ -763,7 +746,6 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) { if (cfqq) { - cfq_log_cfqq(cfqd, cfqq, "set_active"); cfqq->slice_end = 0; cfq_clear_cfqq_must_alloc_slice(cfqq); cfq_clear_cfqq_fifo_expire(cfqq); @@ -781,8 +763,6 @@ static void __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, int timed_out) { - cfq_log_cfqq(cfqd, cfqq, "slice expired t=%d", timed_out); - if (cfq_cfqq_wait_request(cfqq)) del_timer(&cfqd->idle_slice_timer); @@ -792,10 +772,8 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, /* * store what was left of this slice, if the queue idled/timed out */ - if (timed_out && !cfq_cfqq_slice_new(cfqq)) { + if (timed_out && !cfq_cfqq_slice_new(cfqq)) cfqq->slice_resid = cfqq->slice_end - jiffies; - cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid); - } cfq_resort_rr_list(cfqd, cfqq); @@ -887,12 +865,6 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) if (!cfqd->cfq_slice_idle || !cfq_cfqq_idle_window(cfqq)) return; - /* - * still requests with the driver, don't idle - */ - if (cfqd->rq_in_driver) - return; - /* * task has exited, don't wait */ @@ -920,7 +892,6 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT)); mod_timer(&cfqd->idle_slice_timer, jiffies + sl); - cfq_log(cfqd, "arm_idle: %lu", sl); } /* @@ -931,8 +902,6 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq) struct cfq_data *cfqd = q->elevator->elevator_data; struct cfq_queue *cfqq = RQ_CFQQ(rq); - cfq_log_cfqq(cfqd, cfqq, "dispatch_insert"); - cfq_remove_request(rq); cfqq->dispatched++; elv_dispatch_sort(q, rq); @@ -962,9 +931,8 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq) rq = rq_entry_fifo(cfqq->fifo.next); if (time_before(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) - rq = NULL; + return NULL; - cfq_log_cfqq(cfqd, cfqq, "fifo=%p", rq); return rq; } @@ -1104,7 +1072,6 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd) BUG_ON(cfqd->busy_queues); - cfq_log(cfqd, "forced_dispatch=%d\n", dispatched); return dispatched; } @@ -1145,7 +1112,6 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); } - cfq_log(cfqd, "dispatched=%d", dispatched); return dispatched; } @@ -1164,7 +1130,6 @@ static void cfq_put_queue(struct cfq_queue *cfqq) if (!atomic_dec_and_test(&cfqq->ref)) return; - cfq_log_cfqq(cfqd, cfqq, "put_queue"); BUG_ON(rb_first(&cfqq->sort_list)); BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]); BUG_ON(cfq_cfqq_on_rr(cfqq)); @@ -1212,19 +1177,8 @@ static void cfq_cic_free_rcu(struct rcu_head *head) kmem_cache_free(cfq_ioc_pool, cic); elv_ioc_count_dec(ioc_count); - if (ioc_gone) { - /* - * CFQ scheduler is exiting, grab exit lock and check - * the pending io context count. If it hits zero, - * complete ioc_gone and set it back to NULL - */ - spin_lock(&ioc_gone_lock); - if (ioc_gone && !elv_ioc_count_read(ioc_count)) { - complete(ioc_gone); - ioc_gone = NULL; - } - spin_unlock(&ioc_gone_lock); - } + if (ioc_gone && !elv_ioc_count_read(ioc_count)) + complete(ioc_gone); } static void cfq_cic_free(struct cfq_io_context *cic) @@ -1473,8 +1427,6 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, cfq_mark_cfqq_idle_window(cfqq); cfq_mark_cfqq_sync(cfqq); } - cfqq->pid = current->pid; - cfq_log_cfqq(cfqd, cfqq, "alloced"); } if (new_cfqq) @@ -1723,7 +1675,7 @@ static void cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, struct cfq_io_context *cic) { - int old_idle, enable_idle; + int enable_idle; /* * Don't idle for async or idle io prio class @@ -1731,7 +1683,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (!cfq_cfqq_sync(cfqq) || cfq_class_idle(cfqq)) return; - enable_idle = old_idle = cfq_cfqq_idle_window(cfqq); + enable_idle = cfq_cfqq_idle_window(cfqq); if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || (cfqd->hw_tag && CIC_SEEKY(cic))) @@ -1743,13 +1695,10 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, enable_idle = 1; } - if (old_idle != enable_idle) { - cfq_log_cfqq(cfqd, cfqq, "idle=%d", enable_idle); - if (enable_idle) - cfq_mark_cfqq_idle_window(cfqq); - else - cfq_clear_cfqq_idle_window(cfqq); - } + if (enable_idle) + cfq_mark_cfqq_idle_window(cfqq); + else + cfq_clear_cfqq_idle_window(cfqq); } /* @@ -1808,7 +1757,6 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, */ static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - cfq_log_cfqq(cfqd, cfqq, "preempt"); cfq_slice_expired(cfqd, 1); /* @@ -1870,7 +1818,6 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq) struct cfq_data *cfqd = q->elevator->elevator_data; struct cfq_queue *cfqq = RQ_CFQQ(rq); - cfq_log_cfqq(cfqd, cfqq, "insert_request"); cfq_init_prio_data(cfqq, RQ_CIC(rq)->ioc); cfq_add_rq_rb(rq); @@ -1888,7 +1835,6 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) unsigned long now; now = jiffies; - cfq_log_cfqq(cfqd, cfqq, "complete"); WARN_ON(!cfqd->rq_in_driver); WARN_ON(!cfqq->dispatched); @@ -2058,7 +2004,6 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) cfq_schedule_dispatch(cfqd); spin_unlock_irqrestore(q->queue_lock, flags); - cfq_log(cfqd, "set_request fail"); return 1; } @@ -2084,8 +2029,6 @@ static void cfq_idle_slice_timer(unsigned long data) unsigned long flags; int timed_out = 1; - cfq_log(cfqd, "idle timer fired"); - spin_lock_irqsave(cfqd->queue->queue_lock, flags); cfqq = cfqd->active_queue; @@ -2374,7 +2317,7 @@ static void __exit cfq_exit(void) * pending RCU callbacks */ if (elv_ioc_count_read(ioc_count)) - wait_for_completion(&all_gone); + wait_for_completion(ioc_gone); cfq_slab_kill(); } diff --git a/trunk/block/cmd-filter.c b/trunk/block/cmd-filter.c deleted file mode 100644 index eec4404fd357..000000000000 --- a/trunk/block/cmd-filter.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright 2004 Peter M. Jones - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public Licens - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter, - unsigned char *cmd, mode_t *f_mode) -{ - /* root can do any command. */ - if (capable(CAP_SYS_RAWIO)) - return 0; - - /* if there's no filter set, assume we're filtering everything out */ - if (!filter) - return -EPERM; - - /* Anybody who can open the device can do a read-safe command */ - if (test_bit(cmd[0], filter->read_ok)) - return 0; - - /* Write-safe commands require a writable open */ - if (test_bit(cmd[0], filter->write_ok) && (*f_mode & FMODE_WRITE)) - return 0; - - return -EPERM; -} -EXPORT_SYMBOL(blk_cmd_filter_verify_command); - -int blk_verify_command(struct file *file, unsigned char *cmd) -{ - struct gendisk *disk; - struct inode *inode; - - if (!file) - return -EINVAL; - - inode = file->f_dentry->d_inode; - if (!inode) - return -EINVAL; - - disk = inode->i_bdev->bd_disk; - - return blk_cmd_filter_verify_command(&disk->cmd_filter, - cmd, &file->f_mode); -} -EXPORT_SYMBOL(blk_verify_command); - -/* and now, the sysfs stuff */ -static ssize_t rcf_cmds_show(struct blk_scsi_cmd_filter *filter, char *page, - int rw) -{ - char *npage = page; - unsigned long *okbits; - int i; - - if (rw == READ) - okbits = filter->read_ok; - else - okbits = filter->write_ok; - - for (i = 0; i < BLK_SCSI_MAX_CMDS; i++) { - if (test_bit(i, okbits)) { - sprintf(npage, "%02x", i); - npage += 2; - if (i < BLK_SCSI_MAX_CMDS - 1) - sprintf(npage++, " "); - } - } - - if (npage != page) - npage += sprintf(npage, "\n"); - - return npage - page; -} - -static ssize_t rcf_readcmds_show(struct blk_scsi_cmd_filter *filter, char *page) -{ - return rcf_cmds_show(filter, page, READ); -} - -static ssize_t rcf_writecmds_show(struct blk_scsi_cmd_filter *filter, - char *page) -{ - return rcf_cmds_show(filter, page, WRITE); -} - -static ssize_t rcf_cmds_store(struct blk_scsi_cmd_filter *filter, - const char *page, size_t count, int rw) -{ - ssize_t ret = 0; - unsigned long okbits[BLK_SCSI_CMD_PER_LONG], *target_okbits; - int cmd, status, len; - substring_t ss; - - memset(&okbits, 0, sizeof(okbits)); - - for (len = strlen(page); len > 0; len -= 3) { - if (len < 2) - break; - ss.from = (char *) page + ret; - ss.to = (char *) page + ret + 2; - ret += 3; - status = match_hex(&ss, &cmd); - /* either of these cases means invalid input, so do nothing. */ - if (status || cmd >= BLK_SCSI_MAX_CMDS) - return -EINVAL; - - __set_bit(cmd, okbits); - } - - if (rw == READ) - target_okbits = filter->read_ok; - else - target_okbits = filter->write_ok; - - memmove(target_okbits, okbits, sizeof(okbits)); - return count; -} - -static ssize_t rcf_readcmds_store(struct blk_scsi_cmd_filter *filter, - const char *page, size_t count) -{ - return rcf_cmds_store(filter, page, count, READ); -} - -static ssize_t rcf_writecmds_store(struct blk_scsi_cmd_filter *filter, - const char *page, size_t count) -{ - return rcf_cmds_store(filter, page, count, WRITE); -} - -struct rcf_sysfs_entry { - struct attribute attr; - ssize_t (*show)(struct blk_scsi_cmd_filter *, char *); - ssize_t (*store)(struct blk_scsi_cmd_filter *, const char *, size_t); -}; - -static struct rcf_sysfs_entry rcf_readcmds_entry = { - .attr = { .name = "read_table", .mode = S_IRUGO | S_IWUSR }, - .show = rcf_readcmds_show, - .store = rcf_readcmds_store, -}; - -static struct rcf_sysfs_entry rcf_writecmds_entry = { - .attr = {.name = "write_table", .mode = S_IRUGO | S_IWUSR }, - .show = rcf_writecmds_show, - .store = rcf_writecmds_store, -}; - -static struct attribute *default_attrs[] = { - &rcf_readcmds_entry.attr, - &rcf_writecmds_entry.attr, - NULL, -}; - -#define to_rcf(atr) container_of((atr), struct rcf_sysfs_entry, attr) - -static ssize_t -rcf_attr_show(struct kobject *kobj, struct attribute *attr, char *page) -{ - struct rcf_sysfs_entry *entry = to_rcf(attr); - struct blk_scsi_cmd_filter *filter; - - filter = container_of(kobj, struct blk_scsi_cmd_filter, kobj); - if (entry->show) - return entry->show(filter, page); - - return 0; -} - -static ssize_t -rcf_attr_store(struct kobject *kobj, struct attribute *attr, - const char *page, size_t length) -{ - struct rcf_sysfs_entry *entry = to_rcf(attr); - struct blk_scsi_cmd_filter *filter; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - if (!entry->store) - return -EINVAL; - - filter = container_of(kobj, struct blk_scsi_cmd_filter, kobj); - return entry->store(filter, page, length); -} - -static struct sysfs_ops rcf_sysfs_ops = { - .show = rcf_attr_show, - .store = rcf_attr_store, -}; - -static struct kobj_type rcf_ktype = { - .sysfs_ops = &rcf_sysfs_ops, - .default_attrs = default_attrs, -}; - -#ifndef MAINTENANCE_IN_CMD -#define MAINTENANCE_IN_CMD 0xa3 -#endif - -static void rcf_set_defaults(struct blk_scsi_cmd_filter *filter) -{ - /* Basic read-only commands */ - __set_bit(TEST_UNIT_READY, filter->read_ok); - __set_bit(REQUEST_SENSE, filter->read_ok); - __set_bit(READ_6, filter->read_ok); - __set_bit(READ_10, filter->read_ok); - __set_bit(READ_12, filter->read_ok); - __set_bit(READ_16, filter->read_ok); - __set_bit(READ_BUFFER, filter->read_ok); - __set_bit(READ_DEFECT_DATA, filter->read_ok); - __set_bit(READ_CAPACITY, filter->read_ok); - __set_bit(READ_LONG, filter->read_ok); - __set_bit(INQUIRY, filter->read_ok); - __set_bit(MODE_SENSE, filter->read_ok); - __set_bit(MODE_SENSE_10, filter->read_ok); - __set_bit(LOG_SENSE, filter->read_ok); - __set_bit(START_STOP, filter->read_ok); - __set_bit(GPCMD_VERIFY_10, filter->read_ok); - __set_bit(VERIFY_16, filter->read_ok); - __set_bit(REPORT_LUNS, filter->read_ok); - __set_bit(SERVICE_ACTION_IN, filter->read_ok); - __set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok); - __set_bit(MAINTENANCE_IN_CMD, filter->read_ok); - __set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok); - - /* Audio CD commands */ - __set_bit(GPCMD_PLAY_CD, filter->read_ok); - __set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok); - __set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok); - __set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok); - __set_bit(GPCMD_PAUSE_RESUME, filter->read_ok); - - /* CD/DVD data reading */ - __set_bit(GPCMD_READ_CD, filter->read_ok); - __set_bit(GPCMD_READ_CD_MSF, filter->read_ok); - __set_bit(GPCMD_READ_DISC_INFO, filter->read_ok); - __set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok); - __set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok); - __set_bit(GPCMD_READ_HEADER, filter->read_ok); - __set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok); - __set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok); - __set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok); - __set_bit(GPCMD_REPORT_KEY, filter->read_ok); - __set_bit(GPCMD_SCAN, filter->read_ok); - __set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok); - __set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok); - __set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok); - __set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok); - __set_bit(GPCMD_SEEK, filter->read_ok); - __set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok); - - /* Basic writing commands */ - __set_bit(WRITE_6, filter->write_ok); - __set_bit(WRITE_10, filter->write_ok); - __set_bit(WRITE_VERIFY, filter->write_ok); - __set_bit(WRITE_12, filter->write_ok); - __set_bit(WRITE_VERIFY_12, filter->write_ok); - __set_bit(WRITE_16, filter->write_ok); - __set_bit(WRITE_LONG, filter->write_ok); - __set_bit(WRITE_LONG_2, filter->write_ok); - __set_bit(ERASE, filter->write_ok); - __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); - __set_bit(MODE_SELECT, filter->write_ok); - __set_bit(LOG_SELECT, filter->write_ok); - __set_bit(GPCMD_BLANK, filter->write_ok); - __set_bit(GPCMD_CLOSE_TRACK, filter->write_ok); - __set_bit(GPCMD_FLUSH_CACHE, filter->write_ok); - __set_bit(GPCMD_FORMAT_UNIT, filter->write_ok); - __set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok); - __set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok); - __set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok); - __set_bit(GPCMD_SEND_EVENT, filter->write_ok); - __set_bit(GPCMD_SEND_KEY, filter->write_ok); - __set_bit(GPCMD_SEND_OPC, filter->write_ok); - __set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok); - __set_bit(GPCMD_SET_SPEED, filter->write_ok); - __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok); - __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok); - __set_bit(GPCMD_SET_STREAMING, filter->write_ok); -} - -int blk_register_filter(struct gendisk *disk) -{ - int ret; - struct blk_scsi_cmd_filter *filter = &disk->cmd_filter; - struct kobject *parent = kobject_get(disk->holder_dir->parent); - - if (!parent) - return -ENODEV; - - ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, parent, - "%s", "cmd_filter"); - - if (ret < 0) - return ret; - - rcf_set_defaults(filter); - return 0; -} - -void blk_unregister_filter(struct gendisk *disk) -{ - struct blk_scsi_cmd_filter *filter = &disk->cmd_filter; - - kobject_put(&filter->kobj); - kobject_put(disk->holder_dir->parent); -} - diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index ed6f8f32d27e..902dd1344d56 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -86,12 +86,6 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special) return 0; - /* - * only merge integrity protected bio into ditto rq - */ - if (bio_integrity(bio) != blk_integrity_rq(rq)) - return 0; - if (!elv_iosched_allow_merge(rq, bio)) return 0; @@ -150,7 +144,7 @@ static struct elevator_type *elevator_get(const char *name) else sprintf(elv, "%s-iosched", name); - request_module("%s", elv); + request_module(elv); spin_lock(&elv_list_lock); e = elevator_find(name); } diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 9074f384b097..b922d4801c87 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -189,7 +189,6 @@ void add_disk(struct gendisk *disk) disk->minors, NULL, exact_match, exact_lock, disk); register_disk(disk); blk_register_queue(disk); - blk_register_filter(disk); bdi = &disk->queue->backing_dev_info; bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor)); @@ -201,7 +200,6 @@ EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */ void unlink_gendisk(struct gendisk *disk) { - blk_unregister_filter(disk); sysfs_remove_link(&disk->dev.kobj, "bdi"); bdi_unregister(&disk->queue->backing_dev_info); blk_unregister_queue(disk); @@ -402,14 +400,6 @@ static ssize_t disk_removable_show(struct device *dev, (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0)); } -static ssize_t disk_ro_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gendisk *disk = dev_to_disk(dev); - - return sprintf(buf, "%d\n", disk->policy ? 1 : 0); -} - static ssize_t disk_size_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -482,7 +472,6 @@ static ssize_t disk_fail_store(struct device *dev, static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); -static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL); static DEVICE_ATTR(size, S_IRUGO, disk_size_show, NULL); static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); static DEVICE_ATTR(stat, S_IRUGO, disk_stat_show, NULL); @@ -494,7 +483,6 @@ static struct device_attribute dev_attr_fail = static struct attribute *disk_attrs[] = { &dev_attr_range.attr, &dev_attr_removable.attr, - &dev_attr_ro.attr, &dev_attr_size.attr, &dev_attr_capability.attr, &dev_attr_stat.attr, diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index c5b9bcfc0a6d..78199c08ec92 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -105,12 +105,120 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) return put_user(1, p); } +#define CMD_READ_SAFE 0x01 +#define CMD_WRITE_SAFE 0x02 +#define CMD_WARNED 0x04 +#define safe_for_read(cmd) [cmd] = CMD_READ_SAFE +#define safe_for_write(cmd) [cmd] = CMD_WRITE_SAFE + +int blk_verify_command(unsigned char *cmd, int has_write_perm) +{ + static unsigned char cmd_type[256] = { + + /* Basic read-only commands */ + safe_for_read(TEST_UNIT_READY), + safe_for_read(REQUEST_SENSE), + safe_for_read(READ_6), + safe_for_read(READ_10), + safe_for_read(READ_12), + safe_for_read(READ_16), + safe_for_read(READ_BUFFER), + safe_for_read(READ_DEFECT_DATA), + safe_for_read(READ_LONG), + safe_for_read(INQUIRY), + safe_for_read(MODE_SENSE), + safe_for_read(MODE_SENSE_10), + safe_for_read(LOG_SENSE), + safe_for_read(START_STOP), + safe_for_read(GPCMD_VERIFY_10), + safe_for_read(VERIFY_16), + + /* Audio CD commands */ + safe_for_read(GPCMD_PLAY_CD), + safe_for_read(GPCMD_PLAY_AUDIO_10), + safe_for_read(GPCMD_PLAY_AUDIO_MSF), + safe_for_read(GPCMD_PLAY_AUDIO_TI), + safe_for_read(GPCMD_PAUSE_RESUME), + + /* CD/DVD data reading */ + safe_for_read(GPCMD_READ_BUFFER_CAPACITY), + safe_for_read(GPCMD_READ_CD), + safe_for_read(GPCMD_READ_CD_MSF), + safe_for_read(GPCMD_READ_DISC_INFO), + safe_for_read(GPCMD_READ_CDVD_CAPACITY), + safe_for_read(GPCMD_READ_DVD_STRUCTURE), + safe_for_read(GPCMD_READ_HEADER), + safe_for_read(GPCMD_READ_TRACK_RZONE_INFO), + safe_for_read(GPCMD_READ_SUBCHANNEL), + safe_for_read(GPCMD_READ_TOC_PMA_ATIP), + safe_for_read(GPCMD_REPORT_KEY), + safe_for_read(GPCMD_SCAN), + safe_for_read(GPCMD_GET_CONFIGURATION), + safe_for_read(GPCMD_READ_FORMAT_CAPACITIES), + safe_for_read(GPCMD_GET_EVENT_STATUS_NOTIFICATION), + safe_for_read(GPCMD_GET_PERFORMANCE), + safe_for_read(GPCMD_SEEK), + safe_for_read(GPCMD_STOP_PLAY_SCAN), + + /* Basic writing commands */ + safe_for_write(WRITE_6), + safe_for_write(WRITE_10), + safe_for_write(WRITE_VERIFY), + safe_for_write(WRITE_12), + safe_for_write(WRITE_VERIFY_12), + safe_for_write(WRITE_16), + safe_for_write(WRITE_LONG), + safe_for_write(WRITE_LONG_2), + safe_for_write(ERASE), + safe_for_write(GPCMD_MODE_SELECT_10), + safe_for_write(MODE_SELECT), + safe_for_write(LOG_SELECT), + safe_for_write(GPCMD_BLANK), + safe_for_write(GPCMD_CLOSE_TRACK), + safe_for_write(GPCMD_FLUSH_CACHE), + safe_for_write(GPCMD_FORMAT_UNIT), + safe_for_write(GPCMD_REPAIR_RZONE_TRACK), + safe_for_write(GPCMD_RESERVE_RZONE_TRACK), + safe_for_write(GPCMD_SEND_DVD_STRUCTURE), + safe_for_write(GPCMD_SEND_EVENT), + safe_for_write(GPCMD_SEND_KEY), + safe_for_write(GPCMD_SEND_OPC), + safe_for_write(GPCMD_SEND_CUE_SHEET), + safe_for_write(GPCMD_SET_SPEED), + safe_for_write(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL), + safe_for_write(GPCMD_LOAD_UNLOAD), + safe_for_write(GPCMD_SET_STREAMING), + }; + unsigned char type = cmd_type[cmd[0]]; + + /* Anybody who can open the device can do a read-safe command */ + if (type & CMD_READ_SAFE) + return 0; + + /* Write-safe commands just require a writable open.. */ + if ((type & CMD_WRITE_SAFE) && has_write_perm) + return 0; + + /* And root can do any command.. */ + if (capable(CAP_SYS_RAWIO)) + return 0; + + if (!type) { + cmd_type[cmd[0]] = CMD_WARNED; + printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]); + } + + /* Otherwise fail it with an "Operation not permitted" */ + return -EPERM; +} +EXPORT_SYMBOL_GPL(blk_verify_command); + static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, - struct sg_io_hdr *hdr, struct file *file) + struct sg_io_hdr *hdr, int has_write_perm) { if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; - if (blk_verify_command(file, rq->cmd)) + if (blk_verify_command(rq->cmd, has_write_perm)) return -EPERM; /* @@ -179,7 +287,7 @@ static int sg_io(struct file *file, struct request_queue *q, struct gendisk *bd_disk, struct sg_io_hdr *hdr) { unsigned long start_time; - int writing = 0, ret = 0; + int writing = 0, ret = 0, has_write_perm = 0; struct request *rq; char sense[SCSI_SENSE_BUFFERSIZE]; struct bio *bio; @@ -208,7 +316,10 @@ static int sg_io(struct file *file, struct request_queue *q, if (!rq) return -ENOMEM; - if (blk_fill_sghdr_rq(q, rq, hdr, file)) { + if (file) + has_write_perm = file->f_mode & FMODE_WRITE; + + if (blk_fill_sghdr_rq(q, rq, hdr, has_write_perm)) { blk_put_request(rq); return -EFAULT; } @@ -340,7 +451,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q, if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; - err = blk_verify_command(file, rq->cmd); + err = blk_verify_command(rq->cmd, file->f_mode & FMODE_WRITE); if (err) goto error; diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 499ccc628d81..57a43649a461 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -885,8 +885,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, /* set the min alignment and padding */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); - blk_queue_update_dma_pad(sdev->request_queue, - ATA_DMA_PAD_SZ - 1); + blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); /* configure draining */ buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index a002a381df92..cd03473f3547 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -6628,18 +6628,15 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller) * DAC960_gam_ioctl is the ioctl function for performing RAID operations. */ -static long DAC960_gam_ioctl(struct file *file, unsigned int Request, - unsigned long Argument) +static int DAC960_gam_ioctl(struct inode *inode, struct file *file, + unsigned int Request, unsigned long Argument) { - long ErrorCode = 0; + int ErrorCode = 0; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - - lock_kernel(); switch (Request) { case DAC960_IOCTL_GET_CONTROLLER_COUNT: - ErrorCode = DAC960_ControllerCount; - break; + return DAC960_ControllerCount; case DAC960_IOCTL_GET_CONTROLLER_INFO: { DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = @@ -6647,20 +6644,15 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, DAC960_ControllerInfo_T ControllerInfo; DAC960_Controller_T *Controller; int ControllerNumber; - if (UserSpaceControllerInfo == NULL) - ErrorCode = -EINVAL; - else ErrorCode = get_user(ControllerNumber, + if (UserSpaceControllerInfo == NULL) return -EINVAL; + ErrorCode = get_user(ControllerNumber, &UserSpaceControllerInfo->ControllerNumber); - if (ErrorCode != 0) - break;; - ErrorCode = -ENXIO; + if (ErrorCode != 0) return ErrorCode; if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) { - break; - } + ControllerNumber > DAC960_ControllerCount - 1) + return -ENXIO; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - break;; + if (Controller == NULL) return -ENXIO; memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); ControllerInfo.ControllerNumber = ControllerNumber; ControllerInfo.FirmwareType = Controller->FirmwareType; @@ -6673,9 +6665,8 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, ControllerInfo.PCI_Address = Controller->PCI_Address; strcpy(ControllerInfo.ModelName, Controller->ModelName); strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); - ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, + return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); - break; } case DAC960_IOCTL_V1_EXECUTE_COMMAND: { @@ -6693,39 +6684,30 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, int ControllerNumber, DataTransferLength; unsigned char *DataTransferBuffer = NULL; dma_addr_t DataTransferBufferDMA; - if (UserSpaceUserCommand == NULL) { - ErrorCode = -EINVAL; - break; - } + if (UserSpaceUserCommand == NULL) return -EINVAL; if (copy_from_user(&UserCommand, UserSpaceUserCommand, sizeof(DAC960_V1_UserCommand_T))) { ErrorCode = -EFAULT; - break; + goto Failure1a; } ControllerNumber = UserCommand.ControllerNumber; - ErrorCode = -ENXIO; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - break; + return -ENXIO; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - break; - ErrorCode = -EINVAL; - if (Controller->FirmwareType != DAC960_V1_Controller) - break; + if (Controller == NULL) return -ENXIO; + if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; DataTransferLength = UserCommand.DataTransferLength; - if (CommandOpcode & 0x80) - break; + if (CommandOpcode & 0x80) return -EINVAL; if (CommandOpcode == DAC960_V1_DCDB) { if (copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T))) { ErrorCode = -EFAULT; - break; + goto Failure1a; } - if (DCDB.Channel >= DAC960_V1_MaxChannels) - break; + if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; if (!((DataTransferLength == 0 && DCDB.Direction == DAC960_V1_DCDB_NoDataTransfer) || @@ -6735,37 +6717,38 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, (DataTransferLength < 0 && DCDB.Direction == DAC960_V1_DCDB_DataTransferSystemToDevice))) - break; + return -EINVAL; if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) != abs(DataTransferLength)) - break; + return -EINVAL; DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); - if (DCDB_IOBUF == NULL) { - ErrorCode = -ENOMEM; - break; - } + if (DCDB_IOBUF == NULL) + return -ENOMEM; } - ErrorCode = -ENOMEM; if (DataTransferLength > 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - break; + if (DataTransferBuffer == NULL) { + ErrorCode = -ENOMEM; + goto Failure1; + } memset(DataTransferBuffer, 0, DataTransferLength); } else if (DataTransferLength < 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - break; + if (DataTransferBuffer == NULL) { + ErrorCode = -ENOMEM; + goto Failure1; + } if (copy_from_user(DataTransferBuffer, UserCommand.DataTransferBuffer, -DataTransferLength)) { ErrorCode = -EFAULT; - break; + goto Failure1; } } if (CommandOpcode == DAC960_V1_DCDB) @@ -6842,7 +6825,8 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, if (DCDB_IOBUF != NULL) pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), DCDB_IOBUF, DCDB_IOBUFDMA); - break; + Failure1a: + return ErrorCode; } case DAC960_IOCTL_V2_EXECUTE_COMMAND: { @@ -6860,43 +6844,32 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, dma_addr_t DataTransferBufferDMA; unsigned char *RequestSenseBuffer = NULL; dma_addr_t RequestSenseBufferDMA; - - ErrorCode = -EINVAL; - if (UserSpaceUserCommand == NULL) - break; + if (UserSpaceUserCommand == NULL) return -EINVAL; if (copy_from_user(&UserCommand, UserSpaceUserCommand, sizeof(DAC960_V2_UserCommand_T))) { ErrorCode = -EFAULT; - break; + goto Failure2a; } - ErrorCode = -ENXIO; ControllerNumber = UserCommand.ControllerNumber; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - break; + return -ENXIO; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - break; - if (Controller->FirmwareType != DAC960_V2_Controller){ - ErrorCode = -EINVAL; - break; - } + if (Controller == NULL) return -ENXIO; + if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; DataTransferLength = UserCommand.DataTransferLength; - ErrorCode = -ENOMEM; if (DataTransferLength > 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - break; + if (DataTransferBuffer == NULL) return -ENOMEM; memset(DataTransferBuffer, 0, DataTransferLength); } else if (DataTransferLength < 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) - break; + if (DataTransferBuffer == NULL) return -ENOMEM; if (copy_from_user(DataTransferBuffer, UserCommand.DataTransferBuffer, -DataTransferLength)) { @@ -7006,7 +6979,8 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, if (RequestSenseBuffer != NULL) pci_free_consistent(Controller->PCIDevice, RequestSenseLength, RequestSenseBuffer, RequestSenseBufferDMA); - break; + Failure2a: + return ErrorCode; } case DAC960_IOCTL_V2_GET_HEALTH_STATUS: { @@ -7016,33 +6990,21 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; DAC960_Controller_T *Controller; int ControllerNumber; - if (UserSpaceGetHealthStatus == NULL) { - ErrorCode = -EINVAL; - break; - } + if (UserSpaceGetHealthStatus == NULL) return -EINVAL; if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, - sizeof(DAC960_V2_GetHealthStatus_T))) { - ErrorCode = -EFAULT; - break; - } - ErrorCode = -ENXIO; + sizeof(DAC960_V2_GetHealthStatus_T))) + return -EFAULT; ControllerNumber = GetHealthStatus.ControllerNumber; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - break; + return -ENXIO; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) - break; - if (Controller->FirmwareType != DAC960_V2_Controller) { - ErrorCode = -EINVAL; - break; - } + if (Controller == NULL) return -ENXIO; + if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; if (copy_from_user(&HealthStatusBuffer, GetHealthStatus.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) { - ErrorCode = -EFAULT; - break; - } + sizeof(DAC960_V2_HealthStatusBuffer_T))) + return -EFAULT; while (Controller->V2.HealthStatusBuffer->StatusChangeCounter == HealthStatusBuffer.StatusChangeCounter && Controller->V2.HealthStatusBuffer->NextEventSequenceNumber @@ -7050,28 +7012,21 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request, { interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, DAC960_MonitoringTimerInterval); - if (signal_pending(current)) { - ErrorCode = -EINTR; - break; - } + if (signal_pending(current)) return -EINTR; } if (copy_to_user(GetHealthStatus.HealthStatusBuffer, Controller->V2.HealthStatusBuffer, sizeof(DAC960_V2_HealthStatusBuffer_T))) - ErrorCode = -EFAULT; - else - ErrorCode = 0; + return -EFAULT; + return 0; } - default: - ErrorCode = -ENOTTY; } - unlock_kernel(); - return ErrorCode; + return -EINVAL; } static const struct file_operations DAC960_gam_fops = { .owner = THIS_MODULE, - .unlocked_ioctl = DAC960_gam_ioctl + .ioctl = DAC960_gam_ioctl }; static struct miscdevice DAC960_gam_dev = { diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 2f1746295d06..41f818be2f7e 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -1003,7 +1003,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) * Enough people have their dip switches set backwards to * warrant a loud message for this special case. */ - aoemajor = get_unaligned_be16(&h->major); + aoemajor = be16_to_cpu(get_unaligned(&h->major)); if (aoemajor == 0xfff) { printk(KERN_ERR "aoe: Warning: shelf address is all ones. " "Check shelf dip switches.\n"); diff --git a/trunk/drivers/block/paride/pt.c b/trunk/drivers/block/paride/pt.c index 27455ee1e9da..8b9549ab4a4e 100644 --- a/trunk/drivers/block/paride/pt.c +++ b/trunk/drivers/block/paride/pt.c @@ -146,7 +146,6 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; #include #include #include /* current, TASK_*, schedule_timeout() */ -#include #include @@ -190,7 +189,8 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_LOG_SENSE 0x4d static int pt_open(struct inode *inode, struct file *file); -static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +static int pt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); static int pt_release(struct inode *inode, struct file *file); static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos); @@ -236,7 +236,7 @@ static const struct file_operations pt_fops = { .owner = THIS_MODULE, .read = pt_read, .write = pt_write, - .unlocked_ioctl = pt_ioctl, + .ioctl = pt_ioctl, .open = pt_open, .release = pt_release, }; @@ -685,7 +685,8 @@ static int pt_open(struct inode *inode, struct file *file) return err; } -static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int pt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct pt_unit *tape = file->private_data; struct mtop __user *p = (void __user *)arg; @@ -699,26 +700,23 @@ static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (mtop.mt_op) { case MTREW: - lock_kernel(); pt_rewind(tape); - unlock_kernel(); return 0; case MTWEOF: - lock_kernel(); pt_write_fm(tape); - unlock_kernel(); return 0; default: - /* FIXME: rate limit ?? */ - printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name, + printk("%s: Unimplemented mt_op %d\n", tape->name, mtop.mt_op); return -EINVAL; } default: - return -ENOTTY; + printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd); + return -EINVAL; + } } diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index 45bee918c46a..3ba1df93e9e3 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -2080,6 +2079,7 @@ static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd, unsigned char buf[64]; int ret; + memset(buf, 0, sizeof(buf)); init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.sense = &sense; cgc.buflen = pd->mode_offset + 12; @@ -2126,6 +2126,7 @@ static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned char *cap_buf; int ret, offset; + memset(buf, 0, sizeof(buf)); cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_UNKNOWN); cgc.sense = &sense; @@ -2632,12 +2633,11 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio) -static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, - struct bio_vec *bvec) +static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec) { struct pktcdvd_device *pd = q->queuedata; - sector_t zone = ZONE(bmd->bi_sector, pd); - int used = ((bmd->bi_sector - zone) << 9) + bmd->bi_size; + sector_t zone = ZONE(bio->bi_sector, pd); + int used = ((bio->bi_sector - zone) << 9) + bio->bi_size; int remaining = (pd->settings.size << 9) - used; int remaining2; @@ -2645,7 +2645,7 @@ static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, * A bio <= PAGE_SIZE must be allowed. If it crosses a packet * boundary, pkt_make_request() will split the bio. */ - remaining2 = PAGE_SIZE - bmd->bi_size; + remaining2 = PAGE_SIZE - bio->bi_size; remaining = max(remaining, remaining2); BUG_ON(remaining < 0); @@ -2796,14 +2796,9 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) return ret; } -static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - struct pktcdvd_device *pd; - long ret; - - lock_kernel(); - pd = inode->i_bdev->bd_disk->private_data; + struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); @@ -2816,8 +2811,7 @@ static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case CDROM_LAST_WRITTEN: case CDROM_SEND_PACKET: case SCSI_IOCTL_SEND_COMMAND: - ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); - break; + return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); case CDROMEJECT: /* @@ -2826,15 +2820,14 @@ static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) */ if (pd->refcnt == 1) pkt_lock_door(pd, 0); - ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); - break; + return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); default: VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); - ret = -ENOTTY; + return -ENOTTY; } - unlock_kernel(); - return ret; + + return 0; } static int pkt_media_changed(struct gendisk *disk) @@ -2856,7 +2849,7 @@ static struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .unlocked_ioctl = pkt_ioctl, + .ioctl = pkt_ioctl, .media_changed = pkt_media_changed, }; @@ -3021,8 +3014,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) mutex_unlock(&ctl_mutex); } -static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) +static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; struct pkt_ctrl_command ctrl_cmd; @@ -3039,22 +3031,16 @@ static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, case PKT_CTRL_CMD_SETUP: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - lock_kernel(); ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev); ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev); - unlock_kernel(); break; case PKT_CTRL_CMD_TEARDOWN: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - lock_kernel(); ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev)); - unlock_kernel(); break; case PKT_CTRL_CMD_STATUS: - lock_kernel(); pkt_get_status(&ctrl_cmd); - unlock_kernel(); break; default: return -ENOTTY; @@ -3067,7 +3053,7 @@ static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, static const struct file_operations pkt_ctl_fops = { - .unlocked_ioctl = pkt_ctl_ioctl, + .ioctl = pkt_ctl_ioctl, .owner = THIS_MODULE, }; diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index 9ae05c584234..f2fff5799ddf 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -154,40 +153,6 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) return 0; } -int blkif_ioctl(struct inode *inode, struct file *filep, - unsigned command, unsigned long argument) -{ - struct blkfront_info *info = - inode->i_bdev->bd_disk->private_data; - int i; - - dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n", - command, (long)argument); - - switch (command) { - case CDROMMULTISESSION: - dev_dbg(&info->xbdev->dev, "FIXME: support multisession CDs later\n"); - for (i = 0; i < sizeof(struct cdrom_multisession); i++) - if (put_user(0, (char __user *)(argument + i))) - return -EFAULT; - return 0; - - case CDROM_GET_CAPABILITY: { - struct gendisk *gd = info->gd; - if (gd->flags & GENHD_FL_CD) - return 0; - return -EINVAL; - } - - default: - /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n", - command);*/ - return -EINVAL; /* same return as native Linux */ - } - - return 0; -} - /* * blkif_queue_request * @@ -359,9 +324,6 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) /* Make sure buffer addresses are sector-aligned. */ blk_queue_dma_alignment(rq, 511); - /* Make sure we don't use bounce buffers. */ - blk_queue_bounce_limit(rq, BLK_BOUNCE_ANY); - gd->queue = rq; return 0; @@ -584,7 +546,7 @@ static int setup_blkring(struct xenbus_device *dev, info->ring_ref = GRANT_INVALID_REF; - sring = (struct blkif_sring *)__get_free_page(GFP_NOIO | __GFP_HIGH); + sring = (struct blkif_sring *)__get_free_page(GFP_KERNEL); if (!sring) { xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); return -ENOMEM; @@ -741,8 +703,7 @@ static int blkif_recover(struct blkfront_info *info) int j; /* Stage 1: Make a safe copy of the shadow state. */ - copy = kmalloc(sizeof(info->shadow), - GFP_NOIO | __GFP_REPEAT | __GFP_HIGH); + copy = kmalloc(sizeof(info->shadow), GFP_KERNEL); if (!copy) return -ENOMEM; memcpy(copy, info->shadow, sizeof(info->shadow)); @@ -998,7 +959,7 @@ static int blkif_release(struct inode *inode, struct file *filep) struct xenbus_device *dev = info->xbdev; enum xenbus_state state = xenbus_read_driver_state(dev->otherend); - if (state == XenbusStateClosing && info->is_ready) + if (state == XenbusStateClosing) blkfront_closing(dev); } return 0; @@ -1010,7 +971,6 @@ static struct block_device_operations xlvbd_block_fops = .open = blkif_open, .release = blkif_release, .getgeo = blkif_getgeo, - .ioctl = blkif_ioctl, }; @@ -1046,7 +1006,7 @@ static int __init xlblk_init(void) module_init(xlblk_init); -static void __exit xlblk_exit(void) +static void xlblk_exit(void) { return xenbus_unregister_driver(&blkfront); } diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index a5da35632651..69f26eb6415b 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -461,27 +461,37 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med) { struct packet_command cgc; - unsigned char buffer[8]; - struct event_header *eh = (struct event_header *) buffer; + unsigned char *buffer; + struct event_header *eh; + int ret = 1; + + buffer = kmalloc(8, GFP_KERNEL); + if (!buffer) + return -ENOMEM; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + eh = (struct event_header *)buffer; + + init_cdrom_command(&cgc, buffer, 8, CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; cgc.cmd[1] = 1; /* IMMED */ cgc.cmd[4] = 1 << 4; /* media event */ - cgc.cmd[8] = sizeof(buffer); + cgc.cmd[8] = 8; cgc.quiet = 1; if (cdi->ops->generic_packet(cdi, &cgc)) - return 1; + goto err; if (be16_to_cpu(eh->data_len) < sizeof(*med)) - return 1; + goto err; if (eh->nea || eh->notification_class != 0x4) - return 1; + goto err; - memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); - return 0; + memcpy(med, buffer + sizeof(*eh), sizeof(*med)); + ret = 0; +err: + kfree(buffer); + return ret; } /* @@ -491,68 +501,82 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi, static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) { struct packet_command cgc; - char buffer[16]; + char *buffer; + int ret = 1; + + buffer = kmalloc(16, GFP_KERNEL); + if (!buffer) + return -ENOMEM; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); cgc.timeout = HZ; cgc.quiet = 1; if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { cdi->mrw_mode_page = MRW_MODE_PC; - return 0; + ret = 0; } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { cdi->mrw_mode_page = MRW_MODE_PC_PRE1; - return 0; + ret = 0; } - - return 1; + kfree(buffer); + return ret; } static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) { struct packet_command cgc; struct mrw_feature_desc *mfd; - unsigned char buffer[16]; + unsigned char *buffer; int ret; *write = 0; + buffer = kmalloc(16, GFP_KERNEL); + if (!buffer) + return -ENOMEM; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[3] = CDF_MRW; - cgc.cmd[8] = sizeof(buffer); + cgc.cmd[8] = 16; cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - return ret; + goto err; mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; - if (be16_to_cpu(mfd->feature_code) != CDF_MRW) - return 1; + if (be16_to_cpu(mfd->feature_code) != CDF_MRW) { + ret = 1; + goto err; + } *write = mfd->write; if ((ret = cdrom_mrw_probe_pc(cdi))) { *write = 0; - return ret; } - - return 0; +err: + kfree(buffer); + return ret; } static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) { struct packet_command cgc; - unsigned char buffer[12]; + unsigned char *buffer; int ret; printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : ""); + buffer = kmalloc(12, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + /* * FmtData bit set (bit 4), format type is 1 */ - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE); + init_cdrom_command(&cgc, buffer, 12, CGC_DATA_WRITE); cgc.cmd[0] = GPCMD_FORMAT_UNIT; cgc.cmd[1] = (1 << 4) | 1; @@ -579,6 +603,7 @@ static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) if (ret) printk(KERN_INFO "cdrom: bgformat failed\n"); + kfree(buffer); return ret; } @@ -638,16 +663,17 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) { struct packet_command cgc; struct mode_page_header *mph; - char buffer[16]; + char *buffer; int ret, offset, size; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + buffer = kmalloc(16, GFP_KERNEL); + if (!buffer) + return -ENOMEM; - cgc.buffer = buffer; - cgc.buflen = sizeof(buffer); + init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) - return ret; + goto err; mph = (struct mode_page_header *) buffer; offset = be16_to_cpu(mph->desc_length); @@ -657,55 +683,70 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) cgc.buflen = size; if ((ret = cdrom_mode_select(cdi, &cgc))) - return ret; + goto err; printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); - return 0; + ret = 0; +err: + kfree(buffer); + return ret; } static int cdrom_get_random_writable(struct cdrom_device_info *cdi, struct rwrt_feature_desc *rfd) { struct packet_command cgc; - char buffer[24]; + char *buffer; int ret; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + buffer = kmalloc(24, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + init_cdrom_command(&cgc, buffer, 24, CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ - cgc.cmd[8] = sizeof(buffer); /* often 0x18 */ + cgc.cmd[8] = 24; /* often 0x18 */ cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - return ret; + goto err; memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); - return 0; + ret = 0; +err: + kfree(buffer); + return ret; } static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) { struct packet_command cgc; - char buffer[16]; + char *buffer; __be16 *feature_code; int ret; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + buffer = kmalloc(16, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[3] = CDF_HWDM; - cgc.cmd[8] = sizeof(buffer); + cgc.cmd[8] = 16; cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - return ret; + goto err; feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; if (be16_to_cpu(*feature_code) == CDF_HWDM) - return 0; - - return 1; + ret = 0; +err: + kfree(buffer); + return ret; } @@ -796,10 +837,14 @@ static int cdrom_mrw_open_write(struct cdrom_device_info *cdi) static int mo_open_write(struct cdrom_device_info *cdi) { struct packet_command cgc; - char buffer[255]; + char *buffer; int ret; - init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ); + buffer = kmalloc(255, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + init_cdrom_command(&cgc, buffer, 4, CGC_DATA_READ); cgc.quiet = 1; /* @@ -816,10 +861,15 @@ static int mo_open_write(struct cdrom_device_info *cdi) } /* drive gave us no info, let the user go ahead */ - if (ret) - return 0; + if (ret) { + ret = 0; + goto err; + } - return buffer[3] & 0x80; + ret = buffer[3] & 0x80; +err: + kfree(buffer); + return ret; } static int cdrom_ram_open_write(struct cdrom_device_info *cdi) @@ -842,15 +892,19 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi) static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) { struct packet_command cgc; - char buffer[32]; + char *buffer; int ret, mmc3_profile; - init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); + buffer = kmalloc(32, GFP_KERNEL); + if (!buffer) + return; + + init_cdrom_command(&cgc, buffer, 32, CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[1] = 0; cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */ - cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ + cgc.cmd[8] = 32; /* Allocation Length */ cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) @@ -859,6 +913,7 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) mmc3_profile = (buffer[6] << 8) | buffer[7]; cdi->mmc3_profile = mmc3_profile; + kfree(buffer); } static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) @@ -1573,12 +1628,15 @@ static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned t static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) { int ret; - u_char buf[20]; + u_char *buf; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - rpc_state_t rpc_state; + rpc_state_t *rpc_state; + + buf = kzalloc(20, GFP_KERNEL); + if (!buf) + return -ENOMEM; - memset(buf, 0, sizeof(buf)); init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); switch (ai->type) { @@ -1589,7 +1647,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsa.agid, 0); if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; ai->lsa.agid = buf[7] >> 6; /* Returning data, let host change state */ @@ -1600,7 +1658,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsk.agid, 2); if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; copy_key(ai->lsk.key, &buf[4]); /* Returning data, let host change state */ @@ -1611,7 +1669,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsc.agid, 1); if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; copy_chal(ai->lsc.chal, &buf[4]); /* Returning data, let host change state */ @@ -1628,7 +1686,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) cgc.cmd[2] = ai->lstk.lba >> 24; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; ai->lstk.cpm = (buf[4] >> 7) & 1; ai->lstk.cp_sec = (buf[4] >> 6) & 1; @@ -1642,7 +1700,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsasf.agid, 5); if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; ai->lsasf.asf = buf[7] & 1; break; @@ -1655,7 +1713,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) copy_chal(&buf[4], ai->hsc.chal); if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; ai->type = DVD_LU_SEND_KEY1; break; @@ -1668,7 +1726,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) if ((ret = cdo->generic_packet(cdi, &cgc))) { ai->type = DVD_AUTH_FAILURE; - return ret; + goto err; } ai->type = DVD_AUTH_ESTABLISHED; break; @@ -1679,24 +1737,23 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); setup_report_key(&cgc, ai->lsa.agid, 0x3f); if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; break; /* Get region settings */ case DVD_LU_SEND_RPC_STATE: cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); setup_report_key(&cgc, 0, 8); - memset(&rpc_state, 0, sizeof(rpc_state_t)); - cgc.buffer = (char *) &rpc_state; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; - ai->lrpcs.type = rpc_state.type_code; - ai->lrpcs.vra = rpc_state.vra; - ai->lrpcs.ucca = rpc_state.ucca; - ai->lrpcs.region_mask = rpc_state.region_mask; - ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme; + rpc_state = (rpc_state_t *)buf; + ai->lrpcs.type = rpc_state->type_code; + ai->lrpcs.vra = rpc_state->vra; + ai->lrpcs.ucca = rpc_state->ucca; + ai->lrpcs.region_mask = rpc_state->region_mask; + ai->lrpcs.rpc_scheme = rpc_state->rpc_scheme; break; /* Set region settings */ @@ -1707,20 +1764,23 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) buf[4] = ai->hrpcs.pdrc; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; break; default: cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); - return -ENOTTY; + ret = -ENOTTY; + goto err; } - - return 0; + ret = 0; +err: + kfree(buf); + return ret; } static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) { - unsigned char buf[21], *base; + unsigned char *buf, *base; struct dvd_layer *layer; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; @@ -1729,7 +1789,11 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) if (layer_num >= DVD_LAYERS) return -EINVAL; - init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); + buf = kmalloc(21, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + init_cdrom_command(&cgc, buf, 21, CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[6] = layer_num; cgc.cmd[7] = s->type; @@ -1741,7 +1805,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) cgc.quiet = 1; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; base = &buf[4]; layer = &s->physical.layer[layer_num]; @@ -1765,17 +1829,24 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; layer->bca = base[16] >> 7; - return 0; + ret = 0; +err: + kfree(buf); + return ret; } static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) { int ret; - u_char buf[8]; + u_char *buf; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); + buf = kmalloc(8, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + init_cdrom_command(&cgc, buf, 8, CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[6] = s->copyright.layer_num; cgc.cmd[7] = s->type; @@ -1783,12 +1854,15 @@ static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) cgc.cmd[9] = cgc.buflen & 0xff; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; s->copyright.cpst = buf[4]; s->copyright.rmi = buf[5]; - return 0; + ret = 0; +err: + kfree(buf); + return ret; } static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) @@ -1820,26 +1894,33 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) { int ret; - u_char buf[4 + 188]; + u_char *buf; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); + buf = kmalloc(4 + 188, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + init_cdrom_command(&cgc, buf, 4 + 188, CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[7] = s->type; cgc.cmd[9] = cgc.buflen & 0xff; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; s->bca.len = buf[0] << 8 | buf[1]; if (s->bca.len < 12 || s->bca.len > 188) { cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); - return -EIO; + ret = -EIO; + goto err; } memcpy(s->bca.value, &buf[4], s->bca.len); - - return 0; + ret = 0; +err: + kfree(buf); + return ret; } static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) @@ -1939,9 +2020,13 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, { struct cdrom_device_ops *cdo = cdi->ops; struct packet_command cgc; - char buffer[32]; + char *buffer; int ret; + buffer = kmalloc(32, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; cgc.cmd[1] = 2; /* MSF addressing */ @@ -1950,7 +2035,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, cgc.cmd[8] = 16; if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; + goto err; subchnl->cdsc_audiostatus = cgc.buffer[1]; subchnl->cdsc_format = CDROM_MSF; @@ -1965,7 +2050,10 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, subchnl->cdsc_absaddr.msf.second = cgc.buffer[10]; subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11]; - return 0; + ret = 0; +err: + kfree(buffer); + return ret; } /* diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c index 59ca35156d81..4a933d413423 100644 --- a/trunk/drivers/char/pcmcia/cm4000_cs.c +++ b/trunk/drivers/char/pcmcia/cm4000_cs.c @@ -32,9 +32,8 @@ #include #include #include -#include -#include -#include +#include +#include #include #include @@ -1406,11 +1405,11 @@ static void stop_monitor(struct cm4000_dev *dev) DEBUGP(3, dev, "<- stop_monitor\n"); } -static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) { struct cm4000_dev *dev = filp->private_data; unsigned int iobase = dev->p_dev->io.BasePort1; - struct inode *inode = filp->f_path.dentry->d_inode; struct pcmcia_device *link; int size; int rc; @@ -1427,42 +1426,38 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), iminor(inode), ioctl_names[_IOC_NR(cmd)]); - lock_kernel(); - rc = -ENODEV; link = dev_table[iminor(inode)]; if (!pcmcia_dev_present(link)) { DEBUGP(4, dev, "DEV_OK false\n"); - goto out; + return -ENODEV; } if (test_bit(IS_CMM_ABSENT, &dev->flags)) { DEBUGP(4, dev, "CMM_ABSENT flag set\n"); - goto out; + return -ENODEV; } - rc = EINVAL; if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) { DEBUGP(4, dev, "ioctype mismatch\n"); - goto out; + return -EINVAL; } if (_IOC_NR(cmd) > CM_IOC_MAXNR) { DEBUGP(4, dev, "iocnr mismatch\n"); - goto out; + return -EINVAL; } size = _IOC_SIZE(cmd); - rc = -EFAULT; + rc = 0; DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n", _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd); if (_IOC_DIR(cmd) & _IOC_READ) { if (!access_ok(VERIFY_WRITE, argp, size)) - goto out; + return -EFAULT; } if (_IOC_DIR(cmd) & _IOC_WRITE) { if (!access_ok(VERIFY_READ, argp, size)) - goto out; + return -EFAULT; } - rc = 0; switch (cmd) { case CM_IOCGSTATUS: @@ -1482,9 +1477,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (test_bit(IS_BAD_CARD, &dev->flags)) status |= CM_BAD_CARD; if (copy_to_user(argp, &status, sizeof(int))) - rc = -EFAULT; + return -EFAULT; } - break; + return 0; case CM_IOCGATR: DEBUGP(4, dev, "... in CM_IOCGATR\n"); { @@ -1497,29 +1492,25 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) { if (filp->f_flags & O_NONBLOCK) - rc = -EAGAIN; - else - rc = -ERESTARTSYS; - break; + return -EAGAIN; + return -ERESTARTSYS; } - rc = -EFAULT; if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { tmp = -1; if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int))) - break; + return -EFAULT; } else { if (copy_to_user(atreq->atr, dev->atr, dev->atr_len)) - break; + return -EFAULT; tmp = dev->atr_len; if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int))) - break; + return -EFAULT; } - rc = 0; - break; + return 0; } case CM_IOCARDOFF: @@ -1547,10 +1538,8 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) { if (filp->f_flags & O_NONBLOCK) - rc = -EAGAIN; - else - rc = -ERESTARTSYS; - break; + return -EAGAIN; + return -ERESTARTSYS; } /* Set Flags0 = 0x42 */ DEBUGP(4, dev, "Set Flags0=0x42 \n"); @@ -1565,10 +1554,8 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) || (test_bit(IS_ATR_VALID, (void *)&dev->flags) != 0)))) { if (filp->f_flags & O_NONBLOCK) - rc = -EAGAIN; - else - rc = -ERESTARTSYS; - break; + return -EAGAIN; + return -ERESTARTSYS; } } /* release lock */ @@ -1581,10 +1568,8 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ptsreq krnptsreq; if (copy_from_user(&krnptsreq, argp, - sizeof(struct ptsreq))) { - rc = -EFAULT; - break; - } + sizeof(struct ptsreq))) + return -EFAULT; rc = 0; DEBUGP(4, dev, "... in CM_IOCSPTS\n"); @@ -1595,10 +1580,8 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) { if (filp->f_flags & O_NONBLOCK) - rc = -EAGAIN; - else - rc = -ERESTARTSYS; - break; + return -EAGAIN; + return -ERESTARTSYS; } /* get IO lock */ if (wait_event_interruptible @@ -1607,10 +1590,8 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) { if (filp->f_flags & O_NONBLOCK) - rc = -EAGAIN; - else - rc = -ERESTARTSYS; - break; + return -EAGAIN; + return -ERESTARTSYS; } if ((rc = set_protocol(dev, &krnptsreq)) != 0) { @@ -1623,7 +1604,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) wake_up_interruptible(&dev->ioq); } - break; + return rc; #ifdef PCMCIA_DEBUG case CM_IOSDBGLVL: /* set debug log level */ { @@ -1631,20 +1612,18 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) old_pc_debug = pc_debug; if (copy_from_user(&pc_debug, argp, sizeof(int))) - rc = -EFAULT; - else if (old_pc_debug != pc_debug) + return -EFAULT; + + if (old_pc_debug != pc_debug) DEBUGP(0, dev, "Changed debug log level " "to %i\n", pc_debug); } - break; + return rc; #endif default: DEBUGP(4, dev, "... in default (unknown IOCTL code)\n"); - rc = -ENOTTY; + return -EINVAL; } -out: - unlock_kernel(); - return rc; } static int cmm_open(struct inode *inode, struct file *filp) @@ -1652,22 +1631,16 @@ static int cmm_open(struct inode *inode, struct file *filp) struct cm4000_dev *dev; struct pcmcia_device *link; int minor = iminor(inode); - int ret; if (minor >= CM4000_MAX_DEV) return -ENODEV; - lock_kernel(); link = dev_table[minor]; - if (link == NULL || !pcmcia_dev_present(link)) { - ret = -ENODEV; - goto out; - } + if (link == NULL || !pcmcia_dev_present(link)) + return -ENODEV; - if (link->open) { - ret = -EBUSY; - goto out; - } + if (link->open) + return -EBUSY; dev = link->priv; filp->private_data = dev; @@ -1687,10 +1660,8 @@ static int cmm_open(struct inode *inode, struct file *filp) * vaild = block until valid (or card * inserted) */ - if (filp->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto out; - } + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; dev->mdelay = T_50MSEC; @@ -1700,10 +1671,7 @@ static int cmm_open(struct inode *inode, struct file *filp) link->open = 1; /* only one open per device */ DEBUGP(2, dev, "<- cmm_open\n"); - ret = nonseekable_open(inode, filp); -out: - unlock_kernel(); - return ret; + return nonseekable_open(inode, filp); } static int cmm_close(struct inode *inode, struct file *filp) @@ -1929,7 +1897,7 @@ static const struct file_operations cm4000_fops = { .owner = THIS_MODULE, .read = cmm_read, .write = cmm_write, - .unlocked_ioctl = cmm_ioctl, + .ioctl = cmm_ioctl, .open = cmm_open, .release= cmm_close, }; diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c index 6181f8a9b0bd..035084c07329 100644 --- a/trunk/drivers/char/pcmcia/cm4040_cs.c +++ b/trunk/drivers/char/pcmcia/cm4040_cs.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -449,30 +448,23 @@ static int cm4040_open(struct inode *inode, struct file *filp) struct reader_dev *dev; struct pcmcia_device *link; int minor = iminor(inode); - int ret; if (minor >= CM_MAX_DEV) return -ENODEV; - lock_kernel(); link = dev_table[minor]; - if (link == NULL || !pcmcia_dev_present(link)) { - ret = -ENODEV; - goto out; - } + if (link == NULL || !pcmcia_dev_present(link)) + return -ENODEV; - if (link->open) { - ret = -EBUSY; - goto out; - } + if (link->open) + return -EBUSY; dev = link->priv; filp->private_data = dev; if (filp->f_flags & O_NONBLOCK) { DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); - ret = -EAGAIN; - goto out; + return -EAGAIN; } link->open = 1; @@ -481,10 +473,7 @@ static int cm4040_open(struct inode *inode, struct file *filp) mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD); DEBUGP(2, dev, "<- cm4040_open (successfully)\n"); - ret = nonseekable_open(inode, filp); -out: - unlock_kernel(); - return ret; + return nonseekable_open(inode, filp); } static int cm4040_close(struct inode *inode, struct file *filp) diff --git a/trunk/drivers/char/pcmcia/ipwireless/main.c b/trunk/drivers/char/pcmcia/ipwireless/main.c index cc7dcea2d283..00c7f8407e3e 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/main.c +++ b/trunk/drivers/char/pcmcia/ipwireless/main.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index 8dbf4d9b6447..3381424d70a1 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -63,11 +63,11 @@ MODULE_LICENSE("Dual MPL/GPL"); #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0) -#ifdef CONFIG_PCMCIA_DEBUG -INT_MODULE_PARM(pc_debug, 0); +#ifdef PCMCIA_DEBUG +INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -/*static char *version = -"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";*/ +static char *version = +"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -375,7 +375,7 @@ static int ide_config(struct pcmcia_device *link) ======================================================================*/ -static void ide_release(struct pcmcia_device *link) +void ide_release(struct pcmcia_device *link) { ide_info_t *info = link->priv; ide_hwif_t *hwif = info->hwif; diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index 6a866d7c8ae5..10748240cb2f 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -50,19 +50,17 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) /** * linear_mergeable_bvec -- tell bio layer if two requests can be merged * @q: request queue - * @bvm: properties of new bio + * @bio: the buffer head that's been built up so far * @biovec: the request that could be merged to it. * * Return amount of bytes we can take at this offset */ -static int linear_mergeable_bvec(struct request_queue *q, - struct bvec_merge_data *bvm, - struct bio_vec *biovec) +static int linear_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; dev_info_t *dev0; - unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9; - sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); + unsigned long maxsectors, bio_sectors = bio->bi_size >> 9; + sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); dev0 = which_dev(mddev, sector); maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index bcbb82594a19..914c04ddec7c 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -241,20 +241,18 @@ static int create_strip_zones (mddev_t *mddev) /** * raid0_mergeable_bvec -- tell bio layer if a two requests can be merged * @q: request queue - * @bvm: properties of new bio + * @bio: the buffer head that's been built up so far * @biovec: the request that could be merged to it. * * Return amount of bytes we can accept at this offset */ -static int raid0_mergeable_bvec(struct request_queue *q, - struct bvec_merge_data *bvm, - struct bio_vec *biovec) +static int raid0_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; - sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); + sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_size >> 9; - unsigned int bio_sectors = bvm->bi_size >> 9; + unsigned int bio_sectors = bio->bi_size >> 9; max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; if (max < 0) max = 0; /* bio_add cannot handle a negative return */ diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 22bb2b1b886d..a71277b640ab 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -439,27 +439,26 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev) /** * raid10_mergeable_bvec -- tell bio layer if a two requests can be merged * @q: request queue - * @bvm: properties of new bio + * @bio: the buffer head that's been built up so far * @biovec: the request that could be merged to it. * * Return amount of bytes we can accept at this offset * If near_copies == raid_disk, there are no striping issues, * but in that case, the function isn't called at all. */ -static int raid10_mergeable_bvec(struct request_queue *q, - struct bvec_merge_data *bvm, - struct bio_vec *biovec) +static int raid10_mergeable_bvec(struct request_queue *q, struct bio *bio, + struct bio_vec *bio_vec) { mddev_t *mddev = q->queuedata; - sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); + sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_size >> 9; - unsigned int bio_sectors = bvm->bi_size >> 9; + unsigned int bio_sectors = bio->bi_size >> 9; max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; if (max < 0) max = 0; /* bio_add cannot handle a negative return */ - if (max <= biovec->bv_len && bio_sectors == 0) - return biovec->bv_len; + if (max <= bio_vec->bv_len && bio_sectors == 0) + return bio_vec->bv_len; else return max; } diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 9ce7154845c6..3b27df52456b 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -3314,17 +3314,15 @@ static int raid5_congested(void *data, int bits) /* We want read requests to align with chunks where possible, * but write requests don't need to. */ -static int raid5_mergeable_bvec(struct request_queue *q, - struct bvec_merge_data *bvm, - struct bio_vec *biovec) +static int raid5_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; - sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); + sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_size >> 9; - unsigned int bio_sectors = bvm->bi_size >> 9; + unsigned int bio_sectors = bio->bi_size >> 9; - if ((bvm->bi_rw & 1) == WRITE) + if (bio_data_dir(bio) == WRITE) return biovec->bv_len; /* always allow writes to be mergeable */ max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; diff --git a/trunk/drivers/mtd/ftl.c b/trunk/drivers/mtd/ftl.c index 5c29872184e6..4a79b187b568 100644 --- a/trunk/drivers/mtd/ftl.c +++ b/trunk/drivers/mtd/ftl.c @@ -130,6 +130,10 @@ typedef struct partition_t { u_int16_t DataUnits; u_int32_t BlocksPerUnit; erase_unit_header_t header; +#if 0 + region_info_t region; + memory_handle_t handle; +#endif } partition_t; /* Partition state flags */ diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c index 0cc31675aeb9..1912d968718b 100644 --- a/trunk/drivers/mtd/maps/pcmciamtd.c +++ b/trunk/drivers/mtd/maps/pcmciamtd.c @@ -498,14 +498,17 @@ static int pcmciamtd_config(struct pcmcia_device *link) int i; config_info_t t; static char *probes[] = { "jedec_probe", "cfi_probe" }; + cisinfo_t cisinfo; int new_name = 0; DEBUG(3, "link=0x%p", link); DEBUG(2, "Validating CIS"); - ret = pcmcia_validate_cis(link, NULL); + ret = pcmcia_validate_cis(link, &cisinfo); if(ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); + } else { + DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); } card_settings(dev, link, &new_name); @@ -560,7 +563,9 @@ static int pcmciamtd_config(struct pcmcia_device *link) DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win); + CS_CHECK(GetStatus, pcmcia_get_status(link, &status)); + DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", + status.CardState, (unsigned long)link->win); dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index ef671d1a3bf0..d26f69b0184f 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -1324,7 +1324,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) goto fail; } - txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); + txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_KERNEL); if (!txs) { err = -ENOMEM; xenbus_dev_fatal(dev, err, "allocating tx ring page"); @@ -1340,7 +1340,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) } info->tx_ring_ref = err; - rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); + rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_KERNEL); if (!rxs) { err = -ENOMEM; xenbus_dev_fatal(dev, err, "allocating rx ring page"); diff --git a/trunk/drivers/pcmcia/Kconfig b/trunk/drivers/pcmcia/Kconfig index e45402adac3f..1b0eb5aaf650 100644 --- a/trunk/drivers/pcmcia/Kconfig +++ b/trunk/drivers/pcmcia/Kconfig @@ -263,13 +263,6 @@ config OMAP_CF Say Y here to support the CompactFlash controller on OMAP. Note that this doesn't support "True IDE" mode. -config BFIN_CFPCMCIA - tristate "Blackfin CompactFlash PCMCIA Driver" - depends on PCMCIA && BLACKFIN - help - Say Y here to support the CompactFlash PCMCIA driver for Blackfin. - - config AT91_CF tristate "AT91 CompactFlash Controller" depends on PCMCIA && ARCH_AT91RM9200 diff --git a/trunk/drivers/pcmcia/Makefile b/trunk/drivers/pcmcia/Makefile index 85c6cc931f97..6f6478ba7174 100644 --- a/trunk/drivers/pcmcia/Makefile +++ b/trunk/drivers/pcmcia/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o -obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o obj-$(CONFIG_AT91_CF) += at91_cf.o obj-$(CONFIG_ELECTRA_CF) += electra_cf.o diff --git a/trunk/drivers/pcmcia/au1000_generic.h b/trunk/drivers/pcmcia/au1000_generic.h index a53ef5902518..1e467bb54077 100644 --- a/trunk/drivers/pcmcia/au1000_generic.h +++ b/trunk/drivers/pcmcia/au1000_generic.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "cs_internal.h" @@ -33,9 +34,9 @@ #define AU1000_PCMCIA_IO_SPEED (255) #define AU1000_PCMCIA_MEM_SPEED (300) -#define AU1X_SOCK0_IO 0xF00000000ULL -#define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL -#define AU1X_SOCK0_PHYS_MEM 0xF80000000ULL +#define AU1X_SOCK0_IO 0xF00000000 +#define AU1X_SOCK0_PHYS_ATTR 0xF40000000 +#define AU1X_SOCK0_PHYS_MEM 0xF80000000 /* pseudo 32 bit phys addresses, which get fixed up to the * real 36 bit address in fixup_bigphys_addr() */ #define AU1X_SOCK0_PSEUDO_PHYS_ATTR 0xF4000000 @@ -44,20 +45,16 @@ /* pcmcia socket 1 needs external glue logic so the memory map * differs from board to board. */ -#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || \ - defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || \ - defined(CONFIG_MIPS_PB1200) -#define AU1X_SOCK1_IO 0xF08000000ULL -#define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL -#define AU1X_SOCK1_PHYS_MEM 0xF88000000ULL +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_PB1200) +#define AU1X_SOCK1_IO 0xF08000000 +#define AU1X_SOCK1_PHYS_ATTR 0xF48000000 +#define AU1X_SOCK1_PHYS_MEM 0xF88000000 #define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000 #define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8800000 -#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \ - defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || \ - defined(CONFIG_MIPS_DB1200) -#define AU1X_SOCK1_IO 0xF04000000ULL -#define AU1X_SOCK1_PHYS_ATTR 0xF44000000ULL -#define AU1X_SOCK1_PHYS_MEM 0xF84000000ULL +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || defined(CONFIG_MIPS_DB1200) +#define AU1X_SOCK1_IO 0xF04000000 +#define AU1X_SOCK1_PHYS_ATTR 0xF44000000 +#define AU1X_SOCK1_PHYS_MEM 0xF84000000 #define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000 #define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8400000 #endif diff --git a/trunk/drivers/pcmcia/au1000_pb1x00.c b/trunk/drivers/pcmcia/au1000_pb1x00.c index aa1cd4d3aa29..157e41423a0a 100644 --- a/trunk/drivers/pcmcia/au1000_pb1x00.c +++ b/trunk/drivers/pcmcia/au1000_pb1x00.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include "cs_internal.h" diff --git a/trunk/drivers/pcmcia/au1000_xxs1500.c b/trunk/drivers/pcmcia/au1000_xxs1500.c index 8a9b18cee847..c78ed5347510 100644 --- a/trunk/drivers/pcmcia/au1000_xxs1500.c +++ b/trunk/drivers/pcmcia/au1000_xxs1500.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include "cs_internal.h" diff --git a/trunk/drivers/pcmcia/bfin_cf_pcmcia.c b/trunk/drivers/pcmcia/bfin_cf_pcmcia.c deleted file mode 100644 index bb7338863fb9..000000000000 --- a/trunk/drivers/pcmcia/bfin_cf_pcmcia.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * file: drivers/pcmcia/bfin_cf.c - * - * based on: drivers/pcmcia/omap_cf.c - * omap_cf.c -- OMAP 16xx CompactFlash controller driver - * - * Copyright (c) 2005 David Brownell - * Copyright (c) 2006-2008 Michael Hennerich Analog Devices Inc. - * - * bugs: enter bugs at http://blackfin.uclinux.org/ - * - * this program is free software; you can redistribute it and/or modify - * it under the terms of the gnu general public license as published by - * the free software foundation; either version 2, or (at your option) - * any later version. - * - * this program is distributed in the hope that it will be useful, - * but without any warranty; without even the implied warranty of - * merchantability or fitness for a particular purpose. see the - * gnu general public license for more details. - * - * you should have received a copy of the gnu general public license - * along with this program; see the file copying. - * if not, write to the free software foundation, - * 59 temple place - suite 330, boston, ma 02111-1307, usa. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define SZ_1K 0x00000400 -#define SZ_8K 0x00002000 -#define SZ_2K (2 * SZ_1K) - -#define POLL_INTERVAL (2 * HZ) - -#define CF_ATASEL_ENA 0x20311802 /* Inverts RESET */ -#define CF_ATASEL_DIS 0x20311800 - -#define bfin_cf_present(pfx) (gpio_get_value(pfx)) - -/*--------------------------------------------------------------------------*/ - -static const char driver_name[] = "bfin_cf_pcmcia"; - -struct bfin_cf_socket { - struct pcmcia_socket socket; - - struct timer_list timer; - unsigned present:1; - unsigned active:1; - - struct platform_device *pdev; - unsigned long phys_cf_io; - unsigned long phys_cf_attr; - u_int irq; - u_short cd_pfx; -}; - -/*--------------------------------------------------------------------------*/ -static int bfin_cf_reset(void) -{ - outw(0, CF_ATASEL_ENA); - mdelay(200); - outw(0, CF_ATASEL_DIS); - - return 0; -} - -static int bfin_cf_ss_init(struct pcmcia_socket *s) -{ - return 0; -} - -/* the timer is primarily to kick this socket's pccardd */ -static void bfin_cf_timer(unsigned long _cf) -{ - struct bfin_cf_socket *cf = (void *)_cf; - unsigned short present = bfin_cf_present(cf->cd_pfx); - - if (present != cf->present) { - cf->present = present; - dev_dbg(&cf->pdev->dev, ": card %s\n", - present ? "present" : "gone"); - pcmcia_parse_events(&cf->socket, SS_DETECT); - } - - if (cf->active) - mod_timer(&cf->timer, jiffies + POLL_INTERVAL); -} - -static int bfin_cf_get_status(struct pcmcia_socket *s, u_int *sp) -{ - struct bfin_cf_socket *cf; - - if (!sp) - return -EINVAL; - - cf = container_of(s, struct bfin_cf_socket, socket); - - if (bfin_cf_present(cf->cd_pfx)) { - *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; - s->irq.AssignedIRQ = 0; - s->pci_irq = cf->irq; - - } else - *sp = 0; - return 0; -} - -static int -bfin_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) -{ - - struct bfin_cf_socket *cf; - cf = container_of(sock, struct bfin_cf_socket, socket); - - switch (s->Vcc) { - case 0: - case 33: - break; - case 50: - break; - default: - return -EINVAL; - } - - if (s->flags & SS_RESET) { - disable_irq(cf->irq); - bfin_cf_reset(); - enable_irq(cf->irq); - } - - dev_dbg(&cf->pdev->dev, ": Vcc %d, io_irq %d, flags %04x csc %04x\n", - s->Vcc, s->io_irq, s->flags, s->csc_mask); - - return 0; -} - -static int bfin_cf_ss_suspend(struct pcmcia_socket *s) -{ - return bfin_cf_set_socket(s, &dead_socket); -} - -/* regions are 2K each: mem, attrib, io (and reserved-for-ide) */ - -static int bfin_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) -{ - struct bfin_cf_socket *cf; - - cf = container_of(s, struct bfin_cf_socket, socket); - io->flags &= MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT; - io->start = cf->phys_cf_io; - io->stop = io->start + SZ_2K - 1; - return 0; -} - -static int -bfin_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) -{ - struct bfin_cf_socket *cf; - - if (map->card_start) - return -EINVAL; - cf = container_of(s, struct bfin_cf_socket, socket); - map->static_start = cf->phys_cf_io; - map->flags &= MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT; - if (map->flags & MAP_ATTRIB) - map->static_start = cf->phys_cf_attr; - - return 0; -} - -static struct pccard_operations bfin_cf_ops = { - .init = bfin_cf_ss_init, - .suspend = bfin_cf_ss_suspend, - .get_status = bfin_cf_get_status, - .set_socket = bfin_cf_set_socket, - .set_io_map = bfin_cf_set_io_map, - .set_mem_map = bfin_cf_set_mem_map, -}; - -/*--------------------------------------------------------------------------*/ - -static int __devinit bfin_cf_probe(struct platform_device *pdev) -{ - struct bfin_cf_socket *cf; - struct resource *io_mem, *attr_mem; - int irq; - unsigned short cd_pfx; - int status = 0; - - dev_info(&pdev->dev, "Blackfin CompactFlash/PCMCIA Socket Driver\n"); - - irq = platform_get_irq(pdev, 0); - if (!irq) - return -EINVAL; - - cd_pfx = platform_get_irq(pdev, 1); /*Card Detect GPIO PIN */ - - if (gpio_request(cd_pfx, "pcmcia: CD")) { - dev_err(&pdev->dev, - "Failed ro request Card Detect GPIO_%d\n", - cd_pfx); - return -EBUSY; - } - gpio_direction_input(cd_pfx); - - cf = kzalloc(sizeof *cf, GFP_KERNEL); - if (!cf) { - gpio_free(cd_pfx); - return -ENOMEM; - } - - cf->cd_pfx = cd_pfx; - - setup_timer(&cf->timer, bfin_cf_timer, (unsigned long)cf); - - cf->pdev = pdev; - platform_set_drvdata(pdev, cf); - - cf->irq = irq; - cf->socket.pci_irq = irq; - - set_irq_type(irq, IRQF_TRIGGER_LOW); - - io_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - attr_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - - if (!io_mem || !attr_mem) - goto fail0; - - cf->phys_cf_io = io_mem->start; - cf->phys_cf_attr = attr_mem->start; - - /* pcmcia layer only remaps "real" memory */ - cf->socket.io_offset = (unsigned long) - ioremap(cf->phys_cf_io, SZ_2K); - - if (!cf->socket.io_offset) - goto fail0; - - dev_err(&pdev->dev, ": on irq %d\n", irq); - - dev_dbg(&pdev->dev, ": %s\n", - bfin_cf_present(cf->cd_pfx) ? "present" : "(not present)"); - - cf->socket.owner = THIS_MODULE; - cf->socket.dev.parent = &pdev->dev; - cf->socket.ops = &bfin_cf_ops; - cf->socket.resource_ops = &pccard_static_ops; - cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP - | SS_CAP_MEM_ALIGN; - cf->socket.map_size = SZ_2K; - - status = pcmcia_register_socket(&cf->socket); - if (status < 0) - goto fail2; - - cf->active = 1; - mod_timer(&cf->timer, jiffies + POLL_INTERVAL); - return 0; - -fail2: - iounmap((void __iomem *)cf->socket.io_offset); - release_mem_region(cf->phys_cf_io, SZ_8K); - -fail0: - gpio_free(cf->cd_pfx); - kfree(cf); - platform_set_drvdata(pdev, NULL); - - return status; -} - -static int __devexit bfin_cf_remove(struct platform_device *pdev) -{ - struct bfin_cf_socket *cf = platform_get_drvdata(pdev); - - gpio_free(cf->cd_pfx); - cf->active = 0; - pcmcia_unregister_socket(&cf->socket); - del_timer_sync(&cf->timer); - iounmap((void __iomem *)cf->socket.io_offset); - release_mem_region(cf->phys_cf_io, SZ_8K); - platform_set_drvdata(pdev, NULL); - kfree(cf); - return 0; -} - -static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return pcmcia_socket_dev_suspend(&pdev->dev, mesg); -} - -static int bfin_cf_resume(struct platform_device *pdev) -{ - return pcmcia_socket_dev_resume(&pdev->dev); -} - -static struct platform_driver bfin_cf_driver = { - .driver = { - .name = (char *)driver_name, - .owner = THIS_MODULE, - }, - .probe = bfin_cf_probe, - .remove = __devexit_p(bfin_cf_remove), - .suspend = bfin_cf_suspend, - .resume = bfin_cf_resume, -}; - -static int __init bfin_cf_init(void) -{ - return platform_driver_register(&bfin_cf_driver); -} - -static void __exit bfin_cf_exit(void) -{ - platform_driver_unregister(&bfin_cf_driver); -} - -module_init(bfin_cf_init); -module_exit(bfin_cf_exit); - -MODULE_AUTHOR("Michael Hennerich ") -MODULE_DESCRIPTION("BFIN CF/PCMCIA Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/pcmcia/cardbus.c b/trunk/drivers/pcmcia/cardbus.c index 911ca0e8dfc2..fb2f38dc92c5 100644 --- a/trunk/drivers/pcmcia/cardbus.c +++ b/trunk/drivers/pcmcia/cardbus.c @@ -30,9 +30,11 @@ #include #include +#define IN_CARD_SERVICES #include #include #include +#include #include #include "cs_internal.h" diff --git a/trunk/drivers/pcmcia/cistpl.c b/trunk/drivers/pcmcia/cistpl.c index 9fcff0c33619..36379535f9da 100644 --- a/trunk/drivers/pcmcia/cistpl.c +++ b/trunk/drivers/pcmcia/cistpl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "cs_internal.h" @@ -1438,11 +1439,10 @@ EXPORT_SYMBOL(pccard_read_tuple); ======================================================================*/ -int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *info) +int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info) { tuple_t *tuple; cisparse_t *p; - unsigned int count = 0; int ret, reserved, dev_ok = 0, ident_ok = 0; if (!s) @@ -1457,7 +1457,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned return CS_OUT_OF_RESOURCE; } - count = reserved = 0; + info->Chains = reserved = 0; tuple->DesiredTuple = RETURN_FIRST_TUPLE; tuple->Attributes = TUPLE_RETURN_COMMON; ret = pccard_get_first_tuple(s, function, tuple); @@ -1482,7 +1482,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned if (!dev_ok && !ident_ok) goto done; - for (count = 1; count < MAX_TUPLES; count++) { + for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) { ret = pccard_get_next_tuple(s, function, tuple); if (ret != CS_SUCCESS) break; if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || @@ -1490,13 +1490,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) reserved++; } - if ((count) || (reserved > 5) || - ((!dev_ok || !ident_ok) && (count > 10))) - count = 0; + if ((info->Chains == MAX_TUPLES) || (reserved > 5) || + ((!dev_ok || !ident_ok) && (info->Chains > 10))) + info->Chains = 0; done: - if (info) - *info = count; kfree(tuple); kfree(p); return CS_SUCCESS; diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index d1207393fc3e..29276bd28295 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -32,9 +32,11 @@ #include #include +#define IN_CARD_SERVICES #include #include #include +#include #include #include #include @@ -236,6 +238,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) init_completion(&socket->socket_released); init_completion(&socket->thread_done); + init_waitqueue_head(&socket->thread_wait); mutex_init(&socket->skt_mutex); spin_lock_init(&socket->thread_lock); @@ -275,9 +278,10 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket) cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops); - if (socket->thread) + if (socket->thread) { + wake_up(&socket->thread_wait); kthread_stop(socket->thread); - + } release_cis_mem(socket); /* remove from our own list */ @@ -631,6 +635,7 @@ static void socket_detect_change(struct pcmcia_socket *skt) static int pccardd(void *__skt) { struct pcmcia_socket *skt = __skt; + DECLARE_WAITQUEUE(wait, current); int ret; skt->thread = current; @@ -651,6 +656,7 @@ static int pccardd(void *__skt) if (ret) dev_warn(&skt->dev, "err %d adding socket attributes\n", ret); + add_wait_queue(&skt->thread_wait, &wait); complete(&skt->thread_done); set_freezable(); @@ -688,6 +694,8 @@ static int pccardd(void *__skt) /* make sure we are running before we exit */ set_current_state(TASK_RUNNING); + remove_wait_queue(&skt->thread_wait, &wait); + /* remove from the device core */ pccard_sysfs_remove_socket(&skt->dev); device_unregister(&skt->dev); @@ -708,7 +716,7 @@ void pcmcia_parse_events(struct pcmcia_socket *s, u_int events) s->thread_events |= events; spin_unlock_irqrestore(&s->thread_lock, flags); - wake_up_process(s->thread); + wake_up(&s->thread_wait); } } /* pcmcia_parse_events */ EXPORT_SYMBOL(pcmcia_parse_events); diff --git a/trunk/drivers/pcmcia/cs_internal.h b/trunk/drivers/pcmcia/cs_internal.h index 63dc1a28bda2..e7d5d141f24d 100644 --- a/trunk/drivers/pcmcia/cs_internal.h +++ b/trunk/drivers/pcmcia/cs_internal.h @@ -26,6 +26,18 @@ #define CLIENT_WIN_REQ(i) (0x1<<(i)) #define CLIENT_CARDBUS 0x8000 +#define REGION_MAGIC 0xE3C9 +typedef struct region_t { + u_short region_magic; + u_short state; + dev_info_t dev_info; + struct pcmcia_device *mtd; + u_int MediaID; + region_info_t info; +} region_t; + +#define REGION_STALE 0x01 + /* Each card function gets one of these guys */ typedef struct config_t { struct kref ref; @@ -118,6 +130,7 @@ extern struct list_head pcmcia_socket_list; int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req); int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config); int pccard_reset_card(struct pcmcia_socket *skt); +int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status); struct pcmcia_callback{ diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 4174d9656e35..e40775443d04 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -25,6 +25,7 @@ #include #include +#define IN_CARD_SERVICES #include #include #include @@ -740,8 +741,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f static int pcmcia_card_add(struct pcmcia_socket *s) { + cisinfo_t cisinfo; cistpl_longlink_mfc_t mfc; - unsigned int no_funcs, i, no_chains; + unsigned int no_funcs, i; int ret = 0; if (!(s->resource_setup_done)) { @@ -755,8 +757,8 @@ static int pcmcia_card_add(struct pcmcia_socket *s) return -EAGAIN; /* try again, but later... */ } - ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains); - if (ret || !no_chains) { + ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); + if (ret || !cisinfo.Chains) { ds_dbg(0, "invalid CIS or invalid resources\n"); return -ENODEV; } @@ -850,7 +852,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) { struct pcmcia_socket *s = dev->socket; const struct firmware *fw; - char path[FIRMWARE_NAME_MAX]; + char path[20]; int ret = -ENOMEM; int no_funcs; int old_funcs; @@ -862,7 +864,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) ds_dbg(1, "trying to load CIS file %s\n", filename); - if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) { + if (strlen(filename) > 14) { printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n", filename); return -EINVAL; diff --git a/trunk/drivers/pcmcia/hd64465_ss.c b/trunk/drivers/pcmcia/hd64465_ss.c index fb2bc1fb015d..f2e810f53c81 100644 --- a/trunk/drivers/pcmcia/hd64465_ss.c +++ b/trunk/drivers/pcmcia/hd64465_ss.c @@ -1,4 +1,6 @@ /* + * $Id: hd64465_ss.c,v 1.7 2003/07/06 14:42:50 lethal Exp $ + * * Device driver for the PCMCIA controller module of the * Hitachi HD64465 handheld companion chip. * @@ -46,6 +48,7 @@ #include #include #include +#include #include "cs_internal.h" #define MODNAME "hd64465_ss" diff --git a/trunk/drivers/pcmcia/i82092.c b/trunk/drivers/pcmcia/i82092.c index 46561face128..e13618656ff7 100644 --- a/trunk/drivers/pcmcia/i82092.c +++ b/trunk/drivers/pcmcia/i82092.c @@ -5,6 +5,8 @@ * * Author: Arjan Van De Ven * Loosly based on i82365.c from the pcmcia-cs package + * + * $Id: i82092aa.c,v 1.2 2001/10/23 14:43:34 arjanv Exp $ */ #include diff --git a/trunk/drivers/pcmcia/i82092aa.h b/trunk/drivers/pcmcia/i82092aa.h index 8836d393ad02..b0d453303c5d 100644 --- a/trunk/drivers/pcmcia/i82092aa.h +++ b/trunk/drivers/pcmcia/i82092aa.h @@ -3,6 +3,8 @@ #include +/* $Id: i82092aa.h,v 1.1.1.1 2001/09/19 14:53:15 dwmw2 Exp $ */ + /* Debuging defines */ #ifdef NOTRACE #define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) diff --git a/trunk/drivers/pcmcia/i82365.c b/trunk/drivers/pcmcia/i82365.c index 68f6b2702bc4..32a2ab119798 100644 --- a/trunk/drivers/pcmcia/i82365.c +++ b/trunk/drivers/pcmcia/i82365.c @@ -1263,7 +1263,7 @@ static int __init init_i82365(void) ret = driver_register(&i82365_driver); if (ret) - goto err_out; + return ret; i82365_device = platform_device_alloc("i82365", 0); if (i82365_device) { @@ -1273,8 +1273,10 @@ static int __init init_i82365(void) } else ret = -ENOMEM; - if (ret) - goto err_driver_unregister; + if (ret) { + driver_unregister(&i82365_driver); + return ret; + } printk(KERN_INFO "Intel ISA PCIC probe: "); sockets = 0; @@ -1283,17 +1285,16 @@ static int __init init_i82365(void) if (sockets == 0) { printk("not found.\n"); - ret = -ENODEV; - goto err_dev_unregister; + platform_device_unregister(i82365_device); + release_region(i365_base, 2); + driver_unregister(&i82365_driver); + return -ENODEV; } /* Set up interrupt handler(s) */ if (grab_irq != 0) - ret = request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); - - if (ret) - goto err_socket_release; - + request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); + /* register sockets with the pcmcia core */ for (i = 0; i < sockets; i++) { socket[i].socket.dev.parent = &i82365_device->dev; @@ -1323,23 +1324,7 @@ static int __init init_i82365(void) } return 0; -err_socket_release: - for (i = 0; i < sockets; i++) { - /* Turn off all interrupt sources! */ - i365_set(i, I365_CSCINT, 0); - release_region(socket[i].ioaddr, 2); - } -err_dev_unregister: - platform_device_unregister(i82365_device); - release_region(i365_base, 2); -#ifdef CONFIG_PNP - if (i82365_pnpdev) - pnp_disable_dev(i82365_pnpdev); -#endif -err_driver_unregister: - driver_unregister(&i82365_driver); -err_out: - return ret; + } /* init_i82365 */ static void __exit exit_i82365(void) diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index 13a5fbd50a07..ac70d2cb7dd4 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -1,7 +1,7 @@ /* * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series. * - * (C) 1999-2000 Magnus Damm + * (C) 1999-2000 Magnus Damm * (C) 2001-2002 Montavista Software, Inc. * * @@ -60,6 +60,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index afd00e7bbbef..5f186abca108 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -29,10 +29,10 @@ #include #include +#define IN_CARD_SERVICES #include #include #include -#include #include #include @@ -138,154 +138,6 @@ static int proc_read_drivers(char *buf, char **start, off_t pos, } #endif - -#ifdef CONFIG_PCMCIA_PROBE - -static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) -{ - int irq; - u32 mask; - - irq = adj->resource.irq.IRQ; - if ((irq < 0) || (irq > 15)) - return CS_BAD_IRQ; - - if (adj->Action != REMOVE_MANAGED_RESOURCE) - return 0; - - mask = 1 << irq; - - if (!(s->irq_mask & mask)) - return 0; - - s->irq_mask &= ~mask; - - return 0; -} - -#else - -static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { - return CS_SUCCESS; -} - -#endif - -static int pcmcia_adjust_resource_info(adjust_t *adj) -{ - struct pcmcia_socket *s; - int ret = CS_UNSUPPORTED_FUNCTION; - unsigned long flags; - - down_read(&pcmcia_socket_list_rwsem); - list_for_each_entry(s, &pcmcia_socket_list, socket_list) { - - if (adj->Resource == RES_IRQ) - ret = adjust_irq(s, adj); - - else if (s->resource_ops->add_io) { - unsigned long begin, end; - - /* you can't use the old interface if the new - * one was used before */ - spin_lock_irqsave(&s->lock, flags); - if ((s->resource_setup_new) && - !(s->resource_setup_old)) { - spin_unlock_irqrestore(&s->lock, flags); - continue; - } else if (!(s->resource_setup_old)) - s->resource_setup_old = 1; - spin_unlock_irqrestore(&s->lock, flags); - - switch (adj->Resource) { - case RES_MEMORY_RANGE: - begin = adj->resource.memory.Base; - end = adj->resource.memory.Base + adj->resource.memory.Size - 1; - if (s->resource_ops->add_mem) - ret =s->resource_ops->add_mem(s, adj->Action, begin, end); - case RES_IO_RANGE: - begin = adj->resource.io.BasePort; - end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1; - if (s->resource_ops->add_io) - ret = s->resource_ops->add_io(s, adj->Action, begin, end); - } - if (!ret) { - /* as there's no way we know this is the - * last call to adjust_resource_info, we - * always need to assume this is the latest - * one... */ - spin_lock_irqsave(&s->lock, flags); - s->resource_setup_done = 1; - spin_unlock_irqrestore(&s->lock, flags); - } - } - } - up_read(&pcmcia_socket_list_rwsem); - - return (ret); -} - -/** pccard_get_status - * - * Get the current socket state bits. We don't support the latched - * SocketState yet: I haven't seen any point for it. - */ - -static int pccard_get_status(struct pcmcia_socket *s, - struct pcmcia_device *p_dev, - cs_status_t *status) -{ - config_t *c; - int val; - - s->ops->get_status(s, &val); - status->CardState = status->SocketState = 0; - status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0; - status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0; - status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0; - status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0; - if (s->state & SOCKET_SUSPEND) - status->CardState |= CS_EVENT_PM_SUSPEND; - if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; - - c = (p_dev) ? p_dev->function_config : NULL; - - if ((c != NULL) && (c->state & CONFIG_LOCKED) && - (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { - u_char reg; - if (c->CardValues & PRESENT_PIN_REPLACE) { - pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); - status->CardState |= - (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; - status->CardState |= - (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0; - status->CardState |= - (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0; - status->CardState |= - (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0; - } else { - /* No PRR? Then assume we're always ready */ - status->CardState |= CS_EVENT_READY_CHANGE; - } - if (c->CardValues & PRESENT_EXT_STATUS) { - pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); - status->CardState |= - (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; - } - return CS_SUCCESS; - } - status->CardState |= - (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; - status->CardState |= - (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0; - status->CardState |= - (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; - status->CardState |= - (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; - return CS_SUCCESS; -} /* pccard_get_status */ - /*====================================================================== These manage a ring buffer of events pending for one user process @@ -694,6 +546,8 @@ static u_int ds_poll(struct file *file, poll_table *wait) /*====================================================================*/ +extern int pcmcia_adjust_resource_info(adjust_t *adj); + static int ds_ioctl(struct inode * inode, struct file * file, u_int cmd, u_long arg) { @@ -795,7 +649,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, mutex_lock(&s->skt_mutex); pcmcia_validate_mem(s); mutex_unlock(&s->skt_mutex); - ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains); + ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo); break; case DS_SUSPEND_CARD: ret = pcmcia_suspend_card(s); diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index 4884a18cf9e6..1d128fbd1a92 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -21,9 +21,11 @@ #include #include +#define IN_CARD_SERVICES #include #include #include +#include #include #include #include @@ -309,6 +311,74 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, EXPORT_SYMBOL(pcmcia_get_window); +/** pccard_get_status + * + * Get the current socket state bits. We don't support the latched + * SocketState yet: I haven't seen any point for it. + */ + +int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, + cs_status_t *status) +{ + config_t *c; + int val; + + s->ops->get_status(s, &val); + status->CardState = status->SocketState = 0; + status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0; + status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0; + status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0; + status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0; + if (s->state & SOCKET_SUSPEND) + status->CardState |= CS_EVENT_PM_SUSPEND; + if (!(s->state & SOCKET_PRESENT)) + return CS_NO_CARD; + + c = (p_dev) ? p_dev->function_config : NULL; + + if ((c != NULL) && (c->state & CONFIG_LOCKED) && + (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { + u_char reg; + if (c->CardValues & PRESENT_PIN_REPLACE) { + pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); + status->CardState |= + (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; + status->CardState |= + (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0; + status->CardState |= + (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0; + status->CardState |= + (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0; + } else { + /* No PRR? Then assume we're always ready */ + status->CardState |= CS_EVENT_READY_CHANGE; + } + if (c->CardValues & PRESENT_EXT_STATUS) { + pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); + status->CardState |= + (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; + } + return CS_SUCCESS; + } + status->CardState |= + (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; + status->CardState |= + (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0; + status->CardState |= + (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; + status->CardState |= + (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; + return CS_SUCCESS; +} /* pccard_get_status */ + +int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status) +{ + return pccard_get_status(p_dev->socket, p_dev, status); +} +EXPORT_SYMBOL(pcmcia_get_status); + + + /** pcmcia_get_mem_page * * Change the card address of an already open memory window. @@ -742,15 +812,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) type = IRQF_SHARED; #ifdef CONFIG_PCMCIA_PROBE - -#ifdef IRQ_NOAUTOEN - /* if the underlying IRQ infrastructure allows for it, only allocate - * the IRQ, but do not enable it - */ - if (!(req->Attributes & IRQ_HANDLE_PRESENT)) - type |= IRQ_NOAUTOEN; -#endif /* IRQ_NOAUTOEN */ - if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must be the same */ irq = s->irq.AssignedIRQ; @@ -905,7 +966,7 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { pcmcia_release_configuration(p_dev); pcmcia_release_io(p_dev, &p_dev->io); pcmcia_release_irq(p_dev, &p_dev->irq); - if (p_dev->win) + if (&p_dev->win) pcmcia_release_window(p_dev->win); } EXPORT_SYMBOL(pcmcia_disable_device); diff --git a/trunk/drivers/pcmcia/pxa2xx_base.c b/trunk/drivers/pcmcia/pxa2xx_base.c index ccfdf1969a7f..9414163c78e7 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.c +++ b/trunk/drivers/pcmcia/pxa2xx_base.c @@ -33,6 +33,7 @@ #include #include +#include #include #include "cs_internal.h" diff --git a/trunk/drivers/pcmcia/rsrc_mgr.c b/trunk/drivers/pcmcia/rsrc_mgr.c index c0e2afc79e3e..ce2226273aaa 100644 --- a/trunk/drivers/pcmcia/rsrc_mgr.c +++ b/trunk/drivers/pcmcia/rsrc_mgr.c @@ -21,6 +21,86 @@ #include "cs_internal.h" +#ifdef CONFIG_PCMCIA_IOCTL + +#ifdef CONFIG_PCMCIA_PROBE + +static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) +{ + int irq; + u32 mask; + + irq = adj->resource.irq.IRQ; + if ((irq < 0) || (irq > 15)) + return CS_BAD_IRQ; + + if (adj->Action != REMOVE_MANAGED_RESOURCE) + return 0; + + mask = 1 << irq; + + if (!(s->irq_mask & mask)) + return 0; + + s->irq_mask &= ~mask; + + return 0; +} + +#else + +static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { + return CS_SUCCESS; +} + +#endif + + +int pcmcia_adjust_resource_info(adjust_t *adj) +{ + struct pcmcia_socket *s; + int ret = CS_UNSUPPORTED_FUNCTION; + unsigned long flags; + + down_read(&pcmcia_socket_list_rwsem); + list_for_each_entry(s, &pcmcia_socket_list, socket_list) { + + if (adj->Resource == RES_IRQ) + ret = adjust_irq(s, adj); + + else if (s->resource_ops->adjust_resource) { + + /* you can't use the old interface if the new + * one was used before */ + spin_lock_irqsave(&s->lock, flags); + if ((s->resource_setup_new) && + !(s->resource_setup_old)) { + spin_unlock_irqrestore(&s->lock, flags); + continue; + } else if (!(s->resource_setup_old)) + s->resource_setup_old = 1; + spin_unlock_irqrestore(&s->lock, flags); + + ret = s->resource_ops->adjust_resource(s, adj); + if (!ret) { + /* as there's no way we know this is the + * last call to adjust_resource_info, we + * always need to assume this is the latest + * one... */ + spin_lock_irqsave(&s->lock, flags); + s->resource_setup_done = 1; + spin_unlock_irqrestore(&s->lock, flags); + } + } + } + up_read(&pcmcia_socket_list_rwsem); + + return (ret); +} +EXPORT_SYMBOL(pcmcia_adjust_resource_info); + +#endif + int pcmcia_validate_mem(struct pcmcia_socket *s) { if (s->resource_ops->validate_mem) @@ -84,8 +164,7 @@ struct pccard_resource_ops pccard_static_ops = { .adjust_io_region = NULL, .find_io = NULL, .find_mem = NULL, - .add_io = NULL, - .add_mem = NULL, + .adjust_resource = NULL, .init = static_init, .exit = NULL, }; @@ -185,8 +264,7 @@ struct pccard_resource_ops pccard_iodyn_ops = { .adjust_io_region = iodyn_adjust_io_region, .find_io = iodyn_find_io_region, .find_mem = NULL, - .add_io = NULL, - .add_mem = NULL, + .adjust_resource = NULL, .init = static_init, .exit = NULL, }; diff --git a/trunk/drivers/pcmcia/rsrc_nonstatic.c b/trunk/drivers/pcmcia/rsrc_nonstatic.c index d0c1d63d1891..0fcf763b9175 100644 --- a/trunk/drivers/pcmcia/rsrc_nonstatic.c +++ b/trunk/drivers/pcmcia/rsrc_nonstatic.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "cs_internal.h" @@ -260,22 +261,21 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, ======================================================================*/ /* Validation function for cards with a valid CIS */ -static int readable(struct pcmcia_socket *s, struct resource *res, - unsigned int *count) +static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info) { int ret = -1; s->cis_mem.res = res; s->cis_virt = ioremap(res->start, s->map_size); if (s->cis_virt) { - ret = pccard_validate_cis(s, BIND_FN_ALL, count); + ret = pccard_validate_cis(s, BIND_FN_ALL, info); /* invalidate mapping and CIS cache */ iounmap(s->cis_virt); s->cis_virt = NULL; destroy_cis_cache(s); } s->cis_mem.res = NULL; - if ((ret != 0) || (count == 0)) + if ((ret != 0) || (info->Chains == 0)) return 0; return 1; } @@ -316,7 +316,7 @@ static int cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size) { struct resource *res1, *res2; - unsigned int info1, info2; + cisinfo_t info1, info2; int ret = 0; res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe"); @@ -330,7 +330,7 @@ cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size) free_region(res2); free_region(res1); - return (ret == 2) && (info1 == info2); + return (ret == 2) && (info1.Chains == info2.Chains); } static int @@ -766,6 +766,21 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long } +static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj) +{ + unsigned long end; + + switch (adj->Resource) { + case RES_MEMORY_RANGE: + end = adj->resource.memory.Base + adj->resource.memory.Size - 1; + return adjust_memory(s, adj->Action, adj->resource.memory.Base, end); + case RES_IO_RANGE: + end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1; + return adjust_io(s, adj->Action, adj->resource.io.BasePort, end); + } + return CS_UNSUPPORTED_FUNCTION; +} + #ifdef CONFIG_PCI static int nonstatic_autoadd_resources(struct pcmcia_socket *s) { @@ -874,8 +889,7 @@ struct pccard_resource_ops pccard_nonstatic_ops = { .adjust_io_region = nonstatic_adjust_io_region, .find_io = nonstatic_find_io_region, .find_mem = nonstatic_find_mem_region, - .add_io = adjust_io, - .add_mem = adjust_memory, + .adjust_resource = nonstatic_adjust_resource_info, .init = nonstatic_init, .exit = nonstatic_release_resource_db, }; @@ -994,34 +1008,41 @@ static ssize_t store_mem_db(struct device *dev, } static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db); -static struct attribute *pccard_rsrc_attributes[] = { - &dev_attr_available_resources_io.attr, - &dev_attr_available_resources_mem.attr, +static struct device_attribute *pccard_rsrc_attributes[] = { + &dev_attr_available_resources_io, + &dev_attr_available_resources_mem, NULL, }; -static const struct attribute_group rsrc_attributes = { - .attrs = pccard_rsrc_attributes, -}; - static int __devinit pccard_sysfs_add_rsrc(struct device *dev, struct class_interface *class_intf) { struct pcmcia_socket *s = dev_get_drvdata(dev); - + struct device_attribute **attr; + int ret = 0; if (s->resource_ops != &pccard_nonstatic_ops) return 0; - return sysfs_create_group(&dev->kobj, &rsrc_attributes); + + for (attr = pccard_rsrc_attributes; *attr; attr++) { + ret = device_create_file(dev, *attr); + if (ret) + break; + } + + return ret; } static void __devexit pccard_sysfs_remove_rsrc(struct device *dev, struct class_interface *class_intf) { struct pcmcia_socket *s = dev_get_drvdata(dev); + struct device_attribute **attr; if (s->resource_ops != &pccard_nonstatic_ops) return; - sysfs_remove_group(&dev->kobj, &rsrc_attributes); + + for (attr = pccard_rsrc_attributes; *attr; attr++) + device_remove_file(dev, *attr); } static struct class_interface pccard_rsrc_interface __refdata = { diff --git a/trunk/drivers/pcmcia/soc_common.h b/trunk/drivers/pcmcia/soc_common.h index 91ef6a0da3ab..1edc1da9d353 100644 --- a/trunk/drivers/pcmcia/soc_common.h +++ b/trunk/drivers/pcmcia/soc_common.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "cs_internal.h" diff --git a/trunk/drivers/pcmcia/socket_sysfs.c b/trunk/drivers/pcmcia/socket_sysfs.c index 006a29e91d83..562384d6f321 100644 --- a/trunk/drivers/pcmcia/socket_sysfs.c +++ b/trunk/drivers/pcmcia/socket_sysfs.c @@ -27,9 +27,11 @@ #include #include +#define IN_CARD_SERVICES #include #include #include +#include #include #include #include @@ -291,7 +293,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, count = 0; else { struct pcmcia_socket *s; - unsigned int chains; + cisinfo_t cisinfo; if (off + count > size) count = size - off; @@ -300,9 +302,9 @@ static ssize_t pccard_show_cis(struct kobject *kobj, if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - if (pccard_validate_cis(s, BIND_FN_ALL, &chains)) + if (pccard_validate_cis(s, BIND_FN_ALL, &cisinfo)) return -EIO; - if (!chains) + if (!cisinfo.Chains) return -ENODATA; count = pccard_extract_cis(s, buf, off, count); diff --git a/trunk/drivers/pcmcia/ti113x.h b/trunk/drivers/pcmcia/ti113x.h index 129db7bd06c3..d29657bf1b40 100644 --- a/trunk/drivers/pcmcia/ti113x.h +++ b/trunk/drivers/pcmcia/ti113x.h @@ -155,7 +155,7 @@ #define ENE_TEST_C9_TLTENABLE 0x02 #define ENE_TEST_C9_PFENABLE_F0 0x04 #define ENE_TEST_C9_PFENABLE_F1 0x08 -#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F1) +#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0) #define ENE_TEST_C9_WPDISALBLE_F0 0x40 #define ENE_TEST_C9_WPDISALBLE_F1 0x80 #define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1) @@ -692,7 +692,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) goto out; /* check state */ - yenta_get_status(&slot2->socket, &state); + yenta_get_status(&socket->socket, &state); if (state & SS_DETECT) { ret = 0; goto out; diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index b32d7eb3d81a..7b5969ed05cd 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -810,7 +810,7 @@ cio_release_console(void) { console_subchannel.schib.pmcw.intparm = 0; cio_modify(&console_subchannel); - ctl_clear_bit(6, 24); + ctl_clear_bit(6, 30); console_subchannel_in_use = 0; } diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index fe694f0ee19a..ea0edd1b2e76 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -182,9 +182,8 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize); static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp); -static ssize_t sg_new_write(Sg_fd *sfp, struct file *file, - const char __user *buf, size_t count, int blocking, - int read_only, Sg_request **o_srp); +static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, + int blocking, int read_only, Sg_request ** o_srp); static int sg_common_write(Sg_fd * sfp, Sg_request * srp, unsigned char *cmnd, int timeout, int blocking); static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, @@ -205,6 +204,7 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); static Sg_request *sg_add_request(Sg_fd * sfp); static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); static int sg_res_in_use(Sg_fd * sfp); +static int sg_allow_access(unsigned char opcode, char dev_type); static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); static Sg_device *sg_get_dev(int dev); #ifdef CONFIG_SCSI_PROC_FS @@ -544,7 +544,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) return -EFAULT; blocking = !(filp->f_flags & O_NONBLOCK); if (old_hdr.reply_len < 0) - return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL); + return sg_new_write(sfp, buf, count, blocking, 0, NULL); if (count < (SZ_SG_HEADER + 6)) return -EIO; /* The minimum scsi command length is 6 bytes. */ @@ -621,9 +621,8 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) } static ssize_t -sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, - size_t count, int blocking, int read_only, - Sg_request **o_srp) +sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, + int blocking, int read_only, Sg_request ** o_srp) { int k; Sg_request *srp; @@ -679,7 +678,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, sg_remove_request(sfp, srp); return -EFAULT; } - if (read_only && !blk_verify_command(file, cmnd)) { + if (read_only && + (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) { sg_remove_request(sfp, srp); return -EPERM; } @@ -799,7 +799,7 @@ sg_ioctl(struct inode *inode, struct file *filp, if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) return -EFAULT; result = - sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, + sg_new_write(sfp, p, SZ_SG_IO_HDR, blocking, read_only, &srp); if (result < 0) return result; @@ -1048,7 +1048,7 @@ sg_ioctl(struct inode *inode, struct file *filp, if (copy_from_user(&opcode, siocp->data, 1)) return -EFAULT; - if (!blk_verify_command(filp, &opcode)) + if (!sg_allow_access(opcode, sdp->device->type)) return -EPERM; } return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); @@ -2502,6 +2502,30 @@ sg_page_free(struct page *page, int size) __free_pages(page, order); } +#ifndef MAINTENANCE_IN_CMD +#define MAINTENANCE_IN_CMD 0xa3 +#endif + +static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE, + INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12, + READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS, + SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD +}; + +static int +sg_allow_access(unsigned char opcode, char dev_type) +{ + int k; + + if (TYPE_SCANNER == dev_type) /* TYPE_ROM maybe burner */ + return 1; + for (k = 0; k < sizeof (allow_ops); ++k) { + if (opcode == allow_ops[k]) + return 1; + } + return 0; +} + #ifdef CONFIG_SCSI_PROC_FS static int sg_idr_max_id(int id, void *p, void *data) diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index 27f5bfd1def3..c82df8bd4d89 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -673,20 +673,24 @@ static int sr_probe(struct device *dev) static void get_sectorsize(struct scsi_cd *cd) { unsigned char cmd[10]; - unsigned char buffer[8]; + unsigned char *buffer; int the_result, retries = 3; int sector_size; struct request_queue *queue; + buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + if (!buffer) + goto Enomem; + do { cmd[0] = READ_CAPACITY; memset((void *) &cmd[1], 0, 9); - memset(buffer, 0, sizeof(buffer)); + memset(buffer, 0, 8); /* Do the command and wait.. */ the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, - buffer, sizeof(buffer), NULL, - SR_TIMEOUT, MAX_RETRIES); + buffer, 8, NULL, SR_TIMEOUT, + MAX_RETRIES); retries--; @@ -741,8 +745,14 @@ static void get_sectorsize(struct scsi_cd *cd) queue = cd->device->request_queue; blk_queue_hardsect_size(queue, sector_size); - +out: + kfree(buffer); return; + +Enomem: + cd->capacity = 0x1fffff; + cd->device->sector_size = 2048; /* A guess, just in case */ + goto out; } static void get_capabilities(struct scsi_cd *cd) diff --git a/trunk/drivers/xen/xenbus/xenbus_client.c b/trunk/drivers/xen/xenbus/xenbus_client.c index 9678b3e98c63..0f86b0ff7879 100644 --- a/trunk/drivers/xen/xenbus/xenbus_client.c +++ b/trunk/drivers/xen/xenbus/xenbus_client.c @@ -117,7 +117,7 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev, char *path; va_start(ap, pathfmt); - path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap); + path = kvasprintf(GFP_KERNEL, pathfmt, ap); va_end(ap); if (!path) { diff --git a/trunk/drivers/xen/xenbus/xenbus_xs.c b/trunk/drivers/xen/xenbus/xenbus_xs.c index 7f2f91c0e11d..227d53b12a5c 100644 --- a/trunk/drivers/xen/xenbus/xenbus_xs.c +++ b/trunk/drivers/xen/xenbus/xenbus_xs.c @@ -283,9 +283,9 @@ static char *join(const char *dir, const char *name) char *buffer; if (strlen(name) == 0) - buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s", dir); + buffer = kasprintf(GFP_KERNEL, "%s", dir); else - buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s/%s", dir, name); + buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name); return (!buffer) ? ERR_PTR(-ENOMEM) : buffer; } @@ -297,7 +297,7 @@ static char **split(char *strings, unsigned int len, unsigned int *num) *num = count_strings(strings, len); /* Transfer to one big alloc for easy freeing. */ - ret = kmalloc(*num * sizeof(char *) + len, GFP_NOIO | __GFP_HIGH); + ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL); if (!ret) { kfree(strings); return ERR_PTR(-ENOMEM); @@ -751,7 +751,7 @@ static int process_msg(void) } - msg = kmalloc(sizeof(*msg), GFP_NOIO | __GFP_HIGH); + msg = kmalloc(sizeof(*msg), GFP_KERNEL); if (msg == NULL) { err = -ENOMEM; goto out; @@ -763,7 +763,7 @@ static int process_msg(void) goto out; } - body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH); + body = kmalloc(msg->hdr.len + 1, GFP_KERNEL); if (body == NULL) { kfree(msg); err = -ENOMEM; diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index 277b079dec9e..1e7a11bd4da1 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -19,7 +19,6 @@ else obj-y += no-block.o endif -obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_INOTIFY_USER) += inotify_user.o obj-$(CONFIG_EPOLL) += eventpoll.o diff --git a/trunk/fs/bio-integrity.c b/trunk/fs/bio-integrity.c deleted file mode 100644 index 63e2ee63058d..000000000000 --- a/trunk/fs/bio-integrity.c +++ /dev/null @@ -1,719 +0,0 @@ -/* - * bio-integrity.c - bio data integrity extensions - * - * Copyright (C) 2007, 2008 Oracle Corporation - * Written by: Martin K. Petersen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - */ - -#include -#include -#include -#include - -static struct kmem_cache *bio_integrity_slab __read_mostly; -static struct workqueue_struct *kintegrityd_wq; - -/** - * bio_integrity_alloc_bioset - Allocate integrity payload and attach it to bio - * @bio: bio to attach integrity metadata to - * @gfp_mask: Memory allocation mask - * @nr_vecs: Number of integrity metadata scatter-gather elements - * @bs: bio_set to allocate from - * - * Description: This function prepares a bio for attaching integrity - * metadata. nr_vecs specifies the maximum number of pages containing - * integrity metadata that can be attached. - */ -struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio, - gfp_t gfp_mask, - unsigned int nr_vecs, - struct bio_set *bs) -{ - struct bio_integrity_payload *bip; - struct bio_vec *iv; - unsigned long idx; - - BUG_ON(bio == NULL); - - bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask); - if (unlikely(bip == NULL)) { - printk(KERN_ERR "%s: could not alloc bip\n", __func__); - return NULL; - } - - memset(bip, 0, sizeof(*bip)); - - iv = bvec_alloc_bs(gfp_mask, nr_vecs, &idx, bs); - if (unlikely(iv == NULL)) { - printk(KERN_ERR "%s: could not alloc bip_vec\n", __func__); - mempool_free(bip, bs->bio_integrity_pool); - return NULL; - } - - bip->bip_pool = idx; - bip->bip_vec = iv; - bip->bip_bio = bio; - bio->bi_integrity = bip; - - return bip; -} -EXPORT_SYMBOL(bio_integrity_alloc_bioset); - -/** - * bio_integrity_alloc - Allocate integrity payload and attach it to bio - * @bio: bio to attach integrity metadata to - * @gfp_mask: Memory allocation mask - * @nr_vecs: Number of integrity metadata scatter-gather elements - * - * Description: This function prepares a bio for attaching integrity - * metadata. nr_vecs specifies the maximum number of pages containing - * integrity metadata that can be attached. - */ -struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, - gfp_t gfp_mask, - unsigned int nr_vecs) -{ - return bio_integrity_alloc_bioset(bio, gfp_mask, nr_vecs, fs_bio_set); -} -EXPORT_SYMBOL(bio_integrity_alloc); - -/** - * bio_integrity_free - Free bio integrity payload - * @bio: bio containing bip to be freed - * @bs: bio_set this bio was allocated from - * - * Description: Used to free the integrity portion of a bio. Usually - * called from bio_free(). - */ -void bio_integrity_free(struct bio *bio, struct bio_set *bs) -{ - struct bio_integrity_payload *bip = bio->bi_integrity; - - BUG_ON(bip == NULL); - - /* A cloned bio doesn't own the integrity metadata */ - if (!bio_flagged(bio, BIO_CLONED) && bip->bip_buf != NULL) - kfree(bip->bip_buf); - - mempool_free(bip->bip_vec, bs->bvec_pools[bip->bip_pool]); - mempool_free(bip, bs->bio_integrity_pool); - - bio->bi_integrity = NULL; -} -EXPORT_SYMBOL(bio_integrity_free); - -/** - * bio_integrity_add_page - Attach integrity metadata - * @bio: bio to update - * @page: page containing integrity metadata - * @len: number of bytes of integrity metadata in page - * @offset: start offset within page - * - * Description: Attach a page containing integrity metadata to bio. - */ -int bio_integrity_add_page(struct bio *bio, struct page *page, - unsigned int len, unsigned int offset) -{ - struct bio_integrity_payload *bip = bio->bi_integrity; - struct bio_vec *iv; - - if (bip->bip_vcnt >= bvec_nr_vecs(bip->bip_pool)) { - printk(KERN_ERR "%s: bip_vec full\n", __func__); - return 0; - } - - iv = bip_vec_idx(bip, bip->bip_vcnt); - BUG_ON(iv == NULL); - BUG_ON(iv->bv_page != NULL); - - iv->bv_page = page; - iv->bv_len = len; - iv->bv_offset = offset; - bip->bip_vcnt++; - - return len; -} -EXPORT_SYMBOL(bio_integrity_add_page); - -/** - * bio_integrity_enabled - Check whether integrity can be passed - * @bio: bio to check - * - * Description: Determines whether bio_integrity_prep() can be called - * on this bio or not. bio data direction and target device must be - * set prior to calling. The functions honors the write_generate and - * read_verify flags in sysfs. - */ -int bio_integrity_enabled(struct bio *bio) -{ - /* Already protected? */ - if (bio_integrity(bio)) - return 0; - - return bdev_integrity_enabled(bio->bi_bdev, bio_data_dir(bio)); -} -EXPORT_SYMBOL(bio_integrity_enabled); - -/** - * bio_integrity_hw_sectors - Convert 512b sectors to hardware ditto - * @bi: blk_integrity profile for device - * @sectors: Number of 512 sectors to convert - * - * Description: The block layer calculates everything in 512 byte - * sectors but integrity metadata is done in terms of the hardware - * sector size of the storage device. Convert the block layer sectors - * to physical sectors. - */ -static inline unsigned int bio_integrity_hw_sectors(struct blk_integrity *bi, - unsigned int sectors) -{ - /* At this point there are only 512b or 4096b DIF/EPP devices */ - if (bi->sector_size == 4096) - return sectors >>= 3; - - return sectors; -} - -/** - * bio_integrity_tag_size - Retrieve integrity tag space - * @bio: bio to inspect - * - * Description: Returns the maximum number of tag bytes that can be - * attached to this bio. Filesystems can use this to determine how - * much metadata to attach to an I/O. - */ -unsigned int bio_integrity_tag_size(struct bio *bio) -{ - struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); - - BUG_ON(bio->bi_size == 0); - - return bi->tag_size * (bio->bi_size / bi->sector_size); -} -EXPORT_SYMBOL(bio_integrity_tag_size); - -int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, int set) -{ - struct bio_integrity_payload *bip = bio->bi_integrity; - struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); - unsigned int nr_sectors; - - BUG_ON(bip->bip_buf == NULL); - - if (bi->tag_size == 0) - return -1; - - nr_sectors = bio_integrity_hw_sectors(bi, - DIV_ROUND_UP(len, bi->tag_size)); - - if (nr_sectors * bi->tuple_size > bip->bip_size) { - printk(KERN_ERR "%s: tag too big for bio: %u > %u\n", - __func__, nr_sectors * bi->tuple_size, bip->bip_size); - return -1; - } - - if (set) - bi->set_tag_fn(bip->bip_buf, tag_buf, nr_sectors); - else - bi->get_tag_fn(bip->bip_buf, tag_buf, nr_sectors); - - return 0; -} - -/** - * bio_integrity_set_tag - Attach a tag buffer to a bio - * @bio: bio to attach buffer to - * @tag_buf: Pointer to a buffer containing tag data - * @len: Length of the included buffer - * - * Description: Use this function to tag a bio by leveraging the extra - * space provided by devices formatted with integrity protection. The - * size of the integrity buffer must be <= to the size reported by - * bio_integrity_tag_size(). - */ -int bio_integrity_set_tag(struct bio *bio, void *tag_buf, unsigned int len) -{ - BUG_ON(bio_data_dir(bio) != WRITE); - - return bio_integrity_tag(bio, tag_buf, len, 1); -} -EXPORT_SYMBOL(bio_integrity_set_tag); - -/** - * bio_integrity_get_tag - Retrieve a tag buffer from a bio - * @bio: bio to retrieve buffer from - * @tag_buf: Pointer to a buffer for the tag data - * @len: Length of the target buffer - * - * Description: Use this function to retrieve the tag buffer from a - * completed I/O. The size of the integrity buffer must be <= to the - * size reported by bio_integrity_tag_size(). - */ -int bio_integrity_get_tag(struct bio *bio, void *tag_buf, unsigned int len) -{ - BUG_ON(bio_data_dir(bio) != READ); - - return bio_integrity_tag(bio, tag_buf, len, 0); -} -EXPORT_SYMBOL(bio_integrity_get_tag); - -/** - * bio_integrity_generate - Generate integrity metadata for a bio - * @bio: bio to generate integrity metadata for - * - * Description: Generates integrity metadata for a bio by calling the - * block device's generation callback function. The bio must have a - * bip attached with enough room to accommodate the generated - * integrity metadata. - */ -static void bio_integrity_generate(struct bio *bio) -{ - struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); - struct blk_integrity_exchg bix; - struct bio_vec *bv; - sector_t sector = bio->bi_sector; - unsigned int i, sectors, total; - void *prot_buf = bio->bi_integrity->bip_buf; - - total = 0; - bix.disk_name = bio->bi_bdev->bd_disk->disk_name; - bix.sector_size = bi->sector_size; - - bio_for_each_segment(bv, bio, i) { - void *kaddr = kmap_atomic(bv->bv_page, KM_USER0); - bix.data_buf = kaddr + bv->bv_offset; - bix.data_size = bv->bv_len; - bix.prot_buf = prot_buf; - bix.sector = sector; - - bi->generate_fn(&bix); - - sectors = bv->bv_len / bi->sector_size; - sector += sectors; - prot_buf += sectors * bi->tuple_size; - total += sectors * bi->tuple_size; - BUG_ON(total > bio->bi_integrity->bip_size); - - kunmap_atomic(kaddr, KM_USER0); - } -} - -/** - * bio_integrity_prep - Prepare bio for integrity I/O - * @bio: bio to prepare - * - * Description: Allocates a buffer for integrity metadata, maps the - * pages and attaches them to a bio. The bio must have data - * direction, target device and start sector set priot to calling. In - * the WRITE case, integrity metadata will be generated using the - * block device's integrity function. In the READ case, the buffer - * will be prepared for DMA and a suitable end_io handler set up. - */ -int bio_integrity_prep(struct bio *bio) -{ - struct bio_integrity_payload *bip; - struct blk_integrity *bi; - struct request_queue *q; - void *buf; - unsigned long start, end; - unsigned int len, nr_pages; - unsigned int bytes, offset, i; - unsigned int sectors; - - bi = bdev_get_integrity(bio->bi_bdev); - q = bdev_get_queue(bio->bi_bdev); - BUG_ON(bi == NULL); - BUG_ON(bio_integrity(bio)); - - sectors = bio_integrity_hw_sectors(bi, bio_sectors(bio)); - - /* Allocate kernel buffer for protection data */ - len = sectors * blk_integrity_tuple_size(bi); - buf = kmalloc(len, GFP_NOIO | __GFP_NOFAIL | q->bounce_gfp); - if (unlikely(buf == NULL)) { - printk(KERN_ERR "could not allocate integrity buffer\n"); - return -EIO; - } - - end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; - start = ((unsigned long) buf) >> PAGE_SHIFT; - nr_pages = end - start; - - /* Allocate bio integrity payload and integrity vectors */ - bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages); - if (unlikely(bip == NULL)) { - printk(KERN_ERR "could not allocate data integrity bioset\n"); - kfree(buf); - return -EIO; - } - - bip->bip_buf = buf; - bip->bip_size = len; - bip->bip_sector = bio->bi_sector; - - /* Map it */ - offset = offset_in_page(buf); - for (i = 0 ; i < nr_pages ; i++) { - int ret; - bytes = PAGE_SIZE - offset; - - if (len <= 0) - break; - - if (bytes > len) - bytes = len; - - ret = bio_integrity_add_page(bio, virt_to_page(buf), - bytes, offset); - - if (ret == 0) - return 0; - - if (ret < bytes) - break; - - buf += bytes; - len -= bytes; - offset = 0; - } - - /* Install custom I/O completion handler if read verify is enabled */ - if (bio_data_dir(bio) == READ) { - bip->bip_end_io = bio->bi_end_io; - bio->bi_end_io = bio_integrity_endio; - } - - /* Auto-generate integrity metadata if this is a write */ - if (bio_data_dir(bio) == WRITE) - bio_integrity_generate(bio); - - return 0; -} -EXPORT_SYMBOL(bio_integrity_prep); - -/** - * bio_integrity_verify - Verify integrity metadata for a bio - * @bio: bio to verify - * - * Description: This function is called to verify the integrity of a - * bio. The data in the bio io_vec is compared to the integrity - * metadata returned by the HBA. - */ -static int bio_integrity_verify(struct bio *bio) -{ - struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); - struct blk_integrity_exchg bix; - struct bio_vec *bv; - sector_t sector = bio->bi_integrity->bip_sector; - unsigned int i, sectors, total, ret; - void *prot_buf = bio->bi_integrity->bip_buf; - - ret = total = 0; - bix.disk_name = bio->bi_bdev->bd_disk->disk_name; - bix.sector_size = bi->sector_size; - - bio_for_each_segment(bv, bio, i) { - void *kaddr = kmap_atomic(bv->bv_page, KM_USER0); - bix.data_buf = kaddr + bv->bv_offset; - bix.data_size = bv->bv_len; - bix.prot_buf = prot_buf; - bix.sector = sector; - - ret = bi->verify_fn(&bix); - - if (ret) { - kunmap_atomic(kaddr, KM_USER0); - break; - } - - sectors = bv->bv_len / bi->sector_size; - sector += sectors; - prot_buf += sectors * bi->tuple_size; - total += sectors * bi->tuple_size; - BUG_ON(total > bio->bi_integrity->bip_size); - - kunmap_atomic(kaddr, KM_USER0); - } - - return ret; -} - -/** - * bio_integrity_verify_fn - Integrity I/O completion worker - * @work: Work struct stored in bio to be verified - * - * Description: This workqueue function is called to complete a READ - * request. The function verifies the transferred integrity metadata - * and then calls the original bio end_io function. - */ -static void bio_integrity_verify_fn(struct work_struct *work) -{ - struct bio_integrity_payload *bip = - container_of(work, struct bio_integrity_payload, bip_work); - struct bio *bio = bip->bip_bio; - int error = bip->bip_error; - - if (bio_integrity_verify(bio)) { - clear_bit(BIO_UPTODATE, &bio->bi_flags); - error = -EIO; - } - - /* Restore original bio completion handler */ - bio->bi_end_io = bip->bip_end_io; - - if (bio->bi_end_io) - bio->bi_end_io(bio, error); -} - -/** - * bio_integrity_endio - Integrity I/O completion function - * @bio: Protected bio - * @error: Pointer to errno - * - * Description: Completion for integrity I/O - * - * Normally I/O completion is done in interrupt context. However, - * verifying I/O integrity is a time-consuming task which must be run - * in process context. This function postpones completion - * accordingly. - */ -void bio_integrity_endio(struct bio *bio, int error) -{ - struct bio_integrity_payload *bip = bio->bi_integrity; - - BUG_ON(bip->bip_bio != bio); - - bip->bip_error = error; - INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); - queue_work(kintegrityd_wq, &bip->bip_work); -} -EXPORT_SYMBOL(bio_integrity_endio); - -/** - * bio_integrity_mark_head - Advance bip_vec skip bytes - * @bip: Integrity vector to advance - * @skip: Number of bytes to advance it - */ -void bio_integrity_mark_head(struct bio_integrity_payload *bip, - unsigned int skip) -{ - struct bio_vec *iv; - unsigned int i; - - bip_for_each_vec(iv, bip, i) { - if (skip == 0) { - bip->bip_idx = i; - return; - } else if (skip >= iv->bv_len) { - skip -= iv->bv_len; - } else { /* skip < iv->bv_len) */ - iv->bv_offset += skip; - iv->bv_len -= skip; - bip->bip_idx = i; - return; - } - } -} - -/** - * bio_integrity_mark_tail - Truncate bip_vec to be len bytes long - * @bip: Integrity vector to truncate - * @len: New length of integrity vector - */ -void bio_integrity_mark_tail(struct bio_integrity_payload *bip, - unsigned int len) -{ - struct bio_vec *iv; - unsigned int i; - - bip_for_each_vec(iv, bip, i) { - if (len == 0) { - bip->bip_vcnt = i; - return; - } else if (len >= iv->bv_len) { - len -= iv->bv_len; - } else { /* len < iv->bv_len) */ - iv->bv_len = len; - len = 0; - } - } -} - -/** - * bio_integrity_advance - Advance integrity vector - * @bio: bio whose integrity vector to update - * @bytes_done: number of data bytes that have been completed - * - * Description: This function calculates how many integrity bytes the - * number of completed data bytes correspond to and advances the - * integrity vector accordingly. - */ -void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) -{ - struct bio_integrity_payload *bip = bio->bi_integrity; - struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); - unsigned int nr_sectors; - - BUG_ON(bip == NULL); - BUG_ON(bi == NULL); - - nr_sectors = bio_integrity_hw_sectors(bi, bytes_done >> 9); - bio_integrity_mark_head(bip, nr_sectors * bi->tuple_size); -} -EXPORT_SYMBOL(bio_integrity_advance); - -/** - * bio_integrity_trim - Trim integrity vector - * @bio: bio whose integrity vector to update - * @offset: offset to first data sector - * @sectors: number of data sectors - * - * Description: Used to trim the integrity vector in a cloned bio. - * The ivec will be advanced corresponding to 'offset' data sectors - * and the length will be truncated corresponding to 'len' data - * sectors. - */ -void bio_integrity_trim(struct bio *bio, unsigned int offset, - unsigned int sectors) -{ - struct bio_integrity_payload *bip = bio->bi_integrity; - struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); - unsigned int nr_sectors; - - BUG_ON(bip == NULL); - BUG_ON(bi == NULL); - BUG_ON(!bio_flagged(bio, BIO_CLONED)); - - nr_sectors = bio_integrity_hw_sectors(bi, sectors); - bip->bip_sector = bip->bip_sector + offset; - bio_integrity_mark_head(bip, offset * bi->tuple_size); - bio_integrity_mark_tail(bip, sectors * bi->tuple_size); -} -EXPORT_SYMBOL(bio_integrity_trim); - -/** - * bio_integrity_split - Split integrity metadata - * @bio: Protected bio - * @bp: Resulting bio_pair - * @sectors: Offset - * - * Description: Splits an integrity page into a bio_pair. - */ -void bio_integrity_split(struct bio *bio, struct bio_pair *bp, int sectors) -{ - struct blk_integrity *bi; - struct bio_integrity_payload *bip = bio->bi_integrity; - unsigned int nr_sectors; - - if (bio_integrity(bio) == 0) - return; - - bi = bdev_get_integrity(bio->bi_bdev); - BUG_ON(bi == NULL); - BUG_ON(bip->bip_vcnt != 1); - - nr_sectors = bio_integrity_hw_sectors(bi, sectors); - - bp->bio1.bi_integrity = &bp->bip1; - bp->bio2.bi_integrity = &bp->bip2; - - bp->iv1 = bip->bip_vec[0]; - bp->iv2 = bip->bip_vec[0]; - - bp->bip1.bip_vec = &bp->iv1; - bp->bip2.bip_vec = &bp->iv2; - - bp->iv1.bv_len = sectors * bi->tuple_size; - bp->iv2.bv_offset += sectors * bi->tuple_size; - bp->iv2.bv_len -= sectors * bi->tuple_size; - - bp->bip1.bip_sector = bio->bi_integrity->bip_sector; - bp->bip2.bip_sector = bio->bi_integrity->bip_sector + nr_sectors; - - bp->bip1.bip_vcnt = bp->bip2.bip_vcnt = 1; - bp->bip1.bip_idx = bp->bip2.bip_idx = 0; -} -EXPORT_SYMBOL(bio_integrity_split); - -/** - * bio_integrity_clone - Callback for cloning bios with integrity metadata - * @bio: New bio - * @bio_src: Original bio - * @bs: bio_set to allocate bip from - * - * Description: Called to allocate a bip when cloning a bio - */ -int bio_integrity_clone(struct bio *bio, struct bio *bio_src, - struct bio_set *bs) -{ - struct bio_integrity_payload *bip_src = bio_src->bi_integrity; - struct bio_integrity_payload *bip; - - BUG_ON(bip_src == NULL); - - bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); - - if (bip == NULL) - return -EIO; - - memcpy(bip->bip_vec, bip_src->bip_vec, - bip_src->bip_vcnt * sizeof(struct bio_vec)); - - bip->bip_sector = bip_src->bip_sector; - bip->bip_vcnt = bip_src->bip_vcnt; - bip->bip_idx = bip_src->bip_idx; - - return 0; -} -EXPORT_SYMBOL(bio_integrity_clone); - -int bioset_integrity_create(struct bio_set *bs, int pool_size) -{ - bs->bio_integrity_pool = mempool_create_slab_pool(pool_size, - bio_integrity_slab); - if (!bs->bio_integrity_pool) - return -1; - - return 0; -} -EXPORT_SYMBOL(bioset_integrity_create); - -void bioset_integrity_free(struct bio_set *bs) -{ - if (bs->bio_integrity_pool) - mempool_destroy(bs->bio_integrity_pool); -} -EXPORT_SYMBOL(bioset_integrity_free); - -void __init bio_integrity_init_slab(void) -{ - bio_integrity_slab = KMEM_CACHE(bio_integrity_payload, - SLAB_HWCACHE_ALIGN|SLAB_PANIC); -} -EXPORT_SYMBOL(bio_integrity_init_slab); - -static int __init integrity_init(void) -{ - kintegrityd_wq = create_workqueue("kintegrityd"); - - if (!kintegrityd_wq) - panic("Failed to create kintegrityd\n"); - - return 0; -} -subsys_initcall(integrity_init); diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 88322b066acb..78562574cb52 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -28,10 +28,25 @@ #include #include /* for struct sg_iovec */ +#define BIO_POOL_SIZE 2 + static struct kmem_cache *bio_slab __read_mostly; +#define BIOVEC_NR_POOLS 6 + +/* + * a small number of entries is fine, not going to be performance critical. + * basically we just need to survive + */ +#define BIO_SPLIT_ENTRIES 2 mempool_t *bio_split_pool __read_mostly; +struct biovec_slab { + int nr_vecs; + char *name; + struct kmem_cache *slab; +}; + /* * if you change this list, also change bvec_alloc or things will * break badly! cannot be bigger than what you can fit into an @@ -44,18 +59,24 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { }; #undef BV +/* + * bio_set is used to allow other portions of the IO system to + * allocate their own private memory pools for bio and iovec structures. + * These memory pools in turn all allocate from the bio_slab + * and the bvec_slabs[]. + */ +struct bio_set { + mempool_t *bio_pool; + mempool_t *bvec_pools[BIOVEC_NR_POOLS]; +}; + /* * fs_bio_set is the bio_set containing bio and iovec memory pools used by * IO code that does not need private memory pools. */ -struct bio_set *fs_bio_set; - -unsigned int bvec_nr_vecs(unsigned short idx) -{ - return bvec_slabs[idx].nr_vecs; -} +static struct bio_set *fs_bio_set; -struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) +static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) { struct bio_vec *bvl; @@ -96,9 +117,6 @@ void bio_free(struct bio *bio, struct bio_set *bio_set) mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); } - if (bio_integrity(bio)) - bio_integrity_free(bio, bio_set); - mempool_free(bio, bio_set->bio_pool); } @@ -257,19 +275,9 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) { struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set); - if (!b) - return NULL; - - b->bi_destructor = bio_fs_destructor; - __bio_clone(b, bio); - - if (bio_integrity(bio)) { - int ret; - - ret = bio_integrity_clone(b, bio, fs_bio_set); - - if (ret < 0) - return NULL; + if (b) { + b->bi_destructor = bio_fs_destructor; + __bio_clone(b, bio); } return b; @@ -325,19 +333,10 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page if (page == prev->bv_page && offset == prev->bv_offset + prev->bv_len) { prev->bv_len += len; - - if (q->merge_bvec_fn) { - struct bvec_merge_data bvm = { - .bi_bdev = bio->bi_bdev, - .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, - .bi_rw = bio->bi_rw, - }; - - if (q->merge_bvec_fn(q, &bvm, prev) < len) { - prev->bv_len -= len; - return 0; - } + if (q->merge_bvec_fn && + q->merge_bvec_fn(q, bio, prev) < len) { + prev->bv_len -= len; + return 0; } goto done; @@ -378,18 +377,11 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page * queue to get further control */ if (q->merge_bvec_fn) { - struct bvec_merge_data bvm = { - .bi_bdev = bio->bi_bdev, - .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, - .bi_rw = bio->bi_rw, - }; - /* * merge_bvec_fn() returns number of bytes it can accept * at this offset */ - if (q->merge_bvec_fn(q, &bvm, bvec) < len) { + if (q->merge_bvec_fn(q, bio, bvec) < len) { bvec->bv_page = NULL; bvec->bv_len = 0; bvec->bv_offset = 0; @@ -1257,9 +1249,6 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors) bp->bio1.bi_private = bi; bp->bio2.bi_private = pool; - if (bio_integrity(bi)) - bio_integrity_split(bi, bp, first_sectors); - return bp; } @@ -1301,7 +1290,6 @@ void bioset_free(struct bio_set *bs) if (bs->bio_pool) mempool_destroy(bs->bio_pool); - bioset_integrity_free(bs); biovec_free_pools(bs); kfree(bs); @@ -1318,9 +1306,6 @@ struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size) if (!bs->bio_pool) goto bad; - if (bioset_integrity_create(bs, bio_pool_size)) - goto bad; - if (!biovec_create_pools(bs, bvec_pool_size)) return bs; @@ -1347,7 +1332,6 @@ static int __init init_bio(void) { bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); - bio_integrity_init_slab(); biovec_init_slabs(); fs_bio_set = bioset_create(BIO_POOL_SIZE, 2); diff --git a/trunk/fs/ramfs/file-mmu.c b/trunk/fs/ramfs/file-mmu.c index 78f613cb9c76..9590b9024300 100644 --- a/trunk/fs/ramfs/file-mmu.c +++ b/trunk/fs/ramfs/file-mmu.c @@ -45,7 +45,6 @@ const struct file_operations ramfs_file_operations = { .mmap = generic_file_mmap, .fsync = simple_sync_file, .splice_read = generic_file_splice_read, - .splice_write = generic_file_splice_write, .llseek = generic_file_llseek, }; diff --git a/trunk/fs/ramfs/file-nommu.c b/trunk/fs/ramfs/file-nommu.c index 52312ec93ff4..0989bc2c2f69 100644 --- a/trunk/fs/ramfs/file-nommu.c +++ b/trunk/fs/ramfs/file-nommu.c @@ -43,7 +43,6 @@ const struct file_operations ramfs_file_operations = { .aio_write = generic_file_aio_write, .fsync = simple_sync_file, .splice_read = generic_file_splice_read, - .splice_write = generic_file_splice_write, .llseek = generic_file_llseek, }; diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index 399442179d89..aa5f6f60b305 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -379,22 +379,13 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, lock_page(page); /* - * Page was truncated, or invalidated by the - * filesystem. Redo the find/create, but this time the - * page is kept locked, so there's no chance of another - * race with truncate/invalidate. + * page was truncated, stop here. if this isn't the + * first page, we'll just complete what we already + * added */ if (!page->mapping) { unlock_page(page); - page = find_or_create_page(mapping, index, - mapping_gfp_mask(mapping)); - - if (!page) { - error = -ENOMEM; - break; - } - page_cache_release(pages[page_nr]); - pages[page_nr] = page; + break; } /* * page was already under io and is now done, great diff --git a/trunk/include/linux/bio.h b/trunk/include/linux/bio.h index 0933a14e6414..61c15eaf3fb3 100644 --- a/trunk/include/linux/bio.h +++ b/trunk/include/linux/bio.h @@ -64,7 +64,6 @@ struct bio_vec { struct bio_set; struct bio; -struct bio_integrity_payload; typedef void (bio_end_io_t) (struct bio *, int); typedef void (bio_destructor_t) (struct bio *); @@ -113,9 +112,6 @@ struct bio { atomic_t bi_cnt; /* pin count */ void *bi_private; -#if defined(CONFIG_BLK_DEV_INTEGRITY) - struct bio_integrity_payload *bi_integrity; /* data integrity */ -#endif bio_destructor_t *bi_destructor; /* destructor */ }; @@ -275,29 +271,6 @@ static inline void *bio_data(struct bio *bio) */ #define bio_get(bio) atomic_inc(&(bio)->bi_cnt) -#if defined(CONFIG_BLK_DEV_INTEGRITY) -/* - * bio integrity payload - */ -struct bio_integrity_payload { - struct bio *bip_bio; /* parent bio */ - struct bio_vec *bip_vec; /* integrity data vector */ - - sector_t bip_sector; /* virtual start sector */ - - void *bip_buf; /* generated integrity data */ - bio_end_io_t *bip_end_io; /* saved I/O completion fn */ - - int bip_error; /* saved I/O error */ - unsigned int bip_size; - - unsigned short bip_pool; /* pool the ivec came from */ - unsigned short bip_vcnt; /* # of integrity bio_vecs */ - unsigned short bip_idx; /* current bip_vec index */ - - struct work_struct bip_work; /* I/O completion */ -}; -#endif /* CONFIG_BLK_DEV_INTEGRITY */ /* * A bio_pair is used when we need to split a bio. @@ -310,14 +283,10 @@ struct bio_integrity_payload { * in bio2.bi_private */ struct bio_pair { - struct bio bio1, bio2; - struct bio_vec bv1, bv2; -#if defined(CONFIG_BLK_DEV_INTEGRITY) - struct bio_integrity_payload bip1, bip2; - struct bio_vec iv1, iv2; -#endif - atomic_t cnt; - int error; + struct bio bio1, bio2; + struct bio_vec bv1, bv2; + atomic_t cnt; + int error; }; extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors); @@ -364,39 +333,6 @@ extern struct bio *bio_copy_user_iov(struct request_queue *, struct sg_iovec *, int, int); extern int bio_uncopy_user(struct bio *); void zero_fill_bio(struct bio *bio); -extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set *); -extern unsigned int bvec_nr_vecs(unsigned short idx); - -/* - * bio_set is used to allow other portions of the IO system to - * allocate their own private memory pools for bio and iovec structures. - * These memory pools in turn all allocate from the bio_slab - * and the bvec_slabs[]. - */ -#define BIO_POOL_SIZE 2 -#define BIOVEC_NR_POOLS 6 - -struct bio_set { - mempool_t *bio_pool; -#if defined(CONFIG_BLK_DEV_INTEGRITY) - mempool_t *bio_integrity_pool; -#endif - mempool_t *bvec_pools[BIOVEC_NR_POOLS]; -}; - -struct biovec_slab { - int nr_vecs; - char *name; - struct kmem_cache *slab; -}; - -extern struct bio_set *fs_bio_set; - -/* - * a small number of entries is fine, not going to be performance critical. - * basically we just need to survive - */ -#define BIO_SPLIT_ENTRIES 2 #ifdef CONFIG_HIGHMEM /* @@ -445,63 +381,5 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx, __bio_kmap_irq((bio), (bio)->bi_idx, (flags)) #define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags) -#if defined(CONFIG_BLK_DEV_INTEGRITY) - -#define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)])) -#define bip_vec(bip) bip_vec_idx(bip, 0) - -#define __bip_for_each_vec(bvl, bip, i, start_idx) \ - for (bvl = bip_vec_idx((bip), (start_idx)), i = (start_idx); \ - i < (bip)->bip_vcnt; \ - bvl++, i++) - -#define bip_for_each_vec(bvl, bip, i) \ - __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx) - -static inline int bio_integrity(struct bio *bio) -{ -#if defined(CONFIG_BLK_DEV_INTEGRITY) - return bio->bi_integrity != NULL; -#else - return 0; -#endif -} - -extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *); -extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); -extern void bio_integrity_free(struct bio *, struct bio_set *); -extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); -extern int bio_integrity_enabled(struct bio *bio); -extern int bio_integrity_set_tag(struct bio *, void *, unsigned int); -extern int bio_integrity_get_tag(struct bio *, void *, unsigned int); -extern int bio_integrity_prep(struct bio *); -extern void bio_integrity_endio(struct bio *, int); -extern void bio_integrity_advance(struct bio *, unsigned int); -extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int); -extern void bio_integrity_split(struct bio *, struct bio_pair *, int); -extern int bio_integrity_clone(struct bio *, struct bio *, struct bio_set *); -extern int bioset_integrity_create(struct bio_set *, int); -extern void bioset_integrity_free(struct bio_set *); -extern void bio_integrity_init_slab(void); - -#else /* CONFIG_BLK_DEV_INTEGRITY */ - -#define bio_integrity(a) (0) -#define bioset_integrity_create(a, b) (0) -#define bio_integrity_prep(a) (0) -#define bio_integrity_enabled(a) (0) -#define bio_integrity_clone(a, b, c) (0) -#define bioset_integrity_free(a) do { } while (0) -#define bio_integrity_free(a, b) do { } while (0) -#define bio_integrity_endio(a, b) do { } while (0) -#define bio_integrity_advance(a, b) do { } while (0) -#define bio_integrity_trim(a, b, c) do { } while (0) -#define bio_integrity_split(a, b, c) do { } while (0) -#define bio_integrity_set_tag(a, b, c) do { } while (0) -#define bio_integrity_get_tag(a, b, c) do { } while (0) -#define bio_integrity_init_slab(a) do { } while (0) - -#endif /* CONFIG_BLK_DEV_INTEGRITY */ - #endif /* CONFIG_BLOCK */ #endif /* __LINUX_BIO_H */ diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 1ffd8bfdc4c9..d2a1b71e93c3 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -23,6 +23,7 @@ struct scsi_ioctl_command; struct request_queue; +typedef struct request_queue request_queue_t __deprecated; struct elevator_queue; typedef struct elevator_queue elevator_t; struct request_pm_state; @@ -33,6 +34,12 @@ struct sg_io_hdr; #define BLKDEV_MIN_RQ 4 #define BLKDEV_MAX_RQ 128 /* Default maximum */ +int put_io_context(struct io_context *ioc); +void exit_io_context(void); +struct io_context *get_io_context(gfp_t gfp_flags, int node); +struct io_context *alloc_io_context(gfp_t gfp_flags, int node); +void copy_io_context(struct io_context **pdst, struct io_context **psrc); + struct request; typedef void (rq_end_io_fn)(struct request *, int); @@ -106,7 +113,6 @@ enum rq_flag_bits { __REQ_ALLOCED, /* request came from our alloc pool */ __REQ_RW_META, /* metadata io request */ __REQ_COPY_USER, /* contains copies of user pages */ - __REQ_INTEGRITY, /* integrity metadata has been remapped */ __REQ_NR_BITS, /* stops here */ }; @@ -129,7 +135,6 @@ enum rq_flag_bits { #define REQ_ALLOCED (1 << __REQ_ALLOCED) #define REQ_RW_META (1 << __REQ_RW_META) #define REQ_COPY_USER (1 << __REQ_COPY_USER) -#define REQ_INTEGRITY (1 << __REQ_INTEGRITY) #define BLK_MAX_CDB 16 @@ -254,14 +259,7 @@ typedef int (prep_rq_fn) (struct request_queue *, struct request *); typedef void (unplug_fn) (struct request_queue *); struct bio_vec; -struct bvec_merge_data { - struct block_device *bi_bdev; - sector_t bi_sector; - unsigned bi_size; - unsigned long bi_rw; -}; -typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *, - struct bio_vec *); +typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *); typedef void (prepare_flush_fn) (struct request_queue *, struct request *); typedef void (softirq_done_fn)(struct request *); typedef int (dma_drain_needed_fn)(struct request *); @@ -428,32 +426,6 @@ static inline void queue_flag_set_unlocked(unsigned int flag, __set_bit(flag, &q->queue_flags); } -static inline int queue_flag_test_and_clear(unsigned int flag, - struct request_queue *q) -{ - WARN_ON_ONCE(!queue_is_locked(q)); - - if (test_bit(flag, &q->queue_flags)) { - __clear_bit(flag, &q->queue_flags); - return 1; - } - - return 0; -} - -static inline int queue_flag_test_and_set(unsigned int flag, - struct request_queue *q) -{ - WARN_ON_ONCE(!queue_is_locked(q)); - - if (!test_bit(flag, &q->queue_flags)) { - __set_bit(flag, &q->queue_flags); - return 0; - } - - return 1; -} - static inline void queue_flag_set(unsigned int flag, struct request_queue *q) { WARN_ON_ONCE(!queue_is_locked(q)); @@ -704,6 +676,7 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *, struct request *, int); extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, struct request *, int, rq_end_io_fn *); +extern int blk_verify_command(unsigned char *, int); extern void blk_unplug(struct request_queue *q); static inline struct request_queue *bdev_get_queue(struct block_device *bdev) @@ -776,7 +749,6 @@ extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); extern void blk_queue_dma_pad(struct request_queue *, unsigned int); -extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int); extern int blk_queue_dma_drain(struct request_queue *q, dma_drain_needed_fn *dma_drain_needed, void *buf, unsigned int size); @@ -830,15 +802,6 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, extern int blkdev_issue_flush(struct block_device *, sector_t *); -/* -* command filter functions -*/ -extern int blk_verify_command(struct file *file, unsigned char *cmd); -extern int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter, - unsigned char *cmd, mode_t *f_mode); -extern int blk_register_filter(struct gendisk *disk); -extern void blk_unregister_filter(struct gendisk *disk); - #define MAX_PHYS_SEGMENTS 128 #define MAX_HW_SEGMENTS 128 #define SAFE_MAX_SECTORS 255 @@ -902,116 +865,28 @@ void kblockd_flush_work(struct work_struct *work); #define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \ MODULE_ALIAS("block-major-" __stringify(major) "-*") -#if defined(CONFIG_BLK_DEV_INTEGRITY) - -#define INTEGRITY_FLAG_READ 2 /* verify data integrity on read */ -#define INTEGRITY_FLAG_WRITE 4 /* generate data integrity on write */ - -struct blk_integrity_exchg { - void *prot_buf; - void *data_buf; - sector_t sector; - unsigned int data_size; - unsigned short sector_size; - const char *disk_name; -}; - -typedef void (integrity_gen_fn) (struct blk_integrity_exchg *); -typedef int (integrity_vrfy_fn) (struct blk_integrity_exchg *); -typedef void (integrity_set_tag_fn) (void *, void *, unsigned int); -typedef void (integrity_get_tag_fn) (void *, void *, unsigned int); - -struct blk_integrity { - integrity_gen_fn *generate_fn; - integrity_vrfy_fn *verify_fn; - integrity_set_tag_fn *set_tag_fn; - integrity_get_tag_fn *get_tag_fn; - - unsigned short flags; - unsigned short tuple_size; - unsigned short sector_size; - unsigned short tag_size; - - const char *name; - - struct kobject kobj; -}; - -extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); -extern void blk_integrity_unregister(struct gendisk *); -extern int blk_integrity_compare(struct block_device *, struct block_device *); -extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); -extern int blk_rq_count_integrity_sg(struct request *); - -static inline unsigned short blk_integrity_tuple_size(struct blk_integrity *bi) -{ - if (bi) - return bi->tuple_size; - - return 0; -} -static inline struct blk_integrity *bdev_get_integrity(struct block_device *bdev) -{ - return bdev->bd_disk->integrity; -} +#else /* CONFIG_BLOCK */ +/* + * stubs for when the block layer is configured out + */ +#define buffer_heads_over_limit 0 -static inline unsigned int bdev_get_tag_size(struct block_device *bdev) +static inline long nr_blockdev_pages(void) { - struct blk_integrity *bi = bdev_get_integrity(bdev); - - if (bi) - return bi->tag_size; - return 0; } -static inline int bdev_integrity_enabled(struct block_device *bdev, int rw) +static inline void exit_io_context(void) { - struct blk_integrity *bi = bdev_get_integrity(bdev); - - if (bi == NULL) - return 0; - - if (rw == READ && bi->verify_fn != NULL && - (bi->flags & INTEGRITY_FLAG_READ)) - return 1; - - if (rw == WRITE && bi->generate_fn != NULL && - (bi->flags & INTEGRITY_FLAG_WRITE)) - return 1; - - return 0; } -static inline int blk_integrity_rq(struct request *rq) +struct io_context; +static inline int put_io_context(struct io_context *ioc) { - return bio_integrity(rq->bio); + return 1; } -#else /* CONFIG_BLK_DEV_INTEGRITY */ - -#define blk_integrity_rq(rq) (0) -#define blk_rq_count_integrity_sg(a) (0) -#define blk_rq_map_integrity_sg(a, b) (0) -#define bdev_get_integrity(a) (0) -#define bdev_get_tag_size(a) (0) -#define blk_integrity_compare(a, b) (0) -#define blk_integrity_register(a, b) (0) -#define blk_integrity_unregister(a) do { } while (0); - -#endif /* CONFIG_BLK_DEV_INTEGRITY */ - -#else /* CONFIG_BLOCK */ -/* - * stubs for when the block layer is configured out - */ -#define buffer_heads_over_limit 0 - -static inline long nr_blockdev_pages(void) -{ - return 0; -} #endif /* CONFIG_BLOCK */ diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index d084b8d227a5..e3ef903aae88 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -129,7 +129,6 @@ struct blk_trace { u32 dev; struct dentry *dir; struct dentry *dropped_file; - struct dentry *msg_file; atomic_t dropped; }; diff --git a/trunk/include/linux/genhd.h b/trunk/include/linux/genhd.h index e8787417f65a..ae7aec3cabee 100644 --- a/trunk/include/linux/genhd.h +++ b/trunk/include/linux/genhd.h @@ -110,14 +110,6 @@ struct hd_struct { #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 #define GENHD_FL_FAIL 64 -#define BLK_SCSI_MAX_CMDS (256) -#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) - -struct blk_scsi_cmd_filter { - unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; - unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; - struct kobject kobj; -}; struct gendisk { int major; /* major number of driver */ @@ -128,7 +120,6 @@ struct gendisk { struct hd_struct **part; /* [indexed by minor] */ struct block_device_operations *fops; struct request_queue *queue; - struct blk_scsi_cmd_filter cmd_filter; void *private_data; sector_t capacity; @@ -150,9 +141,6 @@ struct gendisk { struct disk_stats dkstats; #endif struct work_struct async_notify; -#ifdef CONFIG_BLK_DEV_INTEGRITY - struct blk_integrity *integrity; -#endif }; /* diff --git a/trunk/include/linux/iocontext.h b/trunk/include/linux/iocontext.h index 08b987bccf89..2b7a1187cb29 100644 --- a/trunk/include/linux/iocontext.h +++ b/trunk/include/linux/iocontext.h @@ -99,22 +99,4 @@ static inline struct io_context *ioc_task_link(struct io_context *ioc) return NULL; } -#ifdef CONFIG_BLOCK -int put_io_context(struct io_context *ioc); -void exit_io_context(void); -struct io_context *get_io_context(gfp_t gfp_flags, int node); -struct io_context *alloc_io_context(gfp_t gfp_flags, int node); -void copy_io_context(struct io_context **pdst, struct io_context **psrc); -#else -static inline void exit_io_context(void) -{ -} - -struct io_context; -static inline int put_io_context(struct io_context *ioc) -{ - return 1; -} -#endif - #endif diff --git a/trunk/include/pcmcia/bulkmem.h b/trunk/include/pcmcia/bulkmem.h new file mode 100644 index 000000000000..6bc7472293b2 --- /dev/null +++ b/trunk/include/pcmcia/bulkmem.h @@ -0,0 +1,41 @@ +/* + * bulkmem.h -- Definitions for bulk memory services + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * (C) 1999 David A. Hinds + */ + +#ifndef _LINUX_BULKMEM_H +#define _LINUX_BULKMEM_H + +/* For GetFirstRegion and GetNextRegion */ +typedef struct region_info_t { + u_int Attributes; + u_int CardOffset; + u_int RegionSize; + u_int AccessSpeed; + u_int BlockSize; + u_int PartMultiple; + u_char JedecMfr, JedecInfo; + memory_handle_t next; +} region_info_t; + +#define REGION_TYPE 0x0001 +#define REGION_TYPE_CM 0x0000 +#define REGION_TYPE_AM 0x0001 +#define REGION_PREFETCH 0x0008 +#define REGION_CACHEABLE 0x0010 +#define REGION_BAR_MASK 0xe000 +#define REGION_BAR_SHIFT 13 + +int pcmcia_get_first_region(struct pcmcia_device *handle, region_info_t *rgn); +int pcmcia_get_next_region(struct pcmcia_device *handle, region_info_t *rgn); + +#endif /* _LINUX_BULKMEM_H */ diff --git a/trunk/include/pcmcia/cistpl.h b/trunk/include/pcmcia/cistpl.h index e2e10c1e9a06..d3bbb19caf81 100644 --- a/trunk/include/pcmcia/cistpl.h +++ b/trunk/include/pcmcia/cistpl.h @@ -595,7 +595,7 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse); -int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *count); +int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info); /* ... but use these wrappers instead */ #define pcmcia_get_first_tuple(p_dev, tuple) \ diff --git a/trunk/include/pcmcia/cs.h b/trunk/include/pcmcia/cs.h index 45d84b275789..87a260e3699e 100644 --- a/trunk/include/pcmcia/cs.h +++ b/trunk/include/pcmcia/cs.h @@ -373,6 +373,9 @@ struct pcmcia_socket; int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg); int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config); +int pcmcia_get_first_window(window_handle_t *win, win_req_t *req); +int pcmcia_get_next_window(window_handle_t *win, win_req_t *req); +int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status); int pcmcia_get_mem_page(window_handle_t win, memreq_t *req); int pcmcia_map_mem_page(window_handle_t win, memreq_t *req); int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); diff --git a/trunk/include/pcmcia/cs_types.h b/trunk/include/pcmcia/cs_types.h index f402a0f435b4..9a6bcc4952f0 100644 --- a/trunk/include/pcmcia/cs_types.h +++ b/trunk/include/pcmcia/cs_types.h @@ -21,8 +21,7 @@ #include #endif -#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \ - defined(__bfin__) +#if defined(__arm__) || defined(__mips__) || defined(__avr32__) /* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */ typedef u_int ioaddr_t; #else @@ -34,6 +33,9 @@ typedef u_int event_t; typedef u_char cisdata_t; typedef u_short page_t; +struct pcmcia_device; +typedef struct pcmcia_device *client_handle_t; + struct window_t; typedef struct window_t *window_handle_t; diff --git a/trunk/include/pcmcia/ds.h b/trunk/include/pcmcia/ds.h index b316027c853d..f047a1fd64f8 100644 --- a/trunk/include/pcmcia/ds.h +++ b/trunk/include/pcmcia/ds.h @@ -20,6 +20,7 @@ #include #endif +#include #include #include @@ -50,24 +51,6 @@ typedef struct mtd_info_t { u_int CardOffset; } mtd_info_t; -typedef struct region_info_t { - u_int Attributes; - u_int CardOffset; - u_int RegionSize; - u_int AccessSpeed; - u_int BlockSize; - u_int PartMultiple; - u_char JedecMfr, JedecInfo; - memory_handle_t next; -} region_info_t; -#define REGION_TYPE 0x0001 -#define REGION_TYPE_CM 0x0000 -#define REGION_TYPE_AM 0x0001 -#define REGION_PREFETCH 0x0008 -#define REGION_CACHEABLE 0x0010 -#define REGION_BAR_MASK 0xe000 -#define REGION_BAR_SHIFT 13 - typedef union ds_ioctl_arg_t { adjust_t adjust; config_info_t config; diff --git a/trunk/include/pcmcia/ss.h b/trunk/include/pcmcia/ss.h index ed919dd9bb5c..f95dca077c1c 100644 --- a/trunk/include/pcmcia/ss.h +++ b/trunk/include/pcmcia/ss.h @@ -21,6 +21,7 @@ #include #include +#include #ifdef CONFIG_CARDBUS #include #endif @@ -135,14 +136,8 @@ struct pccard_resource_ops { struct resource* (*find_mem) (unsigned long base, unsigned long num, unsigned long align, int low, struct pcmcia_socket *s); - int (*add_io) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); - int (*add_mem) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); + int (*adjust_resource) (struct pcmcia_socket *s, + adjust_t *adj); int (*init) (struct pcmcia_socket *s); void (*exit) (struct pcmcia_socket *s); }; @@ -250,6 +245,7 @@ struct pcmcia_socket { struct task_struct *thread; struct completion thread_done; + wait_queue_head_t thread_wait; spinlock_t thread_lock; /* protects thread_events */ unsigned int thread_events; diff --git a/trunk/include/pcmcia/version.h b/trunk/include/pcmcia/version.h new file mode 100644 index 000000000000..5ad9c5e198b6 --- /dev/null +++ b/trunk/include/pcmcia/version.h @@ -0,0 +1,3 @@ +/* version.h 1.94 2000/10/03 17:55:48 (David Hinds) */ + +/* This file will be removed, please don't include it */ diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index ceb258782835..8f6185e69b69 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index b71ccd09fc8d..19908b26cf80 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 5f6e2c4a2ba7..315c392253c7 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -431,8 +431,9 @@ static void print_track(const char *s, struct track *t) if (!t->addr) return; - printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n", - s, t->addr, jiffies - t->when, t->cpu, t->pid); + printk(KERN_ERR "INFO: %s in ", s); + __print_symbol("%s", (unsigned long)t->addr); + printk(" age=%lu cpu=%u pid=%d\n", jiffies - t->when, t->cpu, t->pid); } static void print_tracking(struct kmem_cache *s, void *object)