aboutsummaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/DAC960.c27
-rw-r--r--drivers/block/Kconfig19
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/acsi_slm.c2
-rw-r--r--drivers/block/aoe/aoe.h14
-rw-r--r--drivers/block/aoe/aoeblk.c26
-rw-r--r--drivers/block/aoe/aoechr.c37
-rw-r--r--drivers/block/aoe/aoecmd.c187
-rw-r--r--drivers/block/aoe/aoedev.c69
-rw-r--r--drivers/block/aoe/aoemain.c4
-rw-r--r--drivers/block/aoe/aoenet.c22
-rw-r--r--drivers/block/ataflop.c4
-rw-r--r--drivers/block/cciss.c24
-rw-r--r--drivers/block/cciss_scsi.c5
-rw-r--r--drivers/block/cpqarray.c3
-rw-r--r--drivers/block/floppy.c51
-rw-r--r--drivers/block/loop.c26
-rw-r--r--drivers/block/nbd.c21
-rw-r--r--drivers/block/paride/bpck6.c3
-rw-r--r--drivers/block/paride/comm.c16
-rw-r--r--drivers/block/paride/on26.c2
-rw-r--r--drivers/block/paride/pd.c3
-rw-r--r--drivers/block/paride/pg.c8
-rw-r--r--drivers/block/paride/pt.c8
-rw-r--r--drivers/block/pktcdvd.c57
-rw-r--r--drivers/block/rd.c7
-rw-r--r--drivers/block/ub.c245
-rw-r--r--drivers/block/umem.c7
28 files changed, 393 insertions, 505 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 37b8cda3e8b..45bcda54488 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -41,6 +41,7 @@
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <linux/random.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -228,8 +229,7 @@ static void *slice_dma_loaf(struct dma_loaf *loaf, size_t len,
void *cpu_end = loaf->cpu_free + len;
void *cpu_addr = loaf->cpu_free;
- if (cpu_end > loaf->cpu_base + loaf->length)
- BUG();
+ BUG_ON(cpu_end > loaf->cpu_base + loaf->length);
*dma_handle = loaf->dma_free;
loaf->cpu_free = cpu_end;
loaf->dma_free += len;
@@ -312,11 +312,10 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
CommandsRemaining = CommandAllocationGroupSize;
CommandGroupByteCount =
CommandsRemaining * CommandAllocationLength;
- AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
+ AllocationPointer = kzalloc(CommandGroupByteCount, GFP_ATOMIC);
if (AllocationPointer == NULL)
return DAC960_Failure(Controller,
"AUXILIARY STRUCTURE CREATION");
- memset(AllocationPointer, 0, CommandGroupByteCount);
}
Command = (DAC960_Command_T *) AllocationPointer;
AllocationPointer += CommandAllocationLength;
@@ -2710,14 +2709,12 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
void __iomem *BaseAddress;
int i;
- Controller = (DAC960_Controller_T *)
- kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
+ Controller = kzalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
if (Controller == NULL) {
DAC960_Error("Unable to allocate Controller structure for "
"Controller at\n", NULL);
return NULL;
}
- memset(Controller, 0, sizeof(DAC960_Controller_T));
Controller->ControllerNumber = DAC960_ControllerCount;
DAC960_Controllers[DAC960_ControllerCount++] = Controller;
Controller->Bus = PCI_Device->bus->number;
@@ -3658,8 +3655,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
(NewEnquiry->EventLogSequenceNumber !=
OldEnquiry->EventLogSequenceNumber) ||
Controller->MonitoringTimerCount == 0 ||
- (jiffies - Controller->SecondaryMonitoringTime
- >= DAC960_SecondaryMonitoringInterval))
+ time_after_eq(jiffies, Controller->SecondaryMonitoringTime
+ + DAC960_SecondaryMonitoringInterval))
{
Controller->V1.NeedLogicalDriveInformation = true;
Controller->V1.NewEventLogSequenceNumber =
@@ -5644,8 +5641,8 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
unsigned int StatusChangeCounter =
Controller->V2.HealthStatusBuffer->StatusChangeCounter;
boolean ForceMonitoringCommand = false;
- if (jiffies - Controller->SecondaryMonitoringTime
- > DAC960_SecondaryMonitoringInterval)
+ if (time_after(jiffies, Controller->SecondaryMonitoringTime
+ + DAC960_SecondaryMonitoringInterval))
{
int LogicalDriveNumber;
for (LogicalDriveNumber = 0;
@@ -5673,8 +5670,8 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
ControllerInfo->ConsistencyChecksActive +
ControllerInfo->RebuildsActive +
ControllerInfo->OnlineExpansionsActive == 0 ||
- jiffies - Controller->PrimaryMonitoringTime
- < DAC960_MonitoringTimerInterval) &&
+ time_before(jiffies, Controller->PrimaryMonitoringTime
+ + DAC960_MonitoringTimerInterval)) &&
!ForceMonitoringCommand)
{
Controller->MonitoringTimer.expires =
@@ -5811,8 +5808,8 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
Controller->ProgressBufferLength = Length;
if (Controller->EphemeralProgressMessage)
{
- if (jiffies - Controller->LastProgressReportTime
- >= DAC960_ProgressReportingInterval)
+ if (time_after_eq(jiffies, Controller->LastProgressReportTime
+ + DAC960_ProgressReportingInterval))
{
printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
Controller->ControllerNumber, Buffer);
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 8b133167740..ae0949b3394 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -383,8 +383,9 @@ config BLK_DEV_RAM
thus say N here.
config BLK_DEV_RAM_COUNT
- int "Default number of RAM disks" if BLK_DEV_RAM
+ int "Default number of RAM disks"
default "16"
+ depends on BLK_DEV_RAM
help
The default value is 16 RAM disks. Change this if you know what
are doing. If you boot from a filesystem that needs to be extracted
@@ -400,14 +401,16 @@ config BLK_DEV_RAM_SIZE
8192.
config BLK_DEV_INITRD
- bool "Initial RAM disk (initrd) support"
- depends on BLK_DEV_RAM=y
+ bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
help
- The initial RAM disk is a RAM disk that is loaded by the boot loader
- (loadlin or lilo) and that is mounted as root before the normal boot
- procedure. It is typically used to load modules needed to mount the
- "real" root file system, etc. See <file:Documentation/initrd.txt>
- for details.
+ The initial RAM filesystem is a ramfs which is loaded by the
+ boot loader (loadlin or lilo) and that is mounted as root
+ before the normal boot procedure. It is typically used to
+ load modules needed to mount the "real" root file system,
+ etc. See <file:Documentation/initrd.txt> for details.
+
+ If RAM disk support (BLK_DEV_RAM) is also included, this
+ also enables initial RAM disk (initrd) support.
config CDROM_PKTCDVD
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 3ec1f8df87b..410f259a803 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -7,7 +7,6 @@
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
-obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
obj-$(CONFIG_BLK_DEV_SWIM_IOP) += swim_iop.o
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index a5c1c8e871e..4cb9c133628 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -369,8 +369,6 @@ static ssize_t slm_read( struct file *file, char *buf, size_t count,
int length;
int end;
- if (count < 0)
- return( -EINVAL );
if (!(page = __get_free_page( GFP_KERNEL )))
return( -ENOMEM );
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 881c48d941b..6eebcb7be97 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "14"
+#define VERSION "22"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
@@ -75,8 +75,9 @@ enum {
DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */
DEVFL_EXT = (1<<2), /* device accepts lba48 commands */
DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */
- DEVFL_WC_UPDATE = (1<<4), /* this device needs to update write cache status */
- DEVFL_WORKON = (1<<4),
+ DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */
+ DEVFL_PAUSE = (1<<5),
+ DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */
BUFFL_FAIL = 1,
};
@@ -152,16 +153,17 @@ void aoechr_exit(void);
void aoechr_error(char *);
void aoecmd_work(struct aoedev *d);
-void aoecmd_cfg(ushort, unsigned char);
+void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
void aoecmd_ata_rsp(struct sk_buff *);
void aoecmd_cfg_rsp(struct sk_buff *);
+void aoecmd_sleepwork(void *vp);
int aoedev_init(void);
void aoedev_exit(void);
struct aoedev *aoedev_by_aoeaddr(int maj, int min);
+struct aoedev *aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt);
void aoedev_downdev(struct aoedev *d);
-struct aoedev *aoedev_set(ulong, unsigned char *, struct net_device *, ulong);
-int aoedev_busy(void);
+int aoedev_isbusy(struct aoedev *d);
int aoenet_init(void);
void aoenet_exit(void);
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index c05ee8bffd9..393b86a3dbf 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -22,7 +22,9 @@ static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
return snprintf(page, PAGE_SIZE,
"%s%s\n",
(d->flags & DEVFL_UP) ? "up" : "down",
- (d->flags & DEVFL_CLOSEWAIT) ? ",closewait" : "");
+ (d->flags & DEVFL_PAUSE) ? ",paused" :
+ (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : "");
+ /* I'd rather see nopen exported so we can ditch closewait */
}
static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page)
{
@@ -107,8 +109,7 @@ aoeblk_release(struct inode *inode, struct file *filp)
spin_lock_irqsave(&d->lock, flags);
- if (--d->nopen == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
- d->flags &= ~DEVFL_CLOSEWAIT;
+ if (--d->nopen == 0) {
spin_unlock_irqrestore(&d->lock, flags);
aoecmd_cfg(d->aoemajor, d->aoeminor);
return 0;
@@ -158,14 +159,14 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
}
list_add_tail(&buf->bufs, &d->bufq);
- aoecmd_work(d);
+ aoecmd_work(d);
sl = d->sendq_hd;
d->sendq_hd = d->sendq_tl = NULL;
spin_unlock_irqrestore(&d->lock, flags);
-
aoenet_xmit(sl);
+
return 0;
}
@@ -205,20 +206,18 @@ aoeblk_gdalloc(void *vp)
printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
spin_lock_irqsave(&d->lock, flags);
- d->flags &= ~DEVFL_WORKON;
+ d->flags &= ~DEVFL_GDALLOC;
spin_unlock_irqrestore(&d->lock, flags);
return;
}
- d->bufpool = mempool_create(MIN_BUFS,
- mempool_alloc_slab, mempool_free_slab,
- buf_pool_cache);
+ d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache);
if (d->bufpool == NULL) {
printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
"for %ld.%ld\n", d->aoemajor, d->aoeminor);
put_disk(gd);
spin_lock_irqsave(&d->lock, flags);
- d->flags &= ~DEVFL_WORKON;
+ d->flags &= ~DEVFL_GDALLOC;
spin_unlock_irqrestore(&d->lock, flags);
return;
}
@@ -235,18 +234,13 @@ aoeblk_gdalloc(void *vp)
gd->queue = &d->blkq;
d->gd = gd;
- d->flags &= ~DEVFL_WORKON;
+ d->flags &= ~DEVFL_GDALLOC;
d->flags |= DEVFL_UP;
spin_unlock_irqrestore(&d->lock, flags);
add_disk(gd);
aoedisk_add_sysfs(d);
-
- printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
- "sectors\n", (unsigned long long)mac_addr(d->addr),
- d->aoemajor, d->aoeminor,
- d->fw_ver, (long long)d->ssize);
}
void
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 41ae0ede619..5327f553b4f 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -13,6 +13,7 @@ enum {
MINOR_ERR = 2,
MINOR_DISCOVER,
MINOR_INTERFACES,
+ MINOR_REVALIDATE,
MSGSZ = 2048,
NARGS = 10,
NMSG = 100, /* message backlog to retain */
@@ -41,6 +42,7 @@ static struct aoe_chardev chardevs[] = {
{ MINOR_ERR, "err" },
{ MINOR_DISCOVER, "discover" },
{ MINOR_INTERFACES, "interfaces" },
+ { MINOR_REVALIDATE, "revalidate" },
};
static int
@@ -62,6 +64,39 @@ interfaces(const char __user *str, size_t size)
return 0;
}
+static int
+revalidate(const char __user *str, size_t size)
+{
+ int major, minor, n;
+ ulong flags;
+ struct aoedev *d;
+ char buf[16];
+
+ if (size >= sizeof buf)
+ return -EINVAL;
+ buf[sizeof buf - 1] = '\0';
+ if (copy_from_user(buf, str, size))
+ return -EFAULT;
+
+ /* should be e%d.%d format */
+ n = sscanf(buf, "e%d.%d", &major, &minor);
+ if (n != 2) {
+ printk(KERN_ERR "aoe: %s: invalid device specification\n",
+ __FUNCTION__);
+ return -EINVAL;
+ }
+ d = aoedev_by_aoeaddr(major, minor);
+ if (!d)
+ return -EINVAL;
+
+ spin_lock_irqsave(&d->lock, flags);
+ d->flags |= DEVFL_PAUSE;
+ spin_unlock_irqrestore(&d->lock, flags);
+ aoecmd_cfg(major, minor);
+
+ return 0;
+}
+
void
aoechr_error(char *msg)
{
@@ -114,6 +149,8 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp
case MINOR_INTERFACES:
ret = interfaces(buf, cnt);
break;
+ case MINOR_REVALIDATE:
+ ret = revalidate(buf, cnt);
}
if (ret == 0)
ret = cnt;
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 326ca3876b6..39da28d344f 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -8,6 +8,7 @@
#include <linux/blkdev.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/genhd.h>
#include <asm/unaligned.h>
#include "aoe.h"
@@ -28,6 +29,7 @@ new_skb(struct net_device *if_dev, ulong len)
skb->protocol = __constant_htons(ETH_P_AOE);
skb->priority = 0;
skb_put(skb, len);
+ memset(skb->head, 0, len);
skb->next = skb->prev = NULL;
/* tell the network layer not to perform IP checksums
@@ -188,12 +190,67 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
}
}
+/* some callers cannot sleep, and they can call this function,
+ * transmitting the packets later, when interrupts are on
+ */
+static struct sk_buff *
+aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
+{
+ struct aoe_hdr *h;
+ struct aoe_cfghdr *ch;
+ struct sk_buff *skb, *sl, *sl_tail;
+ struct net_device *ifp;
+
+ sl = sl_tail = NULL;
+
+ read_lock(&dev_base_lock);
+ for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
+ dev_hold(ifp);
+ if (!is_aoe_netif(ifp))
+ continue;
+
+ skb = new_skb(ifp, sizeof *h + sizeof *ch);
+ if (skb == NULL) {
+ printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
+ continue;
+ }
+ if (sl_tail == NULL)
+ sl_tail = skb;
+ h = (struct aoe_hdr *) skb->mac.raw;
+ memset(h, 0, sizeof *h + sizeof *ch);
+
+ memset(h->dst, 0xff, sizeof h->dst);
+ memcpy(h->src, ifp->dev_addr, sizeof h->src);
+ h->type = __constant_cpu_to_be16(ETH_P_AOE);
+ h->verfl = AOE_HVER;
+ h->major = cpu_to_be16(aoemajor);
+ h->minor = aoeminor;
+ h->cmd = AOECMD_CFG;
+
+ skb->next = sl;
+ sl = skb;
+ }
+ read_unlock(&dev_base_lock);
+
+ if (tail != NULL)
+ *tail = sl_tail;
+ return sl;
+}
+
/* enters with d->lock held */
void
aoecmd_work(struct aoedev *d)
{
struct frame *f;
struct buf *buf;
+
+ if (d->flags & DEVFL_PAUSE) {
+ if (!aoedev_isbusy(d))
+ d->sendq_hd = aoecmd_cfg_pkts(d->aoemajor,
+ d->aoeminor, &d->sendq_tl);
+ return;
+ }
+
loop:
f = getframe(d, FREETAG);
if (f == NULL)
@@ -229,6 +286,8 @@ rexmit(struct aoedev *d, struct frame *f)
h = (struct aoe_hdr *) f->data;
f->tag = n;
h->tag = cpu_to_be32(n);
+ memcpy(h->dst, d->addr, sizeof h->dst);
+ memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
skb = skb_prepare(d, f);
if (skb) {
@@ -272,7 +331,7 @@ rexmit_timer(ulong vp)
spin_lock_irqsave(&d->lock, flags);
if (d->flags & DEVFL_TKILL) {
-tdie: spin_unlock_irqrestore(&d->lock, flags);
+ spin_unlock_irqrestore(&d->lock, flags);
return;
}
f = d->frames;
@@ -283,7 +342,7 @@ tdie: spin_unlock_irqrestore(&d->lock, flags);
n /= HZ;
if (n > MAXWAIT) { /* waited too long. device failure. */
aoedev_downdev(d);
- goto tdie;
+ break;
}
rexmit(d, f);
}
@@ -305,6 +364,37 @@ tdie: spin_unlock_irqrestore(&d->lock, flags);
aoenet_xmit(sl);
}
+/* this function performs work that has been deferred until sleeping is OK
+ */
+void
+aoecmd_sleepwork(void *vp)
+{
+ struct aoedev *d = (struct aoedev *) vp;
+
+ if (d->flags & DEVFL_GDALLOC)
+ aoeblk_gdalloc(d);
+
+ if (d->flags & DEVFL_NEWSIZE) {
+ struct block_device *bd;
+ unsigned long flags;
+ u64 ssize;
+
+ ssize = d->gd->capacity;
+ bd = bdget_disk(d->gd, 0);
+
+ if (bd) {
+ mutex_lock(&bd->bd_inode->i_mutex);
+ i_size_write(bd->bd_inode, (loff_t)ssize<<9);
+ mutex_unlock(&bd->bd_inode->i_mutex);
+ bdput(bd);
+ }
+ spin_lock_irqsave(&d->lock, flags);
+ d->flags |= DEVFL_UP;
+ d->flags &= ~DEVFL_NEWSIZE;
+ spin_unlock_irqrestore(&d->lock, flags);
+ }
+}
+
static void
ataid_complete(struct aoedev *d, unsigned char *id)
{
@@ -339,21 +429,29 @@ ataid_complete(struct aoedev *d, unsigned char *id)
d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
}
+
+ if (d->ssize != ssize)
+ printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
+ "sectors\n", (unsigned long long)mac_addr(d->addr),
+ d->aoemajor, d->aoeminor,
+ d->fw_ver, (long long)ssize);
d->ssize = ssize;
d->geo.start = 0;
if (d->gd != NULL) {
d->gd->capacity = ssize;
- d->flags |= DEVFL_UP;
- return;
- }
- if (d->flags & DEVFL_WORKON) {
- printk(KERN_INFO "aoe: ataid_complete: can't schedule work, it's already on! "
- "(This really shouldn't happen).\n");
- return;
+ d->flags |= DEVFL_NEWSIZE;
+ } else {
+ if (d->flags & DEVFL_GDALLOC) {
+ printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n",
+ __FUNCTION__,
+ "can't schedule work for",
+ d->aoemajor, d->aoeminor,
+ "it's already on! (This really shouldn't happen).\n");
+ return;
+ }
+ d->flags |= DEVFL_GDALLOC;
}
- INIT_WORK(&d->work, aoeblk_gdalloc, d);
schedule_work(&d->work);
- d->flags |= DEVFL_WORKON;
}
static void
@@ -419,6 +517,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
buf = f->buf;
+ if (ahout->cmdstat == WIN_IDENTIFY)
+ d->flags &= ~DEVFL_PAUSE;
if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
"stat=%2.2Xh from e%ld.%ld\n",
@@ -451,7 +551,6 @@ aoecmd_ata_rsp(struct sk_buff *skb)
return;
}
ataid_complete(d, (char *) (ahin+1));
- /* d->flags |= DEVFL_WC_UPDATE; */
break;
default:
printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
@@ -484,51 +583,19 @@ aoecmd_ata_rsp(struct sk_buff *skb)
f->tag = FREETAG;
aoecmd_work(d);
-
sl = d->sendq_hd;
d->sendq_hd = d->sendq_tl = NULL;
spin_unlock_irqrestore(&d->lock, flags);
-
aoenet_xmit(sl);
}
void
aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
{
- struct aoe_hdr *h;
- struct aoe_cfghdr *ch;
- struct sk_buff *skb, *sl;
- struct net_device *ifp;
-
- sl = NULL;
-
- read_lock(&dev_base_lock);
- for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
- dev_hold(ifp);
- if (!is_aoe_netif(ifp))
- continue;
-
- skb = new_skb(ifp, sizeof *h + sizeof *ch);
- if (skb == NULL) {
- printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
- continue;
- }
- h = (struct aoe_hdr *) skb->mac.raw;
- memset(h, 0, sizeof *h + sizeof *ch);
-
- memset(h->dst, 0xff, sizeof h->dst);
- memcpy(h->src, ifp->dev_addr, sizeof h->src);
- h->type = __constant_cpu_to_be16(ETH_P_AOE);
- h->verfl = AOE_HVER;
- h->major = cpu_to_be16(aoemajor);
- h->minor = aoeminor;
- h->cmd = AOECMD_CFG;
+ struct sk_buff *sl;
- skb->next = sl;
- sl = skb;
- }
- read_unlock(&dev_base_lock);
+ sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
aoenet_xmit(sl);
}
@@ -561,9 +628,6 @@ aoecmd_ata_id(struct aoedev *d)
f->waited = 0;
f->writedatalen = 0;
- /* this message initializes the device, so we reset the rttavg */
- d->rttavg = MAXTIMER;
-
/* set up ata header */
ah->scnt = 1;
ah->cmdstat = WIN_IDENTIFY;
@@ -571,12 +635,8 @@ aoecmd_ata_id(struct aoedev *d)
skb = skb_prepare(d, f);
- /* we now want to start the rexmit tracking */
- d->flags &= ~DEVFL_TKILL;
- d->timer.data = (ulong) d;
+ d->rttavg = MAXTIMER;
d->timer.function = rexmit_timer;
- d->timer.expires = jiffies + TIMERTICK;
- add_timer(&d->timer);
return skb;
}
@@ -590,7 +650,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
ulong flags, sysminor, aoemajor;
u16 bufcnt;
struct sk_buff *sl;
- enum { MAXFRAMES = 8 };
+ enum { MAXFRAMES = 16 };
h = (struct aoe_hdr *) skb->mac.raw;
ch = (struct aoe_cfghdr *) (h+1);
@@ -618,23 +678,28 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
if (bufcnt > MAXFRAMES) /* keep it reasonable */
bufcnt = MAXFRAMES;
- d = aoedev_set(sysminor, h->src, skb->dev, bufcnt);
+ d = aoedev_by_sysminor_m(sysminor, bufcnt);
if (d == NULL) {
- printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device set failure\n");
+ printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n");
return;
}
spin_lock_irqsave(&d->lock, flags);
- if (d->flags & (DEVFL_UP | DEVFL_CLOSEWAIT)) {
+ /* permit device to migrate mac and network interface */
+ d->ifp = skb->dev;
+ memcpy(d->addr, h->src, sizeof d->addr);
+
+ /* don't change users' perspective */
+ if (d->nopen && !(d->flags & DEVFL_PAUSE)) {
spin_unlock_irqrestore(&d->lock, flags);
return;
}
-
+ d->flags |= DEVFL_PAUSE; /* force pause */
d->fw_ver = be16_to_cpu(ch->fwver);
- /* we get here only if the device is new */
- sl = aoecmd_ata_id(d);
+ /* check for already outstanding ataid */
+ sl = aoedev_isbusy(d) == 0 ? aoecmd_ata_id(d) : NULL;
spin_unlock_irqrestore(&d->lock, flags);
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index ded33ba31ac..ed4258a62df 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -12,6 +12,24 @@
static struct aoedev *devlist;
static spinlock_t devlist_lock;
+int
+aoedev_isbusy(struct aoedev *d)
+{
+ struct frame *f, *e;
+
+ f = d->frames;
+ e = f + d->nframes;
+ do {
+ if (f->tag != FREETAG) {
+ printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n",
+ d->aoemajor, d->aoeminor);
+ return 1;
+ }
+ } while (++f < e);
+
+ return 0;
+}
+
struct aoedev *
aoedev_by_aoeaddr(int maj, int min)
{
@@ -28,6 +46,18 @@ aoedev_by_aoeaddr(int maj, int min)
return d;
}
+static void
+dummy_timer(ulong vp)
+{
+ struct aoedev *d;
+
+ d = (struct aoedev *)vp;
+ if (d->flags & DEVFL_TKILL)
+ return;
+ d->timer.expires = jiffies + HZ;
+ add_timer(&d->timer);
+}
+
/* called with devlist lock held */
static struct aoedev *
aoedev_newdev(ulong nframes)
@@ -44,6 +74,8 @@ aoedev_newdev(ulong nframes)
return NULL;
}
+ INIT_WORK(&d->work, aoecmd_sleepwork, d);
+
d->nframes = nframes;
d->frames = f;
e = f + nframes;
@@ -52,6 +84,10 @@ aoedev_newdev(ulong nframes)
spin_lock_init(&d->lock);
init_timer(&d->timer);
+ d->timer.data = (ulong) d;
+ d->timer.function = dummy_timer;
+ d->timer.expires = jiffies + HZ;
+ add_timer(&d->timer);
d->bufpool = NULL; /* defer to aoeblk_gdalloc */
INIT_LIST_HEAD(&d->bufq);
d->next = devlist;
@@ -67,9 +103,6 @@ aoedev_downdev(struct aoedev *d)
struct buf *buf;
struct bio *bio;
- d->flags |= DEVFL_TKILL;
- del_timer(&d->timer);
-
f = d->frames;
e = f + d->nframes;
for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
@@ -92,16 +125,15 @@ aoedev_downdev(struct aoedev *d)
bio_endio(bio, bio->bi_size, -EIO);
}
- if (d->nopen)
- d->flags |= DEVFL_CLOSEWAIT;
if (d->gd)
d->gd->capacity = 0;
- d->flags &= ~DEVFL_UP;
+ d->flags &= ~(DEVFL_UP | DEVFL_PAUSE);
}
+/* find it or malloc it */
struct aoedev *
-aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt)
+aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
{
struct aoedev *d;
ulong flags;
@@ -112,25 +144,19 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu
if (d->sysminor == sysminor)
break;
- if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
- spin_unlock_irqrestore(&devlist_lock, flags);
- printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
- return NULL;
- } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */
-
- spin_unlock_irqrestore(&devlist_lock, flags);
- spin_lock_irqsave(&d->lock, flags);
-
- d->ifp = ifp;
- memcpy(d->addr, addr, sizeof d->addr);
- if ((d->flags & DEVFL_UP) == 0) {
- aoedev_downdev(d); /* flushes outstanding frames */
+ if (d == NULL) {
+ d = aoedev_newdev(bufcnt);
+ if (d == NULL) {
+ spin_unlock_irqrestore(&devlist_lock, flags);
+ printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
+ return NULL;
+ }
d->sysminor = sysminor;
d->aoemajor = AOEMAJOR(sysminor);
d->aoeminor = AOEMINOR(sysminor);
}
- spin_unlock_irqrestore(&d->lock, flags);
+ spin_unlock_irqrestore(&devlist_lock, flags);
return d;
}
@@ -161,6 +187,7 @@ aoedev_exit(void)
spin_lock_irqsave(&d->lock, flags);
aoedev_downdev(d);
+ d->flags |= DEVFL_TKILL;
spin_unlock_irqrestore(&d->lock, flags);
del_timer_sync(&d->timer);
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
index 387588a3f4b..de08491ebe6 100644
--- a/drivers/block/aoe/aoemain.c
+++ b/drivers/block/aoe/aoemain.c
@@ -11,7 +11,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sam Hopkins <sah@coraid.com>");
-MODULE_DESCRIPTION("AoE block/char driver for 2.6.[0-9]+");
+MODULE_DESCRIPTION("AoE block/char driver for 2.6.2 and newer 2.6 kernels");
MODULE_VERSION(VERSION);
enum { TINIT, TRUN, TKILL };
@@ -89,7 +89,7 @@ aoe_init(void)
}
printk(KERN_INFO
- "aoe: aoe_init: AoE v2.6-%s initialised.\n",
+ "aoe: aoe_init: AoE v%s initialised.\n",
VERSION);
discover_timer(TINIT);
return 0;
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 4be976940f6..fdff774b8ab 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -92,18 +92,6 @@ mac_addr(char addr[6])
return __be64_to_cpu(n);
}
-static struct sk_buff *
-skb_check(struct sk_buff *skb)
-{
- if (skb_is_nonlinear(skb))
- if ((skb = skb_share_check(skb, GFP_ATOMIC)))
- if (skb_linearize(skb, GFP_ATOMIC) < 0) {
- dev_kfree_skb(skb);
- return NULL;
- }
- return skb;
-}
-
void
aoenet_xmit(struct sk_buff *sl)
{
@@ -125,14 +113,14 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
struct aoe_hdr *h;
u32 n;
- skb = skb_check(skb);
- if (!skb)
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (skb == NULL)
return 0;
-
+ if (skb_is_nonlinear(skb))
+ if (skb_linearize(skb, GFP_ATOMIC) < 0)
+ goto exit;
if (!is_aoe_netif(ifp))
goto exit;
-
- //skb->len += ETH_HLEN; /* (1) */
skb_push(skb, ETH_HLEN); /* (1) */
h = (struct aoe_hdr *) skb->mac.raw;
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index f8ce235ccfc..c39650920bd 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -271,7 +271,7 @@ unsigned char *DMABuffer; /* buffer for writes */
static unsigned long PhysDMABuffer; /* physical address */
static int UseTrackbuffer = -1; /* Do track buffering? */
-MODULE_PARM(UseTrackbuffer, "i");
+module_param(UseTrackbuffer, int, 0);
unsigned char *TrackBuffer; /* buffer for reads */
static unsigned long PhysTrackBuffer; /* physical address */
@@ -296,7 +296,7 @@ static int MotorOn = 0, MotorOffTrys;
static int IsFormatting = 0, FormatError;
static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
-MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i");
+module_param_array(UserSteprate, int, NULL, 0);
/* Synchronization of FDC access. */
static volatile int fdc_busy = 0;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 0d65394707d..1b0fd31c57c 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -38,6 +38,7 @@
#include <linux/hdreg.h>
#include <linux/spinlock.h>
#include <linux/compat.h>
+#include <linux/blktrace_api.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -995,13 +996,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
status = -EINVAL;
goto cleanup1;
}
- buff = (unsigned char **) kmalloc(MAXSGENTRIES *
- sizeof(char *), GFP_KERNEL);
+ buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
if (!buff) {
status = -ENOMEM;
goto cleanup1;
}
- memset(buff, 0, MAXSGENTRIES);
buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int),
GFP_KERNEL);
if (!buff_size) {
@@ -2137,7 +2136,7 @@ static void start_io( ctlr_info_t *h)
break;
}
- /* Get the frist entry from the Request Q */
+ /* Get the first entry from the Request Q */
removeQ(&(h->reqQ), c);
h->Qdepth--;
@@ -2331,6 +2330,7 @@ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,
cmd->rq->completion_data = cmd;
cmd->rq->errors = status;
+ blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
blk_complete_request(cmd->rq);
}
@@ -2359,8 +2359,7 @@ queue:
if (!creq)
goto startio;
- if (creq->nr_phys_segments > MAXSGENTRIES)
- BUG();
+ BUG_ON(creq->nr_phys_segments > MAXSGENTRIES);
if (( c = cmd_alloc(h, 1)) == NULL)
goto full;
@@ -2728,9 +2727,9 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev,
return;
}
}
+default_int_mode:
#endif /* CONFIG_PCI_MSI */
/* if we get here we're going to use the default interrupt mode */
-default_int_mode:
c->intr[SIMPLE_MODE_INT] = pdev->irq;
return;
}
@@ -2939,13 +2938,12 @@ static void cciss_getgeometry(int cntl_num)
int block_size;
int total_size;
- ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
+ ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
if (ld_buff == NULL)
{
printk(KERN_ERR "cciss: out of memory\n");
return;
}
- memset(ld_buff, 0, sizeof(ReportLunData_struct));
size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
if (size_buff == NULL)
{
@@ -3059,10 +3057,9 @@ static int alloc_cciss_hba(void)
for(i=0; i< MAX_CTLR; i++) {
if (!hba[i]) {
ctlr_info_t *p;
- p = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+ p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
if (!p)
goto Enomem;
- memset(p, 0, sizeof(ctlr_info_t));
for (n = 0; n < NWD; n++)
p->gendisk[n] = disk[n];
hba[i] = p;
@@ -3251,8 +3248,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
clean4:
#ifdef CONFIG_CISS_SCSI_TAPE
- if(hba[i]->scsi_rejects.complete)
- kfree(hba[i]->scsi_rejects.complete);
+ kfree(hba[i]->scsi_rejects.complete);
#endif
kfree(hba[i]->cmd_pool_bits);
if(hba[i]->cmd_pool)
@@ -3269,8 +3265,8 @@ clean2:
unregister_blkdev(hba[i]->major, hba[i]->devname);
clean1:
release_io_mem(hba[i]);
- free_hba(i);
hba[i]->busy_initializing = 0;
+ free_hba(i);
return(-1);
}
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 9e35de05d5c..597c007fe81 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -1027,12 +1027,11 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
int i;
c = (ctlr_info_t *) hba[cntl_num];
- ld_buff = kmalloc(reportlunsize, GFP_KERNEL);
+ ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
if (ld_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
return;
}
- memset(ld_buff, 0, reportlunsize);
inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
if (inq_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
@@ -1316,7 +1315,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
cp->Request.Timeout = 0;
memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
- if (cmd->cmd_len > sizeof(cp->Request.CDB)) BUG();
+ BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB));
cp->Request.CDBLen = cmd->cmd_len;
memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len);
cp->Request.Type.Type = TYPE_CMD;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 862b9abac0a..b6ea2f0c727 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -906,8 +906,7 @@ queue_next:
if (!creq)
goto startio;
- if (creq->nr_phys_segments > SG_MAX)
- BUG();
+ BUG_ON(creq->nr_phys_segments > SG_MAX);
if ((c = cmd_alloc(h,1)) == NULL)
goto startio;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index d23b54332d7..bedb689b051 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -170,6 +170,7 @@ static int print_unex = 1;
#include <linux/mm.h>
#include <linux/bio.h>
#include <linux/string.h>
+#include <linux/jiffies.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h> /* CMOS defines */
@@ -179,6 +180,7 @@ static int print_unex = 1;
#include <linux/devfs_fs_kernel.h>
#include <linux/platform_device.h>
#include <linux/buffer_head.h> /* for invalidate_buffers() */
+#include <linux/mutex.h>
/*
* PS/2 floppies have much slower step rates than regular floppies.
@@ -249,6 +251,18 @@ static int irqdma_allocated;
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
#include <linux/completion.h>
+/*
+ * Interrupt freeing also means /proc VFS work - dont do it
+ * from interrupt context. We push this work into keventd:
+ */
+static void fd_free_irq_fn(void *data)
+{
+ fd_free_irq();
+}
+
+static DECLARE_WORK(fd_free_irq_work, fd_free_irq_fn, NULL);
+
+
static struct request *current_req;
static struct request_queue *floppy_queue;
static void do_fd_request(request_queue_t * q);
@@ -413,7 +427,7 @@ static struct floppy_write_errors write_errors[N_DRIVE];
static struct timer_list motor_off_timer[N_DRIVE];
static struct gendisk *disks[N_DRIVE];
static struct block_device *opened_bdev[N_DRIVE];
-static DECLARE_MUTEX(open_lock);
+static DEFINE_MUTEX(open_lock);
static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
/*
@@ -734,7 +748,7 @@ static int disk_change(int drive)
{
int fdc = FDC(drive);
#ifdef FLOPPY_SANITY_CHECK
- if (jiffies - UDRS->select_date < UDP->select_delay)
+ if (time_before(jiffies, UDRS->select_date + UDP->select_delay))
DPRINT("WARNING disk change called early\n");
if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
(FDCS->dor & 3) != UNIT(drive) || fdc != FDC(drive)) {
@@ -1062,7 +1076,7 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
return 1;
}
- if ((signed)(jiffies - delay) < 0) {
+ if (time_before(jiffies, delay)) {
del_timer(&fd_timer);
fd_timer.function = function;
fd_timer.expires = delay;
@@ -1522,7 +1536,7 @@ static void setup_rw_floppy(void)
* again just before spinup completion. Beware that
* after scandrives, we must again wait for selection.
*/
- if ((signed)(ready_date - jiffies) > DP->select_delay) {
+ if (time_after(ready_date, jiffies + DP->select_delay)) {
ready_date -= DP->select_delay;
function = (timeout_fn) floppy_start;
} else
@@ -3333,7 +3347,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
if (type) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- down(&open_lock);
+ mutex_lock(&open_lock);
LOCK_FDC(drive, 1);
floppy_type[type] = *g;
floppy_type[type].name = "user format";
@@ -3347,7 +3361,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
continue;
__invalidate_device(bdev);
}
- up(&open_lock);
+ mutex_unlock(&open_lock);
} else {
int oldStretch;
LOCK_FDC(drive, 1);
@@ -3674,7 +3688,7 @@ static int floppy_release(struct inode *inode, struct file *filp)
{
int drive = (long)inode->i_bdev->bd_disk->private_data;
- down(&open_lock);
+ mutex_lock(&open_lock);
if (UDRS->fd_ref < 0)
UDRS->fd_ref = 0;
else if (!UDRS->fd_ref--) {
@@ -3684,7 +3698,7 @@ static int floppy_release(struct inode *inode, struct file *filp)
if (!UDRS->fd_ref)
opened_bdev[drive] = NULL;
floppy_release_irq_and_dma();
- up(&open_lock);
+ mutex_unlock(&open_lock);
return 0;
}
@@ -3702,7 +3716,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
char *tmp;
filp->private_data = (void *)0;
- down(&open_lock);
+ mutex_lock(&open_lock);
old_dev = UDRS->fd_device;
if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
goto out2;
@@ -3785,7 +3799,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
goto out;
}
- up(&open_lock);
+ mutex_unlock(&open_lock);
return 0;
out:
if (UDRS->fd_ref < 0)
@@ -3796,7 +3810,7 @@ out:
opened_bdev[drive] = NULL;
floppy_release_irq_and_dma();
out2:
- up(&open_lock);
+ mutex_unlock(&open_lock);
return res;
}
@@ -3810,7 +3824,7 @@ static int check_floppy_change(struct gendisk *disk)
if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
return 1;
- if (UDP->checkfreq < (int)(jiffies - UDRS->last_checked)) {
+ if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
if (floppy_grab_irq_and_dma()) {
return 1;
}
@@ -4432,6 +4446,13 @@ static int floppy_grab_irq_and_dma(void)
return 0;
}
spin_unlock_irqrestore(&floppy_usage_lock, flags);
+
+ /*
+ * We might have scheduled a free_irq(), wait it to
+ * drain first:
+ */
+ flush_scheduled_work();
+
if (fd_request_irq()) {
DPRINT("Unable to grab IRQ%d for the floppy driver\n",
FLOPPY_IRQ);
@@ -4521,7 +4542,7 @@ static void floppy_release_irq_and_dma(void)
if (irqdma_allocated) {
fd_disable_dma();
fd_free_dma();
- fd_free_irq();
+ schedule_work(&fd_free_irq_work);
irqdma_allocated = 0;
}
set_dor(0, ~0, 8);
@@ -4593,7 +4614,7 @@ static void __init parse_floppy_cfg_string(char *cfg)
}
}
-int init_module(void)
+int __init init_module(void)
{
if (floppy)
parse_floppy_cfg_string(floppy);
@@ -4632,6 +4653,8 @@ void cleanup_module(void)
/* eject disk, if any */
fd_eject(0);
+ flush_scheduled_work(); /* fd_free_irq() might be pending */
+
wait_for_completion(&device_release);
}
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 5f6d1a5cce1..9c3b94e8f03 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -839,7 +839,9 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
set_blocksize(bdev, lo_blocksize);
- kernel_thread(loop_thread, lo, CLONE_KERNEL);
+ error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
+ if (error < 0)
+ goto out_putf;
wait_for_completion(&lo->lo_done);
return 0;
@@ -1144,7 +1146,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
int err;
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
switch (cmd) {
case LOOP_SET_FD:
err = loop_set_fd(lo, file, inode->i_bdev, arg);
@@ -1170,7 +1172,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
return err;
}
@@ -1178,9 +1180,9 @@ static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
lo->lo_refcnt++;
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
return 0;
}
@@ -1189,9 +1191,9 @@ static int lo_release(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
--lo->lo_refcnt;
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
return 0;
}
@@ -1233,12 +1235,12 @@ int loop_unregister_transfer(int number)
xfer_funcs[n] = NULL;
for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
if (lo->lo_encryption == xfer)
loop_release_xfer(lo);
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
}
return 0;
@@ -1285,7 +1287,7 @@ static int __init loop_init(void)
lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
if (!lo->lo_queue)
goto out_mem4;
- init_MUTEX(&lo->lo_ctl_mutex);
+ mutex_init(&lo->lo_ctl_mutex);
init_completion(&lo->lo_done);
init_completion(&lo->lo_bh_done);
lo->lo_number = i;
@@ -1307,7 +1309,7 @@ static int __init loop_init(void)
out_mem4:
while (i--)
- blk_put_queue(loop_dev[i].lo_queue);
+ blk_cleanup_queue(loop_dev[i].lo_queue);
devfs_remove("loop");
i = max_loop;
out_mem3:
@@ -1328,7 +1330,7 @@ static void loop_exit(void)
for (i = 0; i < max_loop; i++) {
del_gendisk(disks[i]);
- blk_put_queue(loop_dev[i].lo_queue);
+ blk_cleanup_queue(loop_dev[i].lo_queue);
put_disk(disks[i]);
}
devfs_remove("loop");
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 6997d8e6bfb..8bca4905d7f 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -459,9 +459,9 @@ static void do_nbd_request(request_queue_t * q)
req->errors = 0;
spin_unlock_irq(q->queue_lock);
- down(&lo->tx_lock);
+ mutex_lock(&lo->tx_lock);
if (unlikely(!lo->sock)) {
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
printk(KERN_ERR "%s: Attempted send on closed socket\n",
lo->disk->disk_name);
req->errors++;
@@ -484,7 +484,7 @@ static void do_nbd_request(request_queue_t * q)
}
lo->active_req = NULL;
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
wake_up_all(&lo->active_wq);
spin_lock_irq(q->queue_lock);
@@ -534,9 +534,9 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
case NBD_CLEAR_SOCK:
error = 0;
- down(&lo->tx_lock);
+ mutex_lock(&lo->tx_lock);
lo->sock = NULL;
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
@@ -590,7 +590,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
* FIXME: This code is duplicated from sys_shutdown, but
* there should be a more generic interface rather than
* calling socket ops directly here */
- down(&lo->tx_lock);
+ mutex_lock(&lo->tx_lock);
if (lo->sock) {
printk(KERN_WARNING "%s: shutting down socket\n",
lo->disk->disk_name);
@@ -598,7 +598,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
SEND_SHUTDOWN|RCV_SHUTDOWN);
lo->sock = NULL;
}
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
@@ -639,10 +639,7 @@ static int __init nbd_init(void)
int err = -ENOMEM;
int i;
- if (sizeof(struct nbd_request) != 28) {
- printk(KERN_CRIT "nbd: sizeof nbd_request needs to be 28 in order to work!\n" );
- return -EIO;
- }
+ BUILD_BUG_ON(sizeof(struct nbd_request) != 28);
if (nbds_max > MAX_NBD) {
printk(KERN_CRIT "nbd: cannot allocate more than %u nbds; %u requested.\n", MAX_NBD,
@@ -683,7 +680,7 @@ static int __init nbd_init(void)
nbd_dev[i].flags = 0;
spin_lock_init(&nbd_dev[i].queue_lock);
INIT_LIST_HEAD(&nbd_dev[i].queue_head);
- init_MUTEX(&nbd_dev[i].tx_lock);
+ mutex_init(&nbd_dev[i].tx_lock);
init_waitqueue_head(&nbd_dev[i].active_wq);
nbd_dev[i].blksize = 1024;
nbd_dev[i].bytesize = 0x7ffffc00ULL << 10; /* 2TB */
diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
index 08d858ad64d..41a237c5957 100644
--- a/drivers/block/paride/bpck6.c
+++ b/drivers/block/paride/bpck6.c
@@ -224,10 +224,9 @@ static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
static int bpck6_init_proto(PIA *pi)
{
- Interface *p = kmalloc(sizeof(Interface), GFP_KERNEL);
+ Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
if (p) {
- memset(p, 0, sizeof(Interface));
pi->private = (unsigned long)p;
return 0;
}
diff --git a/drivers/block/paride/comm.c b/drivers/block/paride/comm.c
index d842956edf7..43d61359d8e 100644
--- a/drivers/block/paride/comm.c
+++ b/drivers/block/paride/comm.c
@@ -60,7 +60,7 @@ static int comm_read_regr( PIA *pi, int cont, int regr )
case 2:
case 3:
- case 4: w3(r+0x20); r1();
+ case 4: w3(r+0x20); (void)r1();
w2(0x24); h = r4(); w2(4);
return h;
@@ -82,7 +82,7 @@ static void comm_write_regr( PIA *pi, int cont, int regr, int val )
case 2:
case 3:
- case 4: w3(r); r1(); w4(val);
+ case 4: w3(r); (void)r1(); w4(val);
break;
}
}
@@ -126,17 +126,17 @@ static void comm_read_block( PIA *pi, char * buf, int count )
w2(4);
break;
- case 2: w3(0x68); r1(); w2(0x24);
+ case 2: w3(0x68); (void)r1(); w2(0x24);
for (i=0;i<count;i++) buf[i] = r4();
w2(4);
break;
- case 3: w3(0x68); r1(); w2(0x24);
+ case 3: w3(0x68); (void)r1(); w2(0x24);
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
w2(4);
break;
- case 4: w3(0x68); r1(); w2(0x24);
+ case 4: w3(0x68); (void)r1(); w2(0x24);
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
w2(4);
break;
@@ -160,15 +160,15 @@ static void comm_write_block( PIA *pi, char * buf, int count )
w2(5); w2(4);
break;
- case 2: w3(0x48); r1();
+ case 2: w3(0x48); (void)r1();
for (k=0;k<count;k++) w4(buf[k^1]);
break;
- case 3: w3(0x48); r1();
+ case 3: w3(0x48); (void)r1();
for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
break;
- case 4: w3(0x48); r1();
+ case 4: w3(0x48); (void)r1();
for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
break;
diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c
index 9f837d9a363..0f833caa210 100644
--- a/drivers/block/paride/on26.c
+++ b/drivers/block/paride/on26.c
@@ -66,7 +66,7 @@ static int on26_read_regr( PIA *pi, int cont, int regr )
case 3:
case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
w3(0); w3(0); w2(0x24); a = r4(); w2(4);
- w2(0x24); r4(); w2(4);
+ w2(0x24); (void)r4(); w2(4);
return a;
}
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 62d2464c12f..2403721f9db 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -151,6 +151,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
#include <linux/cdrom.h> /* for the eject ioctl */
#include <linux/blkdev.h>
#include <linux/blkpg.h>
+#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
@@ -275,7 +276,7 @@ static void pd_print_error(struct pd_unit *disk, char *msg, int status)
int i;
printk("%s: %s: status = 0x%x =", disk->name, msg, status);
- for (i = 0; i < 18; i++)
+ for (i = 0; i < ARRAY_SIZE(pd_errs); i++)
if (status & (1 << i))
printk(" %s", pd_errs[i]);
printk("\n");
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 6f5df0fad70..79b86825403 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -643,7 +643,8 @@ static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t
static int __init pg_init(void)
{
- int unit, err = 0;
+ int unit;
+ int err;
if (disable){
err = -1;
@@ -657,16 +658,17 @@ static int __init pg_init(void)
goto out;
}
- if (register_chrdev(major, name, &pg_fops)) {
+ err = register_chrdev(major, name, &pg_fops);
+ if (err < 0) {
printk("pg_init: unable to get major number %d\n", major);
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present)
pi_release(dev->pi);
}
- err = -1;
goto out;
}
+ major = err; /* In case the user specified `major=0' (dynamic) */
pg_class = class_create(THIS_MODULE, "pg");
if (IS_ERR(pg_class)) {
err = PTR_ERR(pg_class);
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 715ae5dc88f..d2013d36240 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -943,7 +943,8 @@ static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count,
static int __init pt_init(void)
{
- int unit, err = 0;
+ int unit;
+ int err;
if (disable) {
err = -1;
@@ -955,14 +956,15 @@ static int __init pt_init(void)
goto out;
}
- if (register_chrdev(major, name, &pt_fops)) {
+ err = register_chrdev(major, name, &pt_fops);
+ if (err < 0) {
printk("pt_init: unable to get major number %d\n", major);
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present)
pi_release(pt[unit].pi);
- err = -1;
goto out;
}
+ major = err;
pt_class = class_create(THIS_MODULE, "pt");
if (IS_ERR(pt_class)) {
err = PTR_ERR(pt_class);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index bc9b2bcd7db..a04f60693c3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -56,6 +56,7 @@
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
#include <linux/suspend.h>
+#include <linux/mutex.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi.h>
@@ -81,7 +82,7 @@
static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
static struct proc_dir_entry *pkt_proc;
static int pkt_major;
-static struct semaphore ctl_mutex; /* Serialize open/close/setup/teardown */
+static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */
static mempool_t *psd_pool;
@@ -229,16 +230,6 @@ static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
return 1;
}
-static void *pkt_rb_alloc(gfp_t gfp_mask, void *data)
-{
- return kmalloc(sizeof(struct pkt_rb_node), gfp_mask);
-}
-
-static void pkt_rb_free(void *ptr, void *data)
-{
- kfree(ptr);
-}
-
static inline struct pkt_rb_node *pkt_rbtree_next(struct pkt_rb_node *node)
{
struct rb_node *n = rb_next(&node->rb_node);
@@ -2018,7 +2009,7 @@ static int pkt_open(struct inode *inode, struct file *file)
VPRINTK("pktcdvd: entering open\n");
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
pd = pkt_find_dev_from_minor(iminor(inode));
if (!pd) {
ret = -ENODEV;
@@ -2044,14 +2035,14 @@ static int pkt_open(struct inode *inode, struct file *file)
set_blocksize(inode->i_bdev, CD_FRAMESIZE);
}
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
return 0;
out_dec:
pd->refcnt--;
out:
VPRINTK("pktcdvd: failed open (%d)\n", ret);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
return ret;
}
@@ -2060,28 +2051,18 @@ static int pkt_close(struct inode *inode, struct file *file)
struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
int ret = 0;
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
pd->refcnt--;
BUG_ON(pd->refcnt < 0);
if (pd->refcnt == 0) {
int flush = test_bit(PACKET_WRITABLE, &pd->flags);
pkt_release_dev(pd, flush);
}
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
return ret;
}
-static void *psd_pool_alloc(gfp_t gfp_mask, void *data)
-{
- return kmalloc(sizeof(struct packet_stacked_data), gfp_mask);
-}
-
-static void psd_pool_free(void *ptr, void *data)
-{
- kfree(ptr);
-}
-
static int pkt_end_io_read_cloned(struct bio *bio, unsigned int bytes_done, int err)
{
struct packet_stacked_data *psd = bio->bi_private;
@@ -2474,7 +2455,8 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
if (!pd)
return ret;
- pd->rb_pool = mempool_create(PKT_RB_POOL_SIZE, pkt_rb_alloc, pkt_rb_free, NULL);
+ pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
+ sizeof(struct pkt_rb_node));
if (!pd->rb_pool)
goto out_mem;
@@ -2514,7 +2496,7 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
return 0;
out_new_dev:
- blk_put_queue(disk->queue);
+ blk_cleanup_queue(disk->queue);
out_mem2:
put_disk(disk);
out_mem:
@@ -2555,7 +2537,7 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
del_gendisk(pd->disk);
- blk_put_queue(pd->disk->queue);
+ blk_cleanup_queue(pd->disk->queue);
put_disk(pd->disk);
pkt_devs[idx] = NULL;
@@ -2596,21 +2578,21 @@ 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;
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
ret = pkt_setup_dev(&ctrl_cmd);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
break;
case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
ret = pkt_remove_dev(&ctrl_cmd);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
break;
case PKT_CTRL_CMD_STATUS:
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
pkt_get_status(&ctrl_cmd);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
break;
default:
return -ENOTTY;
@@ -2638,7 +2620,8 @@ static int __init pkt_init(void)
{
int ret;
- psd_pool = mempool_create(PSD_POOL_SIZE, psd_pool_alloc, psd_pool_free, NULL);
+ psd_pool = mempool_create_kmalloc_pool(PSD_POOL_SIZE,
+ sizeof(struct packet_stacked_data));
if (!psd_pool)
return -ENOMEM;
@@ -2656,7 +2639,7 @@ static int __init pkt_init(void)
goto out;
}
- init_MUTEX(&ctl_mutex);
+ mutex_init(&ctl_mutex);
pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index ffd6abd6d5a..940bfd7951e 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -186,7 +186,8 @@ static int ramdisk_writepages(struct address_space *mapping,
*/
static int ramdisk_set_page_dirty(struct page *page)
{
- SetPageDirty(page);
+ if (!TestSetPageDirty(page))
+ return 1;
return 0;
}
@@ -310,12 +311,12 @@ static int rd_ioctl(struct inode *inode, struct file *file,
* cache
*/
error = -EBUSY;
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
if (bdev->bd_openers <= 2) {
truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
error = 0;
}
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return error;
}
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index f04d864770a..f73446f580d 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -8,7 +8,6 @@
* and is not licensed separately. See file COPYING for details.
*
* TODO (sorted by decreasing priority)
- * -- Kill first_open (Al Viro fixed the block layer now)
* -- set readonly flag for CDs, set removable flag for CF readers
* -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
* -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
@@ -181,6 +180,7 @@ struct ub_dev;
#define UB_DIR_ILLEGAL2 2
#define UB_DIR_WRITE 3
+/* P3 */
#define UB_DIR_CHAR(c) (((c)==UB_DIR_WRITE)? 'w': \
(((c)==UB_DIR_READ)? 'r': 'n'))
@@ -196,24 +196,11 @@ enum ub_scsi_cmd_state {
UB_CMDST_DONE /* Final state */
};
-static char *ub_scsi_cmd_stname[] = {
- ". ",
- "Cmd",
- "dat",
- "c2s",
- "sts",
- "clr",
- "crs",
- "Sen",
- "fin"
-};
-
struct ub_scsi_cmd {
unsigned char cdb[UB_MAX_CDB_SIZE];
unsigned char cdb_len;
unsigned char dir; /* 0 - none, 1 - read, 3 - write. */
- unsigned char trace_index;
enum ub_scsi_cmd_state state;
unsigned int tag;
struct ub_scsi_cmd *next;
@@ -250,28 +237,6 @@ struct ub_capacity {
};
/*
- * The SCSI command tracing structure.
- */
-
-#define SCMD_ST_HIST_SZ 8
-#define SCMD_TRACE_SZ 63 /* Less than 4KB of 61-byte lines */
-
-struct ub_scsi_cmd_trace {
- int hcur;
- unsigned int tag;
- unsigned int req_size, act_size;
- unsigned char op;
- unsigned char dir;
- unsigned char key, asc, ascq;
- char st_hst[SCMD_ST_HIST_SZ];
-};
-
-struct ub_scsi_trace {
- int cur;
- struct ub_scsi_cmd_trace vec[SCMD_TRACE_SZ];
-};
-
-/*
* This is a direct take-off from linux/include/completion.h
* The difference is that I do not wait on this thing, just poll.
* When I want to wait (ub_probe), I just use the stock completion.
@@ -334,7 +299,6 @@ struct ub_lun {
int changed; /* Media was changed */
int removable;
int readonly;
- int first_open; /* Kludge. See ub_bd_open. */
struct ub_request urq;
@@ -390,7 +354,6 @@ struct ub_dev {
wait_queue_head_t reset_wait;
int sg_stat[6];
- struct ub_scsi_trace tr;
};
/*
@@ -460,137 +423,6 @@ static int ub_qlock_next = 0;
static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */
/*
- * The SCSI command tracing procedures.
- */
-
-static void ub_cmdtr_new(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
-{
- int n;
- struct ub_scsi_cmd_trace *t;
-
- if ((n = sc->tr.cur + 1) == SCMD_TRACE_SZ) n = 0;
- t = &sc->tr.vec[n];
-
- memset(t, 0, sizeof(struct ub_scsi_cmd_trace));
- t->tag = cmd->tag;
- t->op = cmd->cdb[0];
- t->dir = cmd->dir;
- t->req_size = cmd->len;
- t->st_hst[0] = cmd->state;
-
- sc->tr.cur = n;
- cmd->trace_index = n;
-}
-
-static void ub_cmdtr_state(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
-{
- int n;
- struct ub_scsi_cmd_trace *t;
-
- t = &sc->tr.vec[cmd->trace_index];
- if (t->tag == cmd->tag) {
- if ((n = t->hcur + 1) == SCMD_ST_HIST_SZ) n = 0;
- t->st_hst[n] = cmd->state;
- t->hcur = n;
- }
-}
-
-static void ub_cmdtr_act_len(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
-{
- struct ub_scsi_cmd_trace *t;
-
- t = &sc->tr.vec[cmd->trace_index];
- if (t->tag == cmd->tag)
- t->act_size = cmd->act_len;
-}
-
-static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
- unsigned char *sense)
-{
- struct ub_scsi_cmd_trace *t;
-
- t = &sc->tr.vec[cmd->trace_index];
- if (t->tag == cmd->tag) {
- t->key = sense[2] & 0x0F;
- t->asc = sense[12];
- t->ascq = sense[13];
- }
-}
-
-static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
- char *page)
-{
- struct usb_interface *intf;
- struct ub_dev *sc;
- struct list_head *p;
- struct ub_lun *lun;
- int cnt;
- unsigned long flags;
- int nc, nh;
- int i, j;
- struct ub_scsi_cmd_trace *t;
-
- intf = to_usb_interface(dev);
- sc = usb_get_intfdata(intf);
- if (sc == NULL)
- return 0;
-
- cnt = 0;
- spin_lock_irqsave(sc->lock, flags);
-
- cnt += sprintf(page + cnt,
- "poison %d reset %d\n",
- atomic_read(&sc->poison), sc->reset);
- cnt += sprintf(page + cnt,
- "qlen %d qmax %d\n",
- sc->cmd_queue.qlen, sc->cmd_queue.qmax);
- cnt += sprintf(page + cnt,
- "sg %d %d %d %d %d .. %d\n",
- sc->sg_stat[0],
- sc->sg_stat[1],
- sc->sg_stat[2],
- sc->sg_stat[3],
- sc->sg_stat[4],
- sc->sg_stat[5]);
-
- list_for_each (p, &sc->luns) {
- lun = list_entry(p, struct ub_lun, link);
- cnt += sprintf(page + cnt,
- "lun %u changed %d removable %d readonly %d\n",
- lun->num, lun->changed, lun->removable, lun->readonly);
- }
-
- if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0;
- for (j = 0; j < SCMD_TRACE_SZ; j++) {
- t = &sc->tr.vec[nc];
-
- cnt += sprintf(page + cnt, "%08x %02x", t->tag, t->op);
- if (t->op == REQUEST_SENSE) {
- cnt += sprintf(page + cnt, " [sense %x %02x %02x]",
- t->key, t->asc, t->ascq);
- } else {
- cnt += sprintf(page + cnt, " %c", UB_DIR_CHAR(t->dir));
- cnt += sprintf(page + cnt, " [%5d %5d]",
- t->req_size, t->act_size);
- }
- if ((nh = t->hcur + 1) == SCMD_ST_HIST_SZ) nh = 0;
- for (i = 0; i < SCMD_ST_HIST_SZ; i++) {
- cnt += sprintf(page + cnt, " %s",
- ub_scsi_cmd_stname[(int)t->st_hst[nh]]);
- if (++nh == SCMD_ST_HIST_SZ) nh = 0;
- }
- cnt += sprintf(page + cnt, "\n");
-
- if (++nc == SCMD_TRACE_SZ) nc = 0;
- }
-
- spin_unlock_irqrestore(sc->lock, flags);
- return cnt;
-}
-
-static DEVICE_ATTR(diag, S_IRUGO, ub_diag_show, NULL); /* N.B. World readable */
-
-/*
* The id allocator.
*
* This also stores the host for indexing by minor, which is somewhat dirty.
@@ -1092,7 +924,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
add_timer(&sc->work_timer);
cmd->state = UB_CMDST_CMD;
- ub_cmdtr_state(sc, cmd);
return 0;
}
@@ -1145,12 +976,10 @@ static void ub_scsi_dispatch(struct ub_dev *sc)
ub_cmdq_pop(sc);
(*cmd->done)(sc, cmd);
} else if (cmd->state == UB_CMDST_INIT) {
- ub_cmdtr_new(sc, cmd);
if ((rc = ub_scsi_cmd_start(sc, cmd)) == 0)
break;
cmd->error = rc;
cmd->state = UB_CMDST_DONE;
- ub_cmdtr_state(sc, cmd);
} else {
if (!ub_is_completed(&sc->work_done))
break;
@@ -1247,7 +1076,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
cmd->state = UB_CMDST_CLEAR;
- ub_cmdtr_state(sc, cmd);
return;
case -ESHUTDOWN: /* unplug */
case -EILSEQ: /* unplug timeout on uhci */
@@ -1279,7 +1107,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
cmd->state = UB_CMDST_CLR2STS;
- ub_cmdtr_state(sc, cmd);
return;
}
if (urb->status == -EOVERFLOW) {
@@ -1304,7 +1131,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (urb->status != 0 ||
len != cmd->sgv[cmd->current_sg].length) {
cmd->act_len += len;
- ub_cmdtr_act_len(sc, cmd);
cmd->error = -EIO;
ub_state_stat(sc, cmd);
@@ -1331,7 +1157,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
}
cmd->act_len += urb->actual_length;
- ub_cmdtr_act_len(sc, cmd);
if (++cmd->current_sg < cmd->nsg) {
ub_data_start(sc, cmd);
@@ -1357,7 +1182,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
cmd->error = -EIO; /* A cheap trick... */
cmd->state = UB_CMDST_CLRRS;
- ub_cmdtr_state(sc, cmd);
return;
}
@@ -1441,7 +1265,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
cmd->state = UB_CMDST_DONE;
- ub_cmdtr_state(sc, cmd);
ub_cmdq_pop(sc);
(*cmd->done)(sc, cmd);
@@ -1496,7 +1319,6 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
add_timer(&sc->work_timer);
cmd->state = UB_CMDST_DATA;
- ub_cmdtr_state(sc, cmd);
}
/*
@@ -1508,7 +1330,6 @@ static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc)
cmd->error = rc;
cmd->state = UB_CMDST_DONE;
- ub_cmdtr_state(sc, cmd);
ub_cmdq_pop(sc);
(*cmd->done)(sc, cmd);
}
@@ -1554,7 +1375,6 @@ static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
cmd->stat_count = 0;
cmd->state = UB_CMDST_STAT;
- ub_cmdtr_state(sc, cmd);
}
/*
@@ -1573,7 +1393,6 @@ static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
cmd->state = UB_CMDST_STAT;
- ub_cmdtr_state(sc, cmd);
}
/*
@@ -1611,7 +1430,6 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
scmd->tag = sc->tagcnt++;
cmd->state = UB_CMDST_SENSE;
- ub_cmdtr_state(sc, cmd);
ub_cmdq_insert(sc, scmd);
return;
@@ -1668,11 +1486,6 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
struct ub_scsi_cmd *cmd;
/*
- * Ignoring scmd->act_len, because the buffer was pre-zeroed.
- */
- ub_cmdtr_sense(sc, scmd, sense);
-
- /*
* Find the command which triggered the unit attention or a check,
* save the sense into it, and advance its state machine.
*/
@@ -1693,6 +1506,9 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
return;
}
+ /*
+ * Ignoring scmd->act_len, because the buffer was pre-zeroed.
+ */
cmd->key = sense[2] & 0x0F;
cmd->asc = sense[12];
cmd->ascq = sense[13];
@@ -1849,26 +1665,6 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
sc->openc++;
spin_unlock_irqrestore(&ub_lock, flags);
- /*
- * This is a workaround for a specific problem in our block layer.
- * In 2.6.9, register_disk duplicates the code from rescan_partitions.
- * However, if we do add_disk with a device which persistently reports
- * a changed media, add_disk calls register_disk, which does do_open,
- * which will call rescan_paritions for changed media. After that,
- * register_disk attempts to do it all again and causes double kobject
- * registration and a eventually an oops on module removal.
- *
- * The bottom line is, Al Viro says that we should not allow
- * bdev->bd_invalidated to be set when doing add_disk no matter what.
- */
- if (lun->first_open) {
- lun->first_open = 0;
- if (lun->changed) {
- rc = -ENOMEDIUM;
- goto err_open;
- }
- }
-
if (lun->removable || lun->readonly)
check_disk_change(inode->i_bdev);
@@ -2007,9 +1803,8 @@ static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun)
init_completion(&compl);
rc = -ENOMEM;
- if ((cmd = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
+ if ((cmd = kzalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
goto err_alloc;
- memset(cmd, 0, ALLOC_SIZE);
cmd->cdb[0] = TEST_UNIT_READY;
cmd->cdb_len = 6;
@@ -2062,9 +1857,8 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
init_completion(&compl);
rc = -ENOMEM;
- if ((cmd = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
+ if ((cmd = kzalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
goto err_alloc;
- memset(cmd, 0, ALLOC_SIZE);
p = (char *)cmd + sizeof(struct ub_scsi_cmd);
cmd->cdb[0] = 0x25;
@@ -2405,9 +2199,8 @@ static int ub_probe(struct usb_interface *intf,
return -ENXIO;
rc = -ENOMEM;
- if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
+ if ((sc = kzalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
goto err_core;
- memset(sc, 0, sizeof(struct ub_dev));
sc->lock = ub_next_lock();
INIT_LIST_HEAD(&sc->luns);
usb_init_urb(&sc->work_urb);
@@ -2438,9 +2231,6 @@ static int ub_probe(struct usb_interface *intf,
if (ub_get_pipes(sc, sc->dev, intf) != 0)
goto err_dev_desc;
- if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
- goto err_diag;
-
/*
* At this point, all USB initialization is done, do upper layer.
* We really hate halfway initialized structures, so from the
@@ -2480,19 +2270,8 @@ static int ub_probe(struct usb_interface *intf,
nluns = 1;
for (i = 0; i < 3; i++) {
- if ((rc = ub_sync_getmaxlun(sc)) < 0) {
- /*
- * This segment is taken from usb-storage. They say
- * that ZIP-100 needs this, but my own ZIP-100 works
- * fine without this.
- * Still, it does not seem to hurt anything.
- */
- if (rc == -EPIPE) {
- ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
- ub_probe_clear_stall(sc, sc->send_bulk_pipe);
- }
+ if ((rc = ub_sync_getmaxlun(sc)) < 0)
break;
- }
if (rc != 0) {
nluns = rc;
break;
@@ -2505,8 +2284,6 @@ static int ub_probe(struct usb_interface *intf,
}
return 0;
- /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
-err_diag:
err_dev_desc:
usb_set_intfdata(intf, NULL);
// usb_put_intf(sc->intf);
@@ -2524,9 +2301,8 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
int rc;
rc = -ENOMEM;
- if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)
+ if ((lun = kzalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)
goto err_alloc;
- memset(lun, 0, sizeof(struct ub_lun));
lun->num = lnum;
rc = -ENOSR;
@@ -2541,7 +2317,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
lun->removable = 1; /* XXX Query this from the device */
lun->changed = 1; /* ub_revalidate clears only */
- lun->first_open = 1;
ub_revalidate(sc, lun);
rc = -ENOMEM;
@@ -2636,7 +2411,6 @@ static void ub_disconnect(struct usb_interface *intf)
while ((cmd = ub_cmdq_peek(sc)) != NULL) {
cmd->error = -ENOTCONN;
cmd->state = UB_CMDST_DONE;
- ub_cmdtr_state(sc, cmd);
ub_cmdq_pop(sc);
(*cmd->done)(sc, cmd);
cnt++;
@@ -2687,7 +2461,6 @@ static void ub_disconnect(struct usb_interface *intf)
* and no URBs left in transit.
*/
- device_remove_file(&sc->intf->dev, &dev_attr_diag);
usb_set_intfdata(intf, NULL);
// usb_put_intf(sc->intf);
sc->intf = NULL;
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 4ada1268b40..f7d4c65a7b8 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -50,6 +50,7 @@
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/dma-mapping.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/hdreg.h> /* HDIO_GETGEO */
@@ -881,8 +882,8 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i
printk(KERN_INFO "Micro Memory(tm) controller #%d found at %02x:%02x (PCI Mem Module (Battery Backup))\n",
card->card_number, dev->bus->number, dev->devfn);
- if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) &&
- pci_set_dma_mask(dev, 0xffffffffLL)) {
+ if (pci_set_dma_mask(dev, DMA_64BIT_MASK) &&
+ pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards);
return -ENOMEM;
}
@@ -1131,7 +1132,7 @@ static void mm_pci_remove(struct pci_dev *dev)
pci_free_consistent(card->dev, PAGE_SIZE*2,
card->mm_pages[1].desc,
card->mm_pages[1].page_dma);
- blk_put_queue(card->queue);
+ blk_cleanup_queue(card->queue);
}
static const struct pci_device_id mm_pci_ids[] = { {