diff options
Diffstat (limited to 'drivers')
46 files changed, 1024 insertions, 690 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 57a43649a46..499ccc628d8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -885,7 +885,8 @@ 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_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); + blk_queue_update_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/drivers/block/DAC960.c b/drivers/block/DAC960.c index cd03473f354..a002a381df9 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -6628,15 +6628,18 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller) * DAC960_gam_ioctl is the ioctl function for performing RAID operations. */ -static int DAC960_gam_ioctl(struct inode *inode, struct file *file, - unsigned int Request, unsigned long Argument) +static long DAC960_gam_ioctl(struct file *file, unsigned int Request, + unsigned long Argument) { - int ErrorCode = 0; + long ErrorCode = 0; if (!capable(CAP_SYS_ADMIN)) return -EACCES; + + lock_kernel(); switch (Request) { case DAC960_IOCTL_GET_CONTROLLER_COUNT: - return DAC960_ControllerCount; + ErrorCode = DAC960_ControllerCount; + break; case DAC960_IOCTL_GET_CONTROLLER_INFO: { DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = @@ -6644,15 +6647,20 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, DAC960_ControllerInfo_T ControllerInfo; DAC960_Controller_T *Controller; int ControllerNumber; - if (UserSpaceControllerInfo == NULL) return -EINVAL; - ErrorCode = get_user(ControllerNumber, + if (UserSpaceControllerInfo == NULL) + ErrorCode = -EINVAL; + else ErrorCode = get_user(ControllerNumber, &UserSpaceControllerInfo->ControllerNumber); - if (ErrorCode != 0) return ErrorCode; + if (ErrorCode != 0) + break;; + ErrorCode = -ENXIO; if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + ControllerNumber > DAC960_ControllerCount - 1) { + break; + } Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; + if (Controller == NULL) + break;; memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); ControllerInfo.ControllerNumber = ControllerNumber; ControllerInfo.FirmwareType = Controller->FirmwareType; @@ -6665,8 +6673,9 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, ControllerInfo.PCI_Address = Controller->PCI_Address; strcpy(ControllerInfo.ModelName, Controller->ModelName); strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); - return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, + ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); + break; } case DAC960_IOCTL_V1_EXECUTE_COMMAND: { @@ -6684,30 +6693,39 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, int ControllerNumber, DataTransferLength; unsigned char *DataTransferBuffer = NULL; dma_addr_t DataTransferBufferDMA; - if (UserSpaceUserCommand == NULL) return -EINVAL; + if (UserSpaceUserCommand == NULL) { + ErrorCode = -EINVAL; + break; + } if (copy_from_user(&UserCommand, UserSpaceUserCommand, sizeof(DAC960_V1_UserCommand_T))) { ErrorCode = -EFAULT; - goto Failure1a; + break; } ControllerNumber = UserCommand.ControllerNumber; + ErrorCode = -ENXIO; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + break; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; + if (Controller == NULL) + break; + ErrorCode = -EINVAL; + if (Controller->FirmwareType != DAC960_V1_Controller) + break; CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; DataTransferLength = UserCommand.DataTransferLength; - if (CommandOpcode & 0x80) return -EINVAL; + if (CommandOpcode & 0x80) + break; if (CommandOpcode == DAC960_V1_DCDB) { if (copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T))) { ErrorCode = -EFAULT; - goto Failure1a; + break; } - if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; + if (DCDB.Channel >= DAC960_V1_MaxChannels) + break; if (!((DataTransferLength == 0 && DCDB.Direction == DAC960_V1_DCDB_NoDataTransfer) || @@ -6717,38 +6735,37 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, (DataTransferLength < 0 && DCDB.Direction == DAC960_V1_DCDB_DataTransferSystemToDevice))) - return -EINVAL; + break; if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) != abs(DataTransferLength)) - return -EINVAL; + break; DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); - if (DCDB_IOBUF == NULL) - return -ENOMEM; + if (DCDB_IOBUF == NULL) { + ErrorCode = -ENOMEM; + break; + } } + ErrorCode = -ENOMEM; if (DataTransferLength > 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) { - ErrorCode = -ENOMEM; - goto Failure1; - } + if (DataTransferBuffer == NULL) + break; memset(DataTransferBuffer, 0, DataTransferLength); } else if (DataTransferLength < 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) { - ErrorCode = -ENOMEM; - goto Failure1; - } + if (DataTransferBuffer == NULL) + break; if (copy_from_user(DataTransferBuffer, UserCommand.DataTransferBuffer, -DataTransferLength)) { ErrorCode = -EFAULT; - goto Failure1; + break; } } if (CommandOpcode == DAC960_V1_DCDB) @@ -6825,8 +6842,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, if (DCDB_IOBUF != NULL) pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), DCDB_IOBUF, DCDB_IOBUFDMA); - Failure1a: - return ErrorCode; + break; } case DAC960_IOCTL_V2_EXECUTE_COMMAND: { @@ -6844,32 +6860,43 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, dma_addr_t DataTransferBufferDMA; unsigned char *RequestSenseBuffer = NULL; dma_addr_t RequestSenseBufferDMA; - if (UserSpaceUserCommand == NULL) return -EINVAL; + + ErrorCode = -EINVAL; + if (UserSpaceUserCommand == NULL) + break; if (copy_from_user(&UserCommand, UserSpaceUserCommand, sizeof(DAC960_V2_UserCommand_T))) { ErrorCode = -EFAULT; - goto Failure2a; + break; } + ErrorCode = -ENXIO; ControllerNumber = UserCommand.ControllerNumber; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + break; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; + if (Controller == NULL) + break; + if (Controller->FirmwareType != DAC960_V2_Controller){ + ErrorCode = -EINVAL; + break; + } DataTransferLength = UserCommand.DataTransferLength; + ErrorCode = -ENOMEM; if (DataTransferLength > 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) return -ENOMEM; + if (DataTransferBuffer == NULL) + break; memset(DataTransferBuffer, 0, DataTransferLength); } else if (DataTransferLength < 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) return -ENOMEM; + if (DataTransferBuffer == NULL) + break; if (copy_from_user(DataTransferBuffer, UserCommand.DataTransferBuffer, -DataTransferLength)) { @@ -6979,8 +7006,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, if (RequestSenseBuffer != NULL) pci_free_consistent(Controller->PCIDevice, RequestSenseLength, RequestSenseBuffer, RequestSenseBufferDMA); - Failure2a: - return ErrorCode; + break; } case DAC960_IOCTL_V2_GET_HEALTH_STATUS: { @@ -6990,21 +7016,33 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; DAC960_Controller_T *Controller; int ControllerNumber; - if (UserSpaceGetHealthStatus == NULL) return -EINVAL; + if (UserSpaceGetHealthStatus == NULL) { + ErrorCode = -EINVAL; + break; + } if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, - sizeof(DAC960_V2_GetHealthStatus_T))) - return -EFAULT; + sizeof(DAC960_V2_GetHealthStatus_T))) { + ErrorCode = -EFAULT; + break; + } + ErrorCode = -ENXIO; ControllerNumber = GetHealthStatus.ControllerNumber; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + break; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; + if (Controller == NULL) + break; + if (Controller->FirmwareType != DAC960_V2_Controller) { + ErrorCode = -EINVAL; + break; + } if (copy_from_user(&HealthStatusBuffer, GetHealthStatus.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) - return -EFAULT; + sizeof(DAC960_V2_HealthStatusBuffer_T))) { + ErrorCode = -EFAULT; + break; + } while (Controller->V2.HealthStatusBuffer->StatusChangeCounter == HealthStatusBuffer.StatusChangeCounter && Controller->V2.HealthStatusBuffer->NextEventSequenceNumber @@ -7012,21 +7050,28 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, { interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, DAC960_MonitoringTimerInterval); - if (signal_pending(current)) return -EINTR; + if (signal_pending(current)) { + ErrorCode = -EINTR; + break; + } } if (copy_to_user(GetHealthStatus.HealthStatusBuffer, Controller->V2.HealthStatusBuffer, sizeof(DAC960_V2_HealthStatusBuffer_T))) - return -EFAULT; - return 0; + ErrorCode = -EFAULT; + else + ErrorCode = 0; } + default: + ErrorCode = -ENOTTY; } - return -EINVAL; + unlock_kernel(); + return ErrorCode; } static const struct file_operations DAC960_gam_fops = { .owner = THIS_MODULE, - .ioctl = DAC960_gam_ioctl + .unlocked_ioctl = DAC960_gam_ioctl }; static struct miscdevice DAC960_gam_dev = { diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 41f818be2f7..2f1746295d0 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/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 = be16_to_cpu(get_unaligned(&h->major)); + aoemajor = get_unaligned_be16(&h->major); if (aoemajor == 0xfff) { printk(KERN_ERR "aoe: Warning: shelf address is all ones. " "Check shelf dip switches.\n"); diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 8b9549ab4a4..27455ee1e9d 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; #include <linux/mtio.h> #include <linux/device.h> #include <linux/sched.h> /* current, TASK_*, schedule_timeout() */ +#include <linux/smp_lock.h> #include <asm/uaccess.h> @@ -189,8 +190,7 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_LOG_SENSE 0x4d static int pt_open(struct inode *inode, struct file *file); -static int pt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long pt_ioctl(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, - .ioctl = pt_ioctl, + .unlocked_ioctl = pt_ioctl, .open = pt_open, .release = pt_release, }; @@ -685,8 +685,7 @@ out: return err; } -static int pt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct pt_unit *tape = file->private_data; struct mtop __user *p = (void __user *)arg; @@ -700,23 +699,26 @@ static int pt_ioctl(struct inode *inode, struct file *file, 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: - printk("%s: Unimplemented mt_op %d\n", tape->name, + /* FIXME: rate limit ?? */ + printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name, mtop.mt_op); return -EINVAL; } default: - printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd); - return -EINVAL; - + return -ENOTTY; } } diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3ba1df93e9e..45bee918c46 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -49,6 +49,7 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/kthread.h> +#include <linux/smp_lock.h> #include <linux/errno.h> #include <linux/spinlock.h> #include <linux/file.h> @@ -2079,7 +2080,6 @@ 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,7 +2126,6 @@ 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; @@ -2633,11 +2632,12 @@ end_io: -static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec) +static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, + struct bio_vec *bvec) { struct pktcdvd_device *pd = q->queuedata; - sector_t zone = ZONE(bio->bi_sector, pd); - int used = ((bio->bi_sector - zone) << 9) + bio->bi_size; + sector_t zone = ZONE(bmd->bi_sector, pd); + int used = ((bmd->bi_sector - zone) << 9) + bmd->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 bio *bio, struct bio_v * A bio <= PAGE_SIZE must be allowed. If it crosses a packet * boundary, pkt_make_request() will split the bio. */ - remaining2 = PAGE_SIZE - bio->bi_size; + remaining2 = PAGE_SIZE - bmd->bi_size; remaining = max(remaining, remaining2); BUG_ON(remaining < 0); @@ -2796,9 +2796,14 @@ out_mem: return ret; } -static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; + 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; VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); @@ -2811,7 +2816,8 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u case CDROM_LAST_WRITTEN: case CDROM_SEND_PACKET: case SCSI_IOCTL_SEND_COMMAND: - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + break; case CDROMEJECT: /* @@ -2820,14 +2826,15 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u */ if (pd->refcnt == 1) pkt_lock_door(pd, 0); - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + break; default: VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); - return -ENOTTY; + ret = -ENOTTY; } - - return 0; + unlock_kernel(); + return ret; } static int pkt_media_changed(struct gendisk *disk) @@ -2849,7 +2856,7 @@ static struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .ioctl = pkt_ioctl, + .unlocked_ioctl = pkt_ioctl, .media_changed = pkt_media_changed, }; @@ -3014,7 +3021,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) mutex_unlock(&ctl_mutex); } -static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; struct pkt_ctrl_command ctrl_cmd; @@ -3031,16 +3039,22 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm 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; @@ -3053,7 +3067,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm static const struct file_operations pkt_ctl_fops = { - .ioctl = pkt_ctl_ioctl, + .unlocked_ioctl = pkt_ctl_ioctl, .owner = THIS_MODULE, }; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index f2fff5799dd..9ae05c58423 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -38,6 +38,7 @@ #include <linux/interrupt.h> #include <linux/blkdev.h> #include <linux/hdreg.h> +#include <linux/cdrom.h> #include <linux/module.h> #include <xen/xenbus.h> @@ -153,6 +154,40 @@ 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 * @@ -324,6 +359,9 @@ 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; @@ -546,7 +584,7 @@ static int setup_blkring(struct xenbus_device *dev, info->ring_ref = GRANT_INVALID_REF; - sring = (struct blkif_sring *)__get_free_page(GFP_KERNEL); + sring = (struct blkif_sring *)__get_free_page(GFP_NOIO | __GFP_HIGH); if (!sring) { xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); return -ENOMEM; @@ -703,7 +741,8 @@ 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_KERNEL); + copy = kmalloc(sizeof(info->shadow), + GFP_NOIO | __GFP_REPEAT | __GFP_HIGH); if (!copy) return -ENOMEM; memcpy(copy, info->shadow, sizeof(info->shadow)); @@ -959,7 +998,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) + if (state == XenbusStateClosing && info->is_ready) blkfront_closing(dev); } return 0; @@ -971,6 +1010,7 @@ static struct block_device_operations xlvbd_block_fops = .open = blkif_open, .release = blkif_release, .getgeo = blkif_getgeo, + .ioctl = blkif_ioctl, }; @@ -1006,7 +1046,7 @@ static int __init xlblk_init(void) module_init(xlblk_init); -static void xlblk_exit(void) +static void __exit xlblk_exit(void) { return xenbus_unregister_driver(&blkfront); } diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 69f26eb6415..a5da3563265 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -461,37 +461,27 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med) { struct packet_command cgc; - unsigned char *buffer; - struct event_header *eh; - int ret = 1; - - buffer = kmalloc(8, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + unsigned char buffer[8]; + struct event_header *eh = (struct event_header *) buffer; - eh = (struct event_header *)buffer; - - init_cdrom_command(&cgc, buffer, 8, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), 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] = 8; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if (cdi->ops->generic_packet(cdi, &cgc)) - goto err; + return 1; if (be16_to_cpu(eh->data_len) < sizeof(*med)) - goto err; + return 1; if (eh->nea || eh->notification_class != 0x4) - goto err; + return 1; - memcpy(med, buffer + sizeof(*eh), sizeof(*med)); - ret = 0; -err: - kfree(buffer); - return ret; + memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); + return 0; } /* @@ -501,82 +491,68 @@ err: static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) { struct packet_command cgc; - char *buffer; - int ret = 1; - - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + char buffer[16]; - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), 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; - ret = 0; + return 0; } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { cdi->mrw_mode_page = MRW_MODE_PC_PRE1; - ret = 0; + return 0; } - kfree(buffer); - return ret; + + return 1; } static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) { struct packet_command cgc; struct mrw_feature_desc *mfd; - unsigned char *buffer; + unsigned char buffer[16]; int ret; *write = 0; - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[3] = CDF_MRW; - cgc.cmd[8] = 16; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - goto err; + return ret; mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; - if (be16_to_cpu(mfd->feature_code) != CDF_MRW) { - ret = 1; - goto err; - } + if (be16_to_cpu(mfd->feature_code) != CDF_MRW) + return 1; *write = mfd->write; if ((ret = cdrom_mrw_probe_pc(cdi))) { *write = 0; + return ret; } -err: - kfree(buffer); - return ret; + + return 0; } static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) { struct packet_command cgc; - unsigned char *buffer; + unsigned char buffer[12]; 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, 12, CGC_DATA_WRITE); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE); cgc.cmd[0] = GPCMD_FORMAT_UNIT; cgc.cmd[1] = (1 << 4) | 1; @@ -603,7 +579,6 @@ 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; } @@ -663,17 +638,16 @@ 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; + char buffer[16]; int ret, offset, size; - 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.buffer = buffer; + cgc.buflen = sizeof(buffer); if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) - goto err; + return ret; mph = (struct mode_page_header *) buffer; offset = be16_to_cpu(mph->desc_length); @@ -683,70 +657,55 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) cgc.buflen = size; if ((ret = cdrom_mode_select(cdi, &cgc))) - goto err; + return ret; printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); - ret = 0; -err: - kfree(buffer); - return ret; + return 0; } static int cdrom_get_random_writable(struct cdrom_device_info *cdi, struct rwrt_feature_desc *rfd) { struct packet_command cgc; - char *buffer; + char buffer[24]; int ret; - buffer = kmalloc(24, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - init_cdrom_command(&cgc, buffer, 24, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ - cgc.cmd[8] = 24; /* often 0x18 */ + cgc.cmd[8] = sizeof(buffer); /* often 0x18 */ cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - goto err; + return ret; memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); - ret = 0; -err: - kfree(buffer); - return ret; + return 0; } static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) { struct packet_command cgc; - char *buffer; + char buffer[16]; __be16 *feature_code; int ret; - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[3] = CDF_HWDM; - cgc.cmd[8] = 16; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - goto err; + return ret; feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; if (be16_to_cpu(*feature_code) == CDF_HWDM) - ret = 0; -err: - kfree(buffer); - return ret; + return 0; + + return 1; } @@ -837,14 +796,10 @@ 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; + char buffer[255]; int ret; - buffer = kmalloc(255, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - init_cdrom_command(&cgc, buffer, 4, CGC_DATA_READ); + init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ); cgc.quiet = 1; /* @@ -861,15 +816,10 @@ static int mo_open_write(struct cdrom_device_info *cdi) } /* drive gave us no info, let the user go ahead */ - if (ret) { - ret = 0; - goto err; - } + if (ret) + return 0; - ret = buffer[3] & 0x80; -err: - kfree(buffer); - return ret; + return buffer[3] & 0x80; } static int cdrom_ram_open_write(struct cdrom_device_info *cdi) @@ -892,19 +842,15 @@ 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; + char buffer[32]; int ret, mmc3_profile; - buffer = kmalloc(32, GFP_KERNEL); - if (!buffer) - return; - - init_cdrom_command(&cgc, buffer, 32, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), 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] = 32; /* Allocation Length */ + cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) @@ -913,7 +859,6 @@ 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) @@ -1628,15 +1573,12 @@ 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; + u_char buf[20]; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - rpc_state_t *rpc_state; - - buf = kzalloc(20, GFP_KERNEL); - if (!buf) - return -ENOMEM; + rpc_state_t rpc_state; + memset(buf, 0, sizeof(buf)); init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); switch (ai->type) { @@ -1647,7 +1589,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))) - goto err; + return ret; ai->lsa.agid = buf[7] >> 6; /* Returning data, let host change state */ @@ -1658,7 +1600,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))) - goto err; + return ret; copy_key(ai->lsk.key, &buf[4]); /* Returning data, let host change state */ @@ -1669,7 +1611,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))) - goto err; + return ret; copy_chal(ai->lsc.chal, &buf[4]); /* Returning data, let host change state */ @@ -1686,7 +1628,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))) - goto err; + return ret; ai->lstk.cpm = (buf[4] >> 7) & 1; ai->lstk.cp_sec = (buf[4] >> 6) & 1; @@ -1700,7 +1642,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))) - goto err; + return ret; ai->lsasf.asf = buf[7] & 1; break; @@ -1713,7 +1655,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))) - goto err; + return ret; ai->type = DVD_LU_SEND_KEY1; break; @@ -1726,7 +1668,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; - goto err; + return ret; } ai->type = DVD_AUTH_ESTABLISHED; break; @@ -1737,23 +1679,24 @@ 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))) - goto err; + return ret; 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))) - goto err; + return ret; - 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; + 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 */ @@ -1764,23 +1707,20 @@ 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))) - goto err; + return ret; break; default: cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); - ret = -ENOTTY; - goto err; + return -ENOTTY; } - ret = 0; -err: - kfree(buf); - return ret; + + return 0; } static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) { - unsigned char *buf, *base; + unsigned char buf[21], *base; struct dvd_layer *layer; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; @@ -1789,11 +1729,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) if (layer_num >= DVD_LAYERS) return -EINVAL; - buf = kmalloc(21, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - init_cdrom_command(&cgc, buf, 21, CGC_DATA_READ); + init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[6] = layer_num; cgc.cmd[7] = s->type; @@ -1805,7 +1741,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) cgc.quiet = 1; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; base = &buf[4]; layer = &s->physical.layer[layer_num]; @@ -1829,24 +1765,17 @@ 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; - ret = 0; -err: - kfree(buf); - return ret; + return 0; } static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) { int ret; - u_char *buf; + u_char buf[8]; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - buf = kmalloc(8, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - init_cdrom_command(&cgc, buf, 8, CGC_DATA_READ); + init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[6] = s->copyright.layer_num; cgc.cmd[7] = s->type; @@ -1854,15 +1783,12 @@ 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))) - goto err; + return ret; s->copyright.cpst = buf[4]; s->copyright.rmi = buf[5]; - ret = 0; -err: - kfree(buf); - return ret; + return 0; } static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) @@ -1894,33 +1820,26 @@ 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; + u_char buf[4 + 188]; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - buf = kmalloc(4 + 188, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - init_cdrom_command(&cgc, buf, 4 + 188, CGC_DATA_READ); + init_cdrom_command(&cgc, buf, sizeof(buf), 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))) - goto err; + return ret; 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); - ret = -EIO; - goto err; + return -EIO; } memcpy(s->bca.value, &buf[4], s->bca.len); - ret = 0; -err: - kfree(buf); - return ret; + + return 0; } static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) @@ -2020,13 +1939,9 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, { struct cdrom_device_ops *cdo = cdi->ops; struct packet_command cgc; - char *buffer; + char buffer[32]; 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 */ @@ -2035,7 +1950,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, cgc.cmd[8] = 16; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; subchnl->cdsc_audiostatus = cgc.buffer[1]; subchnl->cdsc_format = CDROM_MSF; @@ -2050,10 +1965,7 @@ 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]; - ret = 0; -err: - kfree(buffer); - return ret; + return 0; } /* diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 4a933d41342..59ca35156d8 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -32,8 +32,9 @@ #include <linux/fs.h> #include <linux/delay.h> #include <linux/bitrev.h> -#include <asm/uaccess.h> -#include <asm/io.h> +#include <linux/smp_lock.h> +#include <linux/uaccess.h> +#include <linux/io.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> @@ -1405,11 +1406,11 @@ static void stop_monitor(struct cm4000_dev *dev) DEBUGP(3, dev, "<- stop_monitor\n"); } -static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +static long cmm_ioctl(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; @@ -1426,38 +1427,42 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 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"); - return -ENODEV; + goto out; } if (test_bit(IS_CMM_ABSENT, &dev->flags)) { DEBUGP(4, dev, "CMM_ABSENT flag set\n"); - return -ENODEV; + goto out; } + rc = EINVAL; if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) { DEBUGP(4, dev, "ioctype mismatch\n"); - return -EINVAL; + goto out; } if (_IOC_NR(cmd) > CM_IOC_MAXNR) { DEBUGP(4, dev, "iocnr mismatch\n"); - return -EINVAL; + goto out; } size = _IOC_SIZE(cmd); - rc = 0; + rc = -EFAULT; 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)) - return -EFAULT; + goto out; } if (_IOC_DIR(cmd) & _IOC_WRITE) { if (!access_ok(VERIFY_READ, argp, size)) - return -EFAULT; + goto out; } + rc = 0; switch (cmd) { case CM_IOCGSTATUS: @@ -1477,9 +1482,9 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, if (test_bit(IS_BAD_CARD, &dev->flags)) status |= CM_BAD_CARD; if (copy_to_user(argp, &status, sizeof(int))) - return -EFAULT; + rc = -EFAULT; } - return 0; + break; case CM_IOCGATR: DEBUGP(4, dev, "... in CM_IOCGATR\n"); { @@ -1492,25 +1497,29 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) { if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - return -ERESTARTSYS; + rc = -EAGAIN; + else + rc = -ERESTARTSYS; + break; } + rc = -EFAULT; if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { tmp = -1; if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int))) - return -EFAULT; + break; } else { if (copy_to_user(atreq->atr, dev->atr, dev->atr_len)) - return -EFAULT; + break; tmp = dev->atr_len; if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int))) - return -EFAULT; + break; } - return 0; + rc = 0; + break; } case CM_IOCARDOFF: @@ -1538,8 +1547,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) { if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - return -ERESTARTSYS; + rc = -EAGAIN; + else + rc = -ERESTARTSYS; + break; } /* Set Flags0 = 0x42 */ DEBUGP(4, dev, "Set Flags0=0x42 \n"); @@ -1554,8 +1565,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, || (test_bit(IS_ATR_VALID, (void *)&dev->flags) != 0)))) { if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - return -ERESTARTSYS; + rc = -EAGAIN; + else + rc = -ERESTARTSYS; + break; } } /* release lock */ @@ -1568,8 +1581,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, struct ptsreq krnptsreq; if (copy_from_user(&krnptsreq, argp, - sizeof(struct ptsreq))) - return -EFAULT; + sizeof(struct ptsreq))) { + rc = -EFAULT; + break; + } rc = 0; DEBUGP(4, dev, "... in CM_IOCSPTS\n"); @@ -1580,8 +1595,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) { if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - return -ERESTARTSYS; + rc = -EAGAIN; + else + rc = -ERESTARTSYS; + break; } /* get IO lock */ if (wait_event_interruptible @@ -1590,8 +1607,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) { if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - return -ERESTARTSYS; + rc = -EAGAIN; + else + rc = -ERESTARTSYS; + break; } if ((rc = set_protocol(dev, &krnptsreq)) != 0) { @@ -1604,7 +1623,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, wake_up_interruptible(&dev->ioq); } - return rc; + break; #ifdef PCMCIA_DEBUG case CM_IOSDBGLVL: /* set debug log level */ { @@ -1612,18 +1631,20 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, old_pc_debug = pc_debug; if (copy_from_user(&pc_debug, argp, sizeof(int))) - return -EFAULT; - - if (old_pc_debug != pc_debug) + rc = -EFAULT; + else if (old_pc_debug != pc_debug) DEBUGP(0, dev, "Changed debug log level " "to %i\n", pc_debug); } - return rc; + break; #endif default: DEBUGP(4, dev, "... in default (unknown IOCTL code)\n"); - return -EINVAL; + rc = -ENOTTY; } +out: + unlock_kernel(); + return rc; } static int cmm_open(struct inode *inode, struct file *filp) @@ -1631,16 +1652,22 @@ 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)) - return -ENODEV; + if (link == NULL || !pcmcia_dev_present(link)) { + ret = -ENODEV; + goto out; + } - if (link->open) - return -EBUSY; + if (link->open) { + ret = -EBUSY; + goto out; + } dev = link->priv; filp->private_data = dev; @@ -1660,8 +1687,10 @@ static int cmm_open(struct inode *inode, struct file *filp) * vaild = block until valid (or card * inserted) */ - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; + if (filp->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + goto out; + } dev->mdelay = T_50MSEC; @@ -1671,7 +1700,10 @@ static int cmm_open(struct inode *inode, struct file *filp) link->open = 1; /* only one open per device */ DEBUGP(2, dev, "<- cmm_open\n"); - return nonseekable_open(inode, filp); + ret = nonseekable_open(inode, filp); +out: + unlock_kernel(); + return ret; } static int cmm_close(struct inode *inode, struct file *filp) @@ -1897,7 +1929,7 @@ static const struct file_operations cm4000_fops = { .owner = THIS_MODULE, .read = cmm_read, .write = cmm_write, - .ioctl = cmm_ioctl, + .unlocked_ioctl = cmm_ioctl, .open = cmm_open, .release= cmm_close, }; diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 035084c0732..6181f8a9b0b 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -26,6 +26,7 @@ #include <linux/fs.h> #include <linux/delay.h> #include <linux/poll.h> +#include <linux/smp_lock.h> #include <linux/wait.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -448,23 +449,30 @@ 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)) - return -ENODEV; + if (link == NULL || !pcmcia_dev_present(link)) { + ret = -ENODEV; + goto out; + } - if (link->open) - return -EBUSY; + if (link->open) { + ret = -EBUSY; + goto out; + } dev = link->priv; filp->private_data = dev; if (filp->f_flags & O_NONBLOCK) { DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); - return -EAGAIN; + ret = -EAGAIN; + goto out; } link->open = 1; @@ -473,7 +481,10 @@ 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"); - return nonseekable_open(inode, filp); + ret = nonseekable_open(inode, filp); +out: + unlock_kernel(); + return ret; } static int cm4040_close(struct inode *inode, struct file *filp) diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 00c7f8407e3..cc7dcea2d28 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -28,7 +28,6 @@ #include <linux/sched.h> #include <linux/slab.h> -#include <pcmcia/version.h> #include <pcmcia/cisreg.h> #include <pcmcia/device_id.h> #include <pcmcia/ss.h> diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 3381424d70a..8dbf4d9b644 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/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 PCMCIA_DEBUG -INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); +#ifdef CONFIG_PCMCIA_DEBUG +INT_MODULE_PARM(pc_debug, 0); #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 @@ failed: ======================================================================*/ -void ide_release(struct pcmcia_device *link) +static void ide_release(struct pcmcia_device *link) { ide_info_t *info = link->priv; ide_hwif_t *hwif = info->hwif; diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 10748240cb2..6a866d7c8ae 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -50,17 +50,19 @@ 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 - * @bio: the buffer head that's been built up so far + * @bvm: properties of new bio * @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 bio *bio, struct bio_vec *biovec) +static int linear_mergeable_bvec(struct request_queue *q, + struct bvec_merge_data *bvm, + struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; dev_info_t *dev0; - unsigned long maxsectors, bio_sectors = bio->bi_size >> 9; - sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); + unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9; + sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); dev0 = which_dev(mddev, sector); maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 914c04ddec7..bcbb82594a1 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -241,18 +241,20 @@ static int create_strip_zones (mddev_t *mddev) /** * raid0_mergeable_bvec -- tell bio layer if a two requests can be merged * @q: request queue - * @bio: the buffer head that's been built up so far + * @bvm: properties of new bio * @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 bio *bio, struct bio_vec *biovec) +static int raid0_mergeable_bvec(struct request_queue *q, + struct bvec_merge_data *bvm, + struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; - sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); + sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_size >> 9; - unsigned int bio_sectors = bio->bi_size >> 9; + unsigned int bio_sectors = bvm->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/drivers/md/raid10.c b/drivers/md/raid10.c index a71277b640a..22bb2b1b886 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -439,26 +439,27 @@ 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 - * @bio: the buffer head that's been built up so far + * @bvm: properties of new bio * @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 bio *bio, - struct bio_vec *bio_vec) +static int raid10_mergeable_bvec(struct request_queue *q, + struct bvec_merge_data *bvm, + struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; - sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); + sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_size >> 9; - unsigned int bio_sectors = bio->bi_size >> 9; + unsigned int bio_sectors = bvm->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 <= bio_vec->bv_len && bio_sectors == 0) - return bio_vec->bv_len; + if (max <= biovec->bv_len && bio_sectors == 0) + return biovec->bv_len; else return max; } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3b27df52456..9ce7154845c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3314,15 +3314,17 @@ 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 bio *bio, struct bio_vec *biovec) +static int raid5_mergeable_bvec(struct request_queue *q, + struct bvec_merge_data *bvm, + struct bio_vec *biovec) { mddev_t *mddev = q->queuedata; - sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); + sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_size >> 9; - unsigned int bio_sectors = bio->bi_size >> 9; + unsigned int bio_sectors = bvm->bi_size >> 9; - if (bio_data_dir(bio) == WRITE) + if ((bvm->bi_rw & 1) == WRITE) return biovec->bv_len; /* always allow writes to be mergeable */ max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 4a79b187b56..5c29872184e 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -130,10 +130,6 @@ 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/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 1912d968718..0cc31675aeb 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -498,17 +498,14 @@ 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, &cisinfo); + ret = pcmcia_validate_cis(link, NULL); if(ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); - } else { - DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); } card_settings(dev, link, &new_name); @@ -563,9 +560,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - 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); + DEBUG(2, "window handle = 0x%8.8lx", (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/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index d26f69b0184..ef671d1a3bf 100644 --- a/drivers/net/xen-netfront.c +++ b/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_KERNEL); + txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); 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_KERNEL); + rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); if (!rxs) { err = -ENOMEM; xenbus_dev_fatal(dev, err, "allocating rx ring page"); diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 1b0eb5aaf65..e45402adac3 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -263,6 +263,13 @@ 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/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 6f6478ba717..85c6cc931f9 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -36,6 +36,7 @@ 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/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index 1e467bb5407..a53ef590251 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h @@ -26,7 +26,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include "cs_internal.h" @@ -34,9 +33,9 @@ #define AU1000_PCMCIA_IO_SPEED (255) #define AU1000_PCMCIA_MEM_SPEED (300) -#define AU1X_SOCK0_IO 0xF00000000 -#define AU1X_SOCK0_PHYS_ATTR 0xF40000000 -#define AU1X_SOCK0_PHYS_MEM 0xF80000000 +#define AU1X_SOCK0_IO 0xF00000000ULL +#define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL +#define AU1X_SOCK0_PHYS_MEM 0xF80000000ULL /* 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 @@ -45,16 +44,20 @@ /* 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 0xF08000000 -#define AU1X_SOCK1_PHYS_ATTR 0xF48000000 -#define AU1X_SOCK1_PHYS_MEM 0xF88000000 +#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 #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 0xF04000000 -#define AU1X_SOCK1_PHYS_ATTR 0xF44000000 -#define AU1X_SOCK1_PHYS_MEM 0xF84000000 +#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 #define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000 #define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8400000 #endif diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index 157e41423a0..aa1cd4d3aa2 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c @@ -35,7 +35,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include <pcmcia/bus_ops.h> #include "cs_internal.h" diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c index c78ed534751..8a9b18cee84 100644 --- a/drivers/pcmcia/au1000_xxs1500.c +++ b/drivers/pcmcia/au1000_xxs1500.c @@ -39,7 +39,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include <pcmcia/bus_ops.h> #include "cs_internal.h" diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c new file mode 100644 index 00000000000..bb7338863fb --- /dev/null +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -0,0 +1,339 @@ +/* + * 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 <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/platform_device.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <pcmcia/ss.h> +#include <pcmcia/cisreg.h> +#include <asm/gpio.h> + +#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 <hennerich@blackfin.uclinux.org>") +MODULE_DESCRIPTION("BFIN CF/PCMCIA Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index fb2f38dc92c..911ca0e8dfc 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -30,11 +30,9 @@ #include <asm/irq.h> #include <asm/io.h> -#define IN_CARD_SERVICES #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include "cs_internal.h" diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 36379535f9d..9fcff0c3361 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -30,7 +30,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cisreg.h> #include <pcmcia/cistpl.h> #include "cs_internal.h" @@ -1439,10 +1438,11 @@ EXPORT_SYMBOL(pccard_read_tuple); ======================================================================*/ -int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info) +int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *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, cisinfo_ return CS_OUT_OF_RESOURCE; } - info->Chains = reserved = 0; + count = 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, cisinfo_ if (!dev_ok && !ident_ok) goto done; - for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) { + for (count = 1; count < MAX_TUPLES; count++) { ret = pccard_get_next_tuple(s, function, tuple); if (ret != CS_SUCCESS) break; if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || @@ -1490,11 +1490,13 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_ ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) reserved++; } - if ((info->Chains == MAX_TUPLES) || (reserved > 5) || - ((!dev_ok || !ident_ok) && (info->Chains > 10))) - info->Chains = 0; + if ((count) || (reserved > 5) || + ((!dev_ok || !ident_ok) && (count > 10))) + count = 0; done: + if (info) + *info = count; kfree(tuple); kfree(p); return CS_SUCCESS; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 29276bd2829..d1207393fc3 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -32,11 +32,9 @@ #include <asm/system.h> #include <asm/irq.h> -#define IN_CARD_SERVICES #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> @@ -238,7 +236,6 @@ 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); @@ -278,10 +275,9 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket) cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops); - if (socket->thread) { - wake_up(&socket->thread_wait); + if (socket->thread) kthread_stop(socket->thread); - } + release_cis_mem(socket); /* remove from our own list */ @@ -635,7 +631,6 @@ 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; @@ -656,7 +651,6 @@ 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(); @@ -694,8 +688,6 @@ 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); @@ -716,7 +708,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(&s->thread_wait); + wake_up_process(s->thread); } } /* pcmcia_parse_events */ EXPORT_SYMBOL(pcmcia_parse_events); diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index e7d5d141f24..63dc1a28bda 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -26,18 +26,6 @@ #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; @@ -130,7 +118,6 @@ 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/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index e40775443d0..4174d9656e3 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -25,7 +25,6 @@ #include <linux/kref.h> #include <linux/dma-mapping.h> -#define IN_CARD_SERVICES #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/cistpl.h> @@ -741,9 +740,8 @@ 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; + unsigned int no_funcs, i, no_chains; int ret = 0; if (!(s->resource_setup_done)) { @@ -757,8 +755,8 @@ static int pcmcia_card_add(struct pcmcia_socket *s) return -EAGAIN; /* try again, but later... */ } - ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); - if (ret || !cisinfo.Chains) { + ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains); + if (ret || !no_chains) { ds_dbg(0, "invalid CIS or invalid resources\n"); return -ENODEV; } @@ -852,7 +850,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) { struct pcmcia_socket *s = dev->socket; const struct firmware *fw; - char path[20]; + char path[FIRMWARE_NAME_MAX]; int ret = -ENOMEM; int no_funcs; int old_funcs; @@ -864,7 +862,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) > 14) { + if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) { printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n", filename); return -EINVAL; diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index f2e810f53c8..fb2bc1fb015 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -1,6 +1,4 @@ /* - * $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. * @@ -48,7 +46,6 @@ #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> #include <pcmcia/ss.h> -#include <pcmcia/bulkmem.h> #include "cs_internal.h" #define MODNAME "hd64465_ss" diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index e13618656ff..46561face12 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -5,8 +5,6 @@ * * Author: Arjan Van De Ven <arjanv@redhat.com> * 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 <linux/kernel.h> diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h index b0d453303c5..8836d393ad0 100644 --- a/drivers/pcmcia/i82092aa.h +++ b/drivers/pcmcia/i82092aa.h @@ -3,8 +3,6 @@ #include <linux/interrupt.h> -/* $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/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 32a2ab11979..68f6b2702bc 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1263,7 +1263,7 @@ static int __init init_i82365(void) ret = driver_register(&i82365_driver); if (ret) - return ret; + goto err_out; i82365_device = platform_device_alloc("i82365", 0); if (i82365_device) { @@ -1273,10 +1273,8 @@ static int __init init_i82365(void) } else ret = -ENOMEM; - if (ret) { - driver_unregister(&i82365_driver); - return ret; - } + if (ret) + goto err_driver_unregister; printk(KERN_INFO "Intel ISA PCIC probe: "); sockets = 0; @@ -1285,16 +1283,17 @@ static int __init init_i82365(void) if (sockets == 0) { printk("not found.\n"); - platform_device_unregister(i82365_device); - release_region(i365_base, 2); - driver_unregister(&i82365_driver); - return -ENODEV; + ret = -ENODEV; + goto err_dev_unregister; } /* Set up interrupt handler(s) */ if (grab_irq != 0) - request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); - + ret = request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); + + if (ret) + goto err_socket_release; + /* register sockets with the pcmcia core */ for (i = 0; i < sockets; i++) { socket[i].socket.dev.parent = &i82365_device->dev; @@ -1324,7 +1323,23 @@ 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/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index ac70d2cb7dd..13a5fbd50a0 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/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 <damm@bitsmart.com> + * (C) 1999-2000 Magnus Damm <damm@opensource.se> * (C) 2001-2002 Montavista Software, Inc. * <mlocke@mvista.com> * @@ -60,7 +60,6 @@ #include <asm/of_device.h> #include <asm/of_platform.h> -#include <pcmcia/version.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 5f186abca10..afd00e7bbbe 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -29,10 +29,10 @@ #include <linux/pci.h> #include <linux/workqueue.h> -#define IN_CARD_SERVICES #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/cistpl.h> +#include <pcmcia/cisreg.h> #include <pcmcia/ds.h> #include <pcmcia/ss.h> @@ -138,6 +138,154 @@ 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 @@ -546,8 +694,6 @@ 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) { @@ -649,7 +795,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); + ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains); break; case DS_SUSPEND_CARD: ret = pcmcia_suspend_card(s); diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 1d128fbd1a9..4884a18cf9e 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -21,11 +21,9 @@ #include <linux/pci.h> #include <linux/device.h> -#define IN_CARD_SERVICES #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> @@ -311,74 +309,6 @@ 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. @@ -812,6 +742,15 @@ 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; @@ -966,7 +905,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/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 9414163c78e..ccfdf1969a7 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -33,7 +33,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include "cs_internal.h" diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index ce2226273aa..c0e2afc79e3 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -21,86 +21,6 @@ #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) @@ -164,7 +84,8 @@ struct pccard_resource_ops pccard_static_ops = { .adjust_io_region = NULL, .find_io = NULL, .find_mem = NULL, - .adjust_resource = NULL, + .add_io = NULL, + .add_mem = NULL, .init = static_init, .exit = NULL, }; @@ -264,7 +185,8 @@ struct pccard_resource_ops pccard_iodyn_ops = { .adjust_io_region = iodyn_adjust_io_region, .find_io = iodyn_find_io_region, .find_mem = NULL, - .adjust_resource = NULL, + .add_io = NULL, + .add_mem = NULL, .init = static_init, .exit = NULL, }; diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 0fcf763b917..d0c1d63d189 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -31,7 +31,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include "cs_internal.h" @@ -261,21 +260,22 @@ 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, cisinfo_t *info) +static int readable(struct pcmcia_socket *s, struct resource *res, + unsigned int *count) { 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, info); + ret = pccard_validate_cis(s, BIND_FN_ALL, count); /* 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) || (info->Chains == 0)) + if ((ret != 0) || (count == 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; - cisinfo_t info1, info2; + unsigned int 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.Chains == info2.Chains); + return (ret == 2) && (info1 == info2); } static int @@ -766,21 +766,6 @@ 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) { @@ -889,7 +874,8 @@ 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, - .adjust_resource = nonstatic_adjust_resource_info, + .add_io = adjust_io, + .add_mem = adjust_memory, .init = nonstatic_init, .exit = nonstatic_release_resource_db, }; @@ -1008,41 +994,34 @@ static ssize_t store_mem_db(struct device *dev, } static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db); -static struct device_attribute *pccard_rsrc_attributes[] = { - &dev_attr_available_resources_io, - &dev_attr_available_resources_mem, +static struct attribute *pccard_rsrc_attributes[] = { + &dev_attr_available_resources_io.attr, + &dev_attr_available_resources_mem.attr, 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; - - for (attr = pccard_rsrc_attributes; *attr; attr++) { - ret = device_create_file(dev, *attr); - if (ret) - break; - } - - return ret; + return sysfs_create_group(&dev->kobj, &rsrc_attributes); } 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; - - for (attr = pccard_rsrc_attributes; *attr; attr++) - device_remove_file(dev, *attr); + sysfs_remove_group(&dev->kobj, &rsrc_attributes); } static struct class_interface pccard_rsrc_interface __refdata = { diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 1edc1da9d35..91ef6a0da3a 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -14,7 +14,6 @@ #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/ss.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include "cs_internal.h" diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 562384d6f32..006a29e91d8 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -27,11 +27,9 @@ #include <asm/system.h> #include <asm/irq.h> -#define IN_CARD_SERVICES #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> #include <pcmcia/cs.h> -#include <pcmcia/bulkmem.h> #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> @@ -293,7 +291,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, count = 0; else { struct pcmcia_socket *s; - cisinfo_t cisinfo; + unsigned int chains; if (off + count > size) count = size - off; @@ -302,9 +300,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, &cisinfo)) + if (pccard_validate_cis(s, BIND_FN_ALL, &chains)) return -EIO; - if (!cisinfo.Chains) + if (!chains) return -ENODATA; count = pccard_extract_cis(s, buf, off, count); diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index d29657bf1b4..129db7bd06c 100644 --- a/drivers/pcmcia/ti113x.h +++ b/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_F0) +#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F1) #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(&socket->socket, &state); + yenta_get_status(&slot2->socket, &state); if (state & SS_DETECT) { ret = 0; goto out; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ea0edd1b2e7..fe694f0ee19 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -182,8 +182,9 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, 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, 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, struct file *file, + 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, @@ -204,7 +205,6 @@ 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, buf, count, blocking, 0, NULL); + return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL); if (count < (SZ_SG_HEADER + 6)) return -EIO; /* The minimum scsi command length is 6 bytes. */ @@ -621,8 +621,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) } 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) +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) { int k; Sg_request *srp; @@ -678,8 +679,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, sg_remove_request(sfp, srp); return -EFAULT; } - if (read_only && - (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) { + if (read_only && !blk_verify_command(file, cmnd)) { 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, p, SZ_SG_IO_HDR, + sg_new_write(sfp, filp, 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 (!sg_allow_access(opcode, sdp->device->type)) + if (!blk_verify_command(filp, &opcode)) return -EPERM; } return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); @@ -2502,30 +2502,6 @@ 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/drivers/scsi/sr.c b/drivers/scsi/sr.c index c82df8bd4d8..27f5bfd1def 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -673,24 +673,20 @@ fail: static void get_sectorsize(struct scsi_cd *cd) { unsigned char cmd[10]; - unsigned char *buffer; + unsigned char buffer[8]; 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, 8); + memset(buffer, 0, sizeof(buffer)); /* Do the command and wait.. */ the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, - buffer, 8, NULL, SR_TIMEOUT, - MAX_RETRIES); + buffer, sizeof(buffer), NULL, + SR_TIMEOUT, MAX_RETRIES); retries--; @@ -745,14 +741,8 @@ 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; + return; } static void get_capabilities(struct scsi_cd *cd) diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 0f86b0ff787..9678b3e98c6 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/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_KERNEL, pathfmt, ap); + path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap); va_end(ap); if (!path) { diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 227d53b12a5..7f2f91c0e11 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/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_KERNEL, "%s", dir); + buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s", dir); else - buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name); + buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%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_KERNEL); + ret = kmalloc(*num * sizeof(char *) + len, GFP_NOIO | __GFP_HIGH); if (!ret) { kfree(strings); return ERR_PTR(-ENOMEM); @@ -751,7 +751,7 @@ static int process_msg(void) } - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc(sizeof(*msg), GFP_NOIO | __GFP_HIGH); 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_KERNEL); + body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH); if (body == NULL) { kfree(msg); err = -ENOMEM; |