aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-22 17:03:12 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-22 17:03:12 -0700
commit8abfc6e7a45eb74e51904bbae676fae008b11366 (patch)
tree57d0a24558c0693e3a52e8e756616f6c72def1e9 /drivers
parente9dd2b6837e26fe202708cce5ea4bb4ee3e3482e (diff)
parent6362beea8914cbd4630ccde3617d944aeca2d48f (diff)
Merge branch 'for-2.6.37/drivers' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.37/drivers' of git://git.kernel.dk/linux-2.6-block: (95 commits) cciss: fix PCI IDs for new Smart Array controllers drbd: add race-breaker to drbd_go_diskless drbd: use dynamic_dev_dbg to optionally log uuid changes dynamic_debug.h: Fix dynamic_dev_dbg() macro if CONFIG_DYNAMIC_DEBUG not set drbd: cleanup: change "<= 0" to "== 0" drbd: relax the grace period of the md_sync timer again drbd: add some more explicit drbd_md_sync drbd: drop wrong debug asserts, fix recently introduced race drbd: cleanup useless leftover warn/error printk's drbd: add explicit drbd_md_sync to drbd_resync_finished drbd: Do not log an ASSERT for P_OV_REQUEST packets while C_CONNECTED drbd: fix for possible deadlock on IO error during resync drbd: fix unlikely access after free and list corruption drbd: fix for spurious fullsync (uuids rotated too fast) drbd: allow for explicit resync-finished notifications drbd: preparation commit, using full state in receive_state() drbd: drbd_send_ack_dp must not rely on header information drbd: Fix regression in recv_bm_rle_bits (compressed bitmap) drbd: Fixed a stupid copy and paste error drbd: Allow larger values for c-fill-target. ... Fix up trivial conflict in drivers/block/ataflop.c due to BKL removal
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/amiflop.c60
-rw-r--r--drivers/block/ataflop.c50
-rw-r--r--drivers/block/cciss.c864
-rw-r--r--drivers/block/drbd/drbd_actlog.c41
-rw-r--r--drivers/block/drbd/drbd_bitmap.c2
-rw-r--r--drivers/block/drbd/drbd_int.h216
-rw-r--r--drivers/block/drbd/drbd_main.c593
-rw-r--r--drivers/block/drbd/drbd_nl.c270
-rw-r--r--drivers/block/drbd/drbd_proc.c34
-rw-r--r--drivers/block/drbd/drbd_receiver.c946
-rw-r--r--drivers/block/drbd/drbd_req.c165
-rw-r--r--drivers/block/drbd/drbd_req.h62
-rw-r--r--drivers/block/drbd/drbd_worker.c292
-rw-r--r--drivers/block/floppy.c66
-rw-r--r--drivers/block/loop.c101
15 files changed, 2390 insertions, 1372 deletions
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 4b852c96226..a1725e6488d 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -115,8 +115,6 @@ static unsigned long int fd_def_df0 = FD_DD_3; /* default for df0 if it does
module_param(fd_def_df0, ulong, 0);
MODULE_LICENSE("GPL");
-static struct request_queue *floppy_queue;
-
/*
* Macros
*/
@@ -165,6 +163,7 @@ static volatile int selected = -1; /* currently selected drive */
static int writepending;
static int writefromint;
static char *raw_buf;
+static int fdc_queue;
static DEFINE_SPINLOCK(amiflop_lock);
@@ -1335,6 +1334,42 @@ static int get_track(int drive, int track)
return -1;
}
+/*
+ * Round-robin between our available drives, doing one request from each
+ */
+static struct request *set_next_request(void)
+{
+ struct request_queue *q;
+ int cnt = FD_MAX_UNITS;
+ struct request *rq;
+
+ /* Find next queue we can dispatch from */
+ fdc_queue = fdc_queue + 1;
+ if (fdc_queue == FD_MAX_UNITS)
+ fdc_queue = 0;
+
+ for(cnt = FD_MAX_UNITS; cnt > 0; cnt--) {
+
+ if (unit[fdc_queue].type->code == FD_NODRIVE) {
+ if (++fdc_queue == FD_MAX_UNITS)
+ fdc_queue = 0;
+ continue;
+ }
+
+ q = unit[fdc_queue].gendisk->queue;
+ if (q) {
+ rq = blk_fetch_request(q);
+ if (rq)
+ break;
+ }
+
+ if (++fdc_queue == FD_MAX_UNITS)
+ fdc_queue = 0;
+ }
+
+ return rq;
+}
+
static void redo_fd_request(void)
{
struct request *rq;
@@ -1346,7 +1381,7 @@ static void redo_fd_request(void)
int err;
next_req:
- rq = blk_fetch_request(floppy_queue);
+ rq = set_next_request();
if (!rq) {
/* Nothing left to do */
return;
@@ -1683,6 +1718,13 @@ static int __init fd_probe_drives(void)
continue;
}
unit[drive].gendisk = disk;
+
+ disk->queue = blk_init_queue(do_fd_request, &amiflop_lock);
+ if (!disk->queue) {
+ unit[drive].type->code = FD_NODRIVE;
+ continue;
+ }
+
drives++;
if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {
printk("no mem for ");
@@ -1696,7 +1738,6 @@ static int __init fd_probe_drives(void)
disk->fops = &floppy_fops;
sprintf(disk->disk_name, "fd%d", drive);
disk->private_data = &unit[drive];
- disk->queue = floppy_queue;
set_capacity(disk, 880*2);
add_disk(disk);
}
@@ -1744,11 +1785,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev)
goto out_irq2;
}
- ret = -ENOMEM;
- floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock);
- if (!floppy_queue)
- goto out_queue;
-
ret = -ENODEV;
if (fd_probe_drives() < 1) /* No usable drives */
goto out_probe;
@@ -1792,8 +1828,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev)
return 0;
out_probe:
- blk_cleanup_queue(floppy_queue);
-out_queue:
free_irq(IRQ_AMIGA_CIAA_TB, NULL);
out_irq2:
free_irq(IRQ_AMIGA_DSKBLK, NULL);
@@ -1811,9 +1845,12 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev)
for( i = 0; i < FD_MAX_UNITS; i++) {
if (unit[i].type->code != FD_NODRIVE) {
+ struct request_queue *q = unit[i].gendisk->queue;
del_gendisk(unit[i].gendisk);
put_disk(unit[i].gendisk);
kfree(unit[i].trackbuf);
+ if (q)
+ blk_cleanup_queue(q);
}
}
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
@@ -1821,7 +1858,6 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev)
free_irq(IRQ_AMIGA_DSKBLK, NULL);
custom.dmacon = DMAF_DISK; /* disable DMA */
amiga_chip_free(raw_buf);
- blk_cleanup_queue(floppy_queue);
unregister_blkdev(FLOPPY_MAJOR, "fd");
}
#endif
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 8c021bb7a99..4e4cc6c828c 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -80,8 +80,8 @@
#undef DEBUG
static DEFINE_MUTEX(ataflop_mutex);
-static struct request_queue *floppy_queue;
static struct request *fd_request;
+static int fdc_queue;
/* Disk types: DD, HD, ED */
static struct atari_disk_type {
@@ -1392,6 +1392,29 @@ static void setup_req_params( int drive )
ReqTrack, ReqSector, (unsigned long)ReqData ));
}
+/*
+ * Round-robin between our available drives, doing one request from each
+ */
+static struct request *set_next_request(void)
+{
+ struct request_queue *q;
+ int old_pos = fdc_queue;
+ struct request *rq;
+
+ do {
+ q = unit[fdc_queue].disk->queue;
+ if (++fdc_queue == FD_MAX_UNITS)
+ fdc_queue = 0;
+ if (q) {
+ rq = blk_fetch_request(q);
+ if (rq)
+ break;
+ }
+ } while (fdc_queue != old_pos);
+
+ return rq;
+}
+
static void redo_fd_request(void)
{
@@ -1406,7 +1429,7 @@ static void redo_fd_request(void)
repeat:
if (!fd_request) {
- fd_request = blk_fetch_request(floppy_queue);
+ fd_request = set_next_request();
if (!fd_request)
goto the_end;
}
@@ -1933,10 +1956,6 @@ static int __init atari_floppy_init (void)
PhysTrackBuffer = virt_to_phys(TrackBuffer);
BufferDrive = BufferSide = BufferTrack = -1;
- floppy_queue = blk_init_queue(do_fd_request, &ataflop_lock);
- if (!floppy_queue)
- goto Enomem;
-
for (i = 0; i < FD_MAX_UNITS; i++) {
unit[i].track = -1;
unit[i].flags = 0;
@@ -1945,7 +1964,10 @@ static int __init atari_floppy_init (void)
sprintf(unit[i].disk->disk_name, "fd%d", i);
unit[i].disk->fops = &floppy_fops;
unit[i].disk->private_data = &unit[i];
- unit[i].disk->queue = floppy_queue;
+ unit[i].disk->queue = blk_init_queue(do_fd_request,
+ &ataflop_lock);
+ if (!unit[i].disk->queue)
+ goto Enomem;
set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
add_disk(unit[i].disk);
}
@@ -1960,10 +1982,14 @@ static int __init atari_floppy_init (void)
return 0;
Enomem:
- while (i--)
+ while (i--) {
+ struct request_queue *q = unit[i].disk->queue;
+
put_disk(unit[i].disk);
- if (floppy_queue)
- blk_cleanup_queue(floppy_queue);
+ if (q)
+ blk_cleanup_queue(q);
+ }
+
unregister_blkdev(FLOPPY_MAJOR, "fd");
return -ENOMEM;
}
@@ -2012,12 +2038,14 @@ static void __exit atari_floppy_exit(void)
int i;
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
for (i = 0; i < FD_MAX_UNITS; i++) {
+ struct request_queue *q = unit[i].disk->queue;
+
del_gendisk(unit[i].disk);
put_disk(unit[i].disk);
+ blk_cleanup_queue(q);
}
unregister_blkdev(FLOPPY_MAJOR, "fd");
- blk_cleanup_queue(floppy_queue);
del_timer_sync(&fd_timer);
atari_stram_free( DMABuffer );
}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index c484c96e22a..f09e6df15aa 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -105,11 +105,12 @@ static const struct pci_device_id cciss_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3250},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3251},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3350},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3351},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3352},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3353},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3354},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3355},
{0,}
};
@@ -149,11 +150,12 @@ static struct board_type products[] = {
{0x3249103C, "Smart Array P812", &SA5_access},
{0x324A103C, "Smart Array P712m", &SA5_access},
{0x324B103C, "Smart Array P711m", &SA5_access},
- {0x3250103C, "Smart Array", &SA5_access},
- {0x3251103C, "Smart Array", &SA5_access},
- {0x3252103C, "Smart Array", &SA5_access},
- {0x3253103C, "Smart Array", &SA5_access},
- {0x3254103C, "Smart Array", &SA5_access},
+ {0x3350103C, "Smart Array", &SA5_access},
+ {0x3351103C, "Smart Array", &SA5_access},
+ {0x3352103C, "Smart Array", &SA5_access},
+ {0x3353103C, "Smart Array", &SA5_access},
+ {0x3354103C, "Smart Array", &SA5_access},
+ {0x3355103C, "Smart Array", &SA5_access},
};
/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -1232,470 +1234,452 @@ static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c)
c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
(void)check_for_unit_attention(h, c);
}
-/*
- * ioctl
- */
-static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
+
+static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
{
- struct gendisk *disk = bdev->bd_disk;
- ctlr_info_t *h = get_host(disk);
- drive_info_struct *drv = get_drv(disk);
- void __user *argp = (void __user *)arg;
+ cciss_pci_info_struct pciinfo;
- dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
- cmd, arg);
- switch (cmd) {
- case CCISS_GETPCIINFO:
- {
- cciss_pci_info_struct pciinfo;
-
- if (!arg)
- return -EINVAL;
- pciinfo.domain = pci_domain_nr(h->pdev->bus);
- pciinfo.bus = h->pdev->bus->number;
- pciinfo.dev_fn = h->pdev->devfn;
- pciinfo.board_id = h->board_id;
- if (copy_to_user
- (argp, &pciinfo, sizeof(cciss_pci_info_struct)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETINTINFO:
- {
- cciss_coalint_struct intinfo;
- if (!arg)
- return -EINVAL;
- intinfo.delay =
- readl(&h->cfgtable->HostWrite.CoalIntDelay);
- intinfo.count =
- readl(&h->cfgtable->HostWrite.CoalIntCount);
- if (copy_to_user
- (argp, &intinfo, sizeof(cciss_coalint_struct)))
- return -EFAULT;
- return 0;
- }
- case CCISS_SETINTINFO:
- {
- cciss_coalint_struct intinfo;
- unsigned long flags;
- int i;
-
- if (!arg)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (copy_from_user
- (&intinfo, argp, sizeof(cciss_coalint_struct)))
- return -EFAULT;
- if ((intinfo.delay == 0) && (intinfo.count == 0))
- return -EINVAL;
- spin_lock_irqsave(&h->lock, flags);
- /* Update the field, and then ring the doorbell */
- writel(intinfo.delay,
- &(h->cfgtable->HostWrite.CoalIntDelay));
- writel(intinfo.count,
- &(h->cfgtable->HostWrite.CoalIntCount));
- writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
-
- for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
- if (!(readl(h->vaddr + SA5_DOORBELL)
- & CFGTBL_ChangeReq))
- break;
- /* delay and try again */
- udelay(1000);
- }
- spin_unlock_irqrestore(&h->lock, flags);
- if (i >= MAX_IOCTL_CONFIG_WAIT)
- return -EAGAIN;
- return 0;
- }
- case CCISS_GETNODENAME:
- {
- NodeName_type NodeName;
- int i;
-
- if (!arg)
- return -EINVAL;
- for (i = 0; i < 16; i++)
- NodeName[i] =
- readb(&h->cfgtable->ServerName[i]);
- if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_SETNODENAME:
- {
- NodeName_type NodeName;
- unsigned long flags;
- int i;
+ if (!argp)
+ return -EINVAL;
+ pciinfo.domain = pci_domain_nr(h->pdev->bus);
+ pciinfo.bus = h->pdev->bus->number;
+ pciinfo.dev_fn = h->pdev->devfn;
+ pciinfo.board_id = h->board_id;
+ if (copy_to_user(argp, &pciinfo, sizeof(cciss_pci_info_struct)))
+ return -EFAULT;
+ return 0;
+}
- if (!arg)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
+{
+ cciss_coalint_struct intinfo;
- if (copy_from_user
- (NodeName, argp, sizeof(NodeName_type)))
- return -EFAULT;
+ if (!argp)
+ return -EINVAL;
+ intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
+ intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
+ if (copy_to_user
+ (argp, &intinfo, sizeof(cciss_coalint_struct)))
+ return -EFAULT;
+ return 0;
+}
- spin_lock_irqsave(&h->lock, flags);
+static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
+{
+ cciss_coalint_struct intinfo;
+ unsigned long flags;
+ int i;
- /* Update the field, and then ring the doorbell */
- for (i = 0; i < 16; i++)
- writeb(NodeName[i],
- &h->cfgtable->ServerName[i]);
+ if (!argp)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&intinfo, argp, sizeof(intinfo)))
+ return -EFAULT;
+ if ((intinfo.delay == 0) && (intinfo.count == 0))
+ return -EINVAL;
+ spin_lock_irqsave(&h->lock, flags);
+ /* Update the field, and then ring the doorbell */
+ writel(intinfo.delay, &(h->cfgtable->HostWrite.CoalIntDelay));
+ writel(intinfo.count, &(h->cfgtable->HostWrite.CoalIntCount));
+ writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
- writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+ for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+ if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+ break;
+ udelay(1000); /* delay and try again */
+ }
+ spin_unlock_irqrestore(&h->lock, flags);
+ if (i >= MAX_IOCTL_CONFIG_WAIT)
+ return -EAGAIN;
+ return 0;
+}
- for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
- if (!(readl(h->vaddr + SA5_DOORBELL)
- & CFGTBL_ChangeReq))
- break;
- /* delay and try again */
- udelay(1000);
- }
- spin_unlock_irqrestore(&h->lock, flags);
- if (i >= MAX_IOCTL_CONFIG_WAIT)
- return -EAGAIN;
- return 0;
- }
+static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
+{
+ NodeName_type NodeName;
+ int i;
- case CCISS_GETHEARTBEAT:
- {
- Heartbeat_type heartbeat;
-
- if (!arg)
- return -EINVAL;
- heartbeat = readl(&h->cfgtable->HeartBeat);
- if (copy_to_user
- (argp, &heartbeat, sizeof(Heartbeat_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETBUSTYPES:
- {
- BusTypes_type BusTypes;
-
- if (!arg)
- return -EINVAL;
- BusTypes = readl(&h->cfgtable->BusTypes);
- if (copy_to_user
- (argp, &BusTypes, sizeof(BusTypes_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETFIRMVER:
- {
- FirmwareVer_type firmware;
+ if (!argp)
+ return -EINVAL;
+ for (i = 0; i < 16; i++)
+ NodeName[i] = readb(&h->cfgtable->ServerName[i]);
+ if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
+ return -EFAULT;
+ return 0;
+}
- if (!arg)
- return -EINVAL;
- memcpy(firmware, h->firm_ver, 4);
+static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
+{
+ NodeName_type NodeName;
+ unsigned long flags;
+ int i;
- if (copy_to_user
- (argp, firmware, sizeof(FirmwareVer_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETDRIVVER:
- {
- DriverVer_type DriverVer = DRIVER_VERSION;
+ if (!argp)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(NodeName, argp, sizeof(NodeName_type)))
+ return -EFAULT;
+ spin_lock_irqsave(&h->lock, flags);
+ /* Update the field, and then ring the doorbell */
+ for (i = 0; i < 16; i++)
+ writeb(NodeName[i], &h->cfgtable->ServerName[i]);
+ writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+ for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+ if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+ break;
+ udelay(1000); /* delay and try again */
+ }
+ spin_unlock_irqrestore(&h->lock, flags);
+ if (i >= MAX_IOCTL_CONFIG_WAIT)
+ return -EAGAIN;
+ return 0;
+}
- if (!arg)
- return -EINVAL;
+static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
+{
+ Heartbeat_type heartbeat;
- if (copy_to_user
- (argp, &DriverVer, sizeof(DriverVer_type)))
- return -EFAULT;
- return 0;
- }
+ if (!argp)
+ return -EINVAL;
+ heartbeat = readl(&h->cfgtable->HeartBeat);
+ if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
+ return -EFAULT;
+ return 0;
+}
- case CCISS_DEREGDISK:
- case CCISS_REGNEWD:
- case CCISS_REVALIDVOLS:
- return rebuild_lun_table(h, 0, 1);
+static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
+{
+ BusTypes_type BusTypes;
+
+ if (!argp)
+ return -EINVAL;
+ BusTypes = readl(&h->cfgtable->BusTypes);
+ if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
+ return -EFAULT;
+ return 0;
+}
- case CCISS_GETLUNINFO:{
- LogvolInfo_struct luninfo;
+static int cciss_getfirmver(ctlr_info_t *h, void __user *argp)
+{
+ FirmwareVer_type firmware;
- memcpy(&luninfo.LunID, drv->LunID,
- sizeof(luninfo.LunID));
- luninfo.num_opens = drv->usage_count;
- luninfo.num_parts = 0;
- if (copy_to_user(argp, &luninfo,
- sizeof(LogvolInfo_struct)))
- return -EFAULT;
- return 0;
+ if (!argp)
+ return -EINVAL;
+ memcpy(firmware, h->firm_ver, 4);
+
+ if (copy_to_user
+ (argp, firmware, sizeof(FirmwareVer_type)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cciss_getdrivver(ctlr_info_t *h, void __user *argp)
+{
+ DriverVer_type DriverVer = DRIVER_VERSION;
+
+ if (!argp)
+ return -EINVAL;
+ if (copy_to_user(argp, &DriverVer, sizeof(DriverVer_type)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cciss_getluninfo(ctlr_info_t *h,
+ struct gendisk *disk, void __user *argp)
+{
+ LogvolInfo_struct luninfo;
+ drive_info_struct *drv = get_drv(disk);
+
+ if (!argp)
+ return -EINVAL;
+ memcpy(&luninfo.LunID, drv->LunID, sizeof(luninfo.LunID));
+ luninfo.num_opens = drv->usage_count;
+ luninfo.num_parts = 0;
+ if (copy_to_user(argp, &luninfo, sizeof(LogvolInfo_struct)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cciss_passthru(ctlr_info_t *h, void __user *argp)
+{
+ IOCTL_Command_struct iocommand;
+ CommandList_struct *c;
+ char *buff = NULL;
+ u64bit temp64;
+ DECLARE_COMPLETION_ONSTACK(wait);
+
+ if (!argp)
+ return -EINVAL;
+
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
+ if (copy_from_user
+ (&iocommand, argp, sizeof(IOCTL_Command_struct)))
+ return -EFAULT;
+ if ((iocommand.buf_size < 1) &&
+ (iocommand.Request.Type.Direction != XFER_NONE)) {
+ return -EINVAL;
+ }
+ if (iocommand.buf_size > 0) {
+ buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
+ if (buff == NULL)
+ return -EFAULT;
+ }
+ if (iocommand.Request.Type.Direction == XFER_WRITE) {
+ /* Copy the data into the buffer we created */
+ if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
+ kfree(buff);
+ return -EFAULT;
}
- case CCISS_PASSTHRU:
- {
- IOCTL_Command_struct iocommand;
- CommandList_struct *c;
- char *buff = NULL;
- u64bit temp64;
- DECLARE_COMPLETION_ONSTACK(wait);
-
- if (!arg)
- return -EINVAL;
-
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- if (copy_from_user
- (&iocommand, argp, sizeof(IOCTL_Command_struct)))
- return -EFAULT;
- if ((iocommand.buf_size < 1) &&
- (iocommand.Request.Type.Direction != XFER_NONE)) {
- return -EINVAL;
- }
-#if 0 /* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */
- /* Check kmalloc limits */
- if (iocommand.buf_size > 128000)
- return -EINVAL;
-#endif
- if (iocommand.buf_size > 0) {
- buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
- if (buff == NULL)
- return -EFAULT;
- }
- if (iocommand.Request.Type.Direction == XFER_WRITE) {
- /* Copy the data into the buffer we created */
- if (copy_from_user
- (buff, iocommand.buf, iocommand.buf_size)) {
- kfree(buff);
- return -EFAULT;
- }
- } else {
- memset(buff, 0, iocommand.buf_size);
- }
- c = cmd_special_alloc(h);
- if (!c) {
- kfree(buff);
- return -ENOMEM;
- }
- /* Fill in the command type */
- c->cmd_type = CMD_IOCTL_PEND;
- /* Fill in Command Header */
- c->Header.ReplyQueue = 0; /* unused in simple mode */
- if (iocommand.buf_size > 0) /* buffer to fill */
- {
- c->Header.SGList = 1;
- c->Header.SGTotal = 1;
- } else /* no buffers to fill */
- {
- c->Header.SGList = 0;
- c->Header.SGTotal = 0;
- }
- c->Header.LUN = iocommand.LUN_info;
- /* use the kernel address the cmd block for tag */
- c->Header.Tag.lower = c->busaddr;
-
- /* Fill in Request block */
- c->Request = iocommand.Request;
-
- /* Fill in the scatter gather information */
- if (iocommand.buf_size > 0) {
- temp64.val = pci_map_single(h->pdev, buff,
- iocommand.buf_size,
- PCI_DMA_BIDIRECTIONAL);
- c->SG[0].Addr.lower = temp64.val32.lower;
- c->SG[0].Addr.upper = temp64.val32.upper;
- c->SG[0].Len = iocommand.buf_size;
- c->SG[0].Ext = 0; /* we are not chaining */
- }
- c->waiting = &wait;
+ } else {
+ memset(buff, 0, iocommand.buf_size);
+ }
+ c = cmd_special_alloc(h);
+ if (!c) {
+ kfree(buff);
+ return -ENOMEM;
+ }
+ /* Fill in the command type */
+ c->cmd_type = CMD_IOCTL_PEND;
+ /* Fill in Command Header */
+ c->Header.ReplyQueue = 0; /* unused in simple mode */
+ if (iocommand.buf_size > 0) { /* buffer to fill */
+ c->Header.SGList = 1;
+ c->Header.SGTotal = 1;
+ } else { /* no buffers to fill */
+ c->Header.SGList = 0;
+ c->Header.SGTotal = 0;
+ }
+ c->Header.LUN = iocommand.LUN_info;
+ /* use the kernel address the cmd block for tag */
+ c->Header.Tag.lower = c->busaddr;
- enqueue_cmd_and_start_io(h, c);
- wait_for_completion(&wait);
+ /* Fill in Request block */
+ c->Request = iocommand.Request;
- /* unlock the buffers from DMA */
- temp64.val32.lower = c->SG[0].Addr.lower;
- temp64.val32.upper = c->SG[0].Addr.upper;
- pci_unmap_single(h->pdev, (dma_addr_t) temp64.val,
- iocommand.buf_size,
- PCI_DMA_BIDIRECTIONAL);
+ /* Fill in the scatter gather information */
+ if (iocommand.buf_size > 0) {
+ temp64.val = pci_map_single(h->pdev, buff,
+ iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
+ c->SG[0].Addr.lower = temp64.val32.lower;
+ c->SG[0].Addr.upper = temp64.val32.upper;
+ c->SG[0].Len = iocommand.buf_size;
+ c->SG[0].Ext = 0; /* we are not chaining */
+ }
+ c->waiting = &wait;
- check_ioctl_unit_attention(h, c);
+ enqueue_cmd_and_start_io(h, c);
+ wait_for_completion(&wait);
- /* Copy the error information out */
- iocommand.error_info = *(c->err_info);
- if (copy_to_user
- (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
- kfree(buff);
- cmd_special_free(h, c);
- return -EFAULT;
- }
+ /* unlock the buffers from DMA */
+ temp64.val32.lower = c->SG[0].Addr.lower;
+ temp64.val32.upper = c->SG[0].Addr.upper;
+ pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, iocommand.buf_size,
+ PCI_DMA_BIDIRECTIONAL);
+ check_ioctl_unit_attention(h, c);
+
+ /* Copy the error information out */
+ iocommand.error_info = *(c->err_info);
+ if (copy_to_user(argp, &iocommand, sizeof(IOCTL_Command_struct))) {
+ kfree(buff);
+ cmd_special_free(h, c);
+ return -EFAULT;
+ }
- if (iocommand.Request.Type.Direction == XFER_READ) {
- /* Copy the data out of the buffer we created */
- if (copy_to_user
- (iocommand.buf, buff, iocommand.buf_size)) {
- kfree(buff);
- cmd_special_free(h, c);
- return -EFAULT;
- }
- }
+ if (iocommand.Request.Type.Direction == XFER_READ) {
+ /* Copy the data out of the buffer we created */
+ if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
kfree(buff);
cmd_special_free(h, c);
- return 0;
+ return -EFAULT;
}
- case CCISS_BIG_PASSTHRU:{
- BIG_IOCTL_Command_struct *ioc;
- CommandList_struct *c;
- unsigned char **buff = NULL;
- int *buff_size = NULL;
- u64bit temp64;
- BYTE sg_used = 0;
- int status = 0;
- int i;
- DECLARE_COMPLETION_ONSTACK(wait);
- __u32 left;
- __u32 sz;
- BYTE __user *data_ptr;
-
- if (!arg)
- return -EINVAL;
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
- ioc = (BIG_IOCTL_Command_struct *)
- kmalloc(sizeof(*ioc), GFP_KERNEL);
- if (!ioc) {
- status = -ENOMEM;
- goto cleanup1;
- }
- if (copy_from_user(ioc, argp, sizeof(*ioc))) {
+ }
+ kfree(buff);
+ cmd_special_free(h, c);
+ return 0;
+}
+
+static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp)
+{
+ BIG_IOCTL_Command_struct *ioc;
+ CommandList_struct *c;
+ unsigned char **buff = NULL;
+ int *buff_size = NULL;
+ u64bit temp64;
+ BYTE sg_used = 0;
+ int status = 0;
+ int i;
+ DECLARE_COMPLETION_ONSTACK(wait);
+ __u32 left;
+ __u32 sz;
+ BYTE __user *data_ptr;
+
+ if (!argp)
+ return -EINVAL;
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+ ioc = (BIG_IOCTL_Command_struct *)
+ kmalloc(sizeof(*ioc), GFP_KERNEL);
+ if (!ioc) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ if (copy_from_user(ioc, argp, sizeof(*ioc))) {
+ status = -EFAULT;
+ goto cleanup1;
+ }
+ if ((ioc->buf_size < 1) &&
+ (ioc->Request.Type.Direction != XFER_NONE)) {
+ status = -EINVAL;
+ goto cleanup1;
+ }
+ /* Check kmalloc limits using all SGs */
+ if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
+ status = -EINVAL;
+ goto cleanup1;
+ }
+ if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
+ status = -EINVAL;
+ goto cleanup1;
+ }
+ buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
+ if (!buff) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL);
+ if (!buff_size) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ left = ioc->buf_size;
+ data_ptr = ioc->buf;
+ while (left) {
+ sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
+ buff_size[sg_used] = sz;
+ buff[sg_used] = kmalloc(sz, GFP_KERNEL);
+ if (buff[sg_used] == NULL) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ if (ioc->Request.Type.Direction == XFER_WRITE) {
+ if (copy_from_user(buff[sg_used], data_ptr, sz)) {
status = -EFAULT;
goto cleanup1;
}
- if ((ioc->buf_size < 1) &&
- (ioc->Request.Type.Direction != XFER_NONE)) {
- status = -EINVAL;
- goto cleanup1;
- }
- /* Check kmalloc limits using all SGs */
- if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
- status = -EINVAL;
- goto cleanup1;
- }
- if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
- status = -EINVAL;
- goto cleanup1;
- }
- buff =
- kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
- if (!buff) {
- status = -ENOMEM;
- goto cleanup1;
- }
- buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
- GFP_KERNEL);
- if (!buff_size) {
- status = -ENOMEM;
- goto cleanup1;
- }
- left = ioc->buf_size;
- data_ptr = ioc->buf;
- while (left) {
- sz = (left >
- ioc->malloc_size) ? ioc->
- malloc_size : left;
- buff_size[sg_used] = sz;
- buff[sg_used] = kmalloc(sz, GFP_KERNEL);
- if (buff[sg_used] == NULL) {
- status = -ENOMEM;
- goto cleanup1;
- }
- if (ioc->Request.Type.Direction == XFER_WRITE) {
- if (copy_from_user
- (buff[sg_used], data_ptr, sz)) {
- status = -EFAULT;
- goto cleanup1;
- }
- } else {
- memset(buff[sg_used], 0, sz);
- }
- left -= sz;
- data_ptr += sz;
- sg_used++;
- }
- c = cmd_special_alloc(h);
- if (!c) {
- status = -ENOMEM;
- goto cleanup1;
- }
- c->cmd_type = CMD_IOCTL_PEND;
- c->Header.ReplyQueue = 0;
+ } else {
+ memset(buff[sg_used], 0, sz);
+ }
+ left -= sz;
+ data_ptr += sz;
+ sg_used++;
+ }
+ c = cmd_special_alloc(h);
+ if (!c) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ c->cmd_type = CMD_IOCTL_PEND;
+ c->Header.ReplyQueue = 0;
+ c->Header.SGList = sg_used;
+ c->Header.SGTotal = sg_used;
+ c->Header.LUN = ioc->LUN_info;
+ c->Header.Tag.lower = c->busaddr;
- if (ioc->buf_size > 0) {
- c->Header.SGList = sg_used;
- c->Header.SGTotal = sg_used;
- } else {
- c->Header.SGList = 0;
- c->Header.SGTotal = 0;
- }
- c->Header.LUN = ioc->LUN_info;
- c->Header.Tag.lower = c->busaddr;
-
- c->Request = ioc->Re