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/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.c15
-rw-r--r--drivers/block/cciss_scsi.c5
-rw-r--r--drivers/block/cpqarray.c3
-rw-r--r--drivers/block/floppy.c34
-rw-r--r--drivers/block/loop.c4
-rw-r--r--drivers/block/nbd.c5
-rw-r--r--drivers/block/paride/bpck6.c3
-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.c26
-rw-r--r--drivers/block/umem.c5
23 files changed, 321 insertions, 209 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/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 1f2890989b5..1b0fd31c57c 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -996,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) {
@@ -2361,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;
@@ -2730,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;
}
@@ -2941,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)
{
@@ -3061,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;
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 fb2d0be7cde..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 */
@@ -250,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);
@@ -735,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)) {
@@ -1063,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;
@@ -1523,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
@@ -3811,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;
}
@@ -4433,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);
@@ -4522,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);
@@ -4594,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);
@@ -4633,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 74bf0255e98..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;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index a9bde30dada..8bca4905d7f 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -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,
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/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 1d261f985f3..a04f60693c3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -230,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);
@@ -2073,16 +2063,6 @@ static int pkt_close(struct inode *inode, struct file *file)
}
-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;
@@ -2475,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;
@@ -2639,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;
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index c16e66b9c7a..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;
}