* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Questions/Comments/Bugfixes to Cpqarray-discuss@lists.sourceforge.net
+ * Questions/Comments/Bugfixes to iss_storagedev@hp.com
*
*/
#include <linux/config.h> /* CONFIG_PROC_FS */
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/bio.h>
static int eisa[8];
-#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type))
+#define NR_PRODUCTS ARRAY_SIZE(products)
/* board_id = Subsystem Device ID & Vendor ID
* product = Marketing Name for the board
- * access = Address of the struct of function pointers
+ * access = Address of the struct of function pointers
*/
static struct board_type products[] = {
{ 0x0040110E, "IDA", &smart1_access },
};
/* define the PCI info for the PCI cards this driver can control */
-const struct pci_device_id cpqarray_pci_device_id[] =
+static const struct pci_device_id cpqarray_pci_device_id[] =
{
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX,
0x0E11, 0x4058, 0, 0, 0}, /* SA431 */
/* Debug Extra Paranoid... */
#define DBGPX(s) do { } while(0)
-int cpqarray_init_step2(void);
static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev);
-static void *remap_pci_mem(ulong base, ulong size);
+static void __iomem *remap_pci_mem(ulong base, ulong size);
static int cpqarray_eisa_detect(void);
static int pollcomplete(int ctlr);
static void getgeometry(int ctlr);
static int ida_open(struct inode *inode, struct file *filep);
static int ida_release(struct inode *inode, struct file *filep);
static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
+static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
static void do_ida_request(request_queue_t *q);
.open = ida_open,
.release = ida_release,
.ioctl = ida_ioctl,
+ .getgeo = ida_getgeo,
.revalidate_disk= ida_revalidate,
};
}
#endif /* CONFIG_PROC_FS */
-MODULE_PARM(eisa, "1-8i");
-
-/* This is a bit of a hack,
- * necessary to support both eisa and pci
- */
-int __init cpqarray_init(void)
-{
- return (cpqarray_init_step2());
-}
+module_param_array(eisa, int, NULL, 0);
static void release_io_mem(ctlr_info_t *c)
{
}
hba[i]->access.set_intr_mask(hba[i], 0);
if (request_irq(hba[i]->intr, do_ida_intr,
- SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i]))
+ SA_INTERRUPT|SA_SHIRQ|SA_SAMPLE_RANDOM,
+ hba[i]->devname, hba[i]))
{
printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n",
hba[i]->intr, hba[i]->devname);
}
static struct pci_driver cpqarray_pci_driver = {
- name: "cpqarray",
- probe: cpqarray_init_one,
- remove: __devexit_p(cpqarray_remove_one_pci),
- id_table: cpqarray_pci_device_id,
+ .name = "cpqarray",
+ .probe = cpqarray_init_one,
+ .remove = __devexit_p(cpqarray_remove_one_pci),
+ .id_table = cpqarray_pci_device_id,
};
/*
* This is it. Find all the controllers and register them.
* returns the number of block devices registered.
*/
-int __init cpqarray_init_step2(void)
+static int __init cpqarray_init(void)
{
int num_cntlrs_reg = 0;
int i;
/* detect controllers */
printk(DRIVER_NAME "\n");
-/* TODO: If it's an eisa only system, will rc return negative? */
+
rc = pci_register_driver(&cpqarray_pci_driver);
- if (rc < 0)
+ if (rc)
return rc;
cpqarray_eisa_detect();
/*
* Map (physical) PCI mem into (virtual) kernel space
*/
-static void *remap_pci_mem(ulong base, ulong size)
+static void __iomem *remap_pci_mem(ulong base, ulong size)
{
ulong page_base = ((ulong) base) & PAGE_MASK;
ulong page_offs = ((ulong) base) - page_base;
- void *page_remapped = ioremap(page_base, page_offs+size);
+ void __iomem *page_remapped = ioremap(page_base, page_offs+size);
return (page_remapped ? (page_remapped + page_offs) : NULL);
}
#ifndef MODULE
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)
/*
* Config string is a comma separated set of i/o addresses of EISA cards.
*/
__setup("smart2=", cpqarray_setup);
-#else
-
-/*
- * Copy the contents of the ints[] array passed to us by init.
- */
-void cpqarray_setup(char *str, int *ints)
-{
- int i;
- for(i=0; i<ints[0] && i<8; i++)
- eisa[i] = ints[i+1];
-}
-#endif
#endif
/*
*/
static inline void complete_command(cmdlist_t *cmd, int timeout)
{
+ struct request *rq = cmd->rq;
int ok=1;
int i, ddir;
pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
cmd->req.sg[i].size, ddir);
- complete_buffers(cmd->rq->bio, ok);
+ complete_buffers(rq->bio, ok);
+
+ if (blk_fs_request(rq)) {
+ const int rw = rq_data_dir(rq);
+
+ disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+ }
- DBGPX(printk("Done with %p\n", cmd->rq););
- end_that_request_last(cmd->rq);
+ DBGPX(printk("Done with %p\n", rq););
+ end_that_request_last(rq, ok ? 1 : -EIO);
}
/*
h->misc_tflags = 0;
}
+static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ drv_info_t *drv = get_drv(bdev->bd_disk);
+
+ if (drv->cylinders) {
+ geo->heads = drv->heads;
+ geo->sectors = drv->sectors;
+ geo->cylinders = drv->cylinders;
+ } else {
+ geo->heads = 0xff;
+ geo->sectors = 0x3f;
+ geo->cylinders = drv->nr_blks / (0xff*0x3f);
+ }
+
+ return 0;
+}
+
/*
* ida_ioctl does some miscellaneous stuff like reporting drive geometry,
* setting readahead and submitting commands from userspace to the controller.
drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
int error;
- int diskinfo[4];
- struct hd_geometry *geo = (struct hd_geometry *)arg;
- ida_ioctl_t *io = (ida_ioctl_t*)arg;
+ ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
ida_ioctl_t *my_io;
switch(cmd) {
- case HDIO_GETGEO:
- if (drv->cylinders) {
- diskinfo[0] = drv->heads;
- diskinfo[1] = drv->sectors;
- diskinfo[2] = drv->cylinders;
- } else {
- diskinfo[0] = 0xff;
- diskinfo[1] = 0x3f;
- diskinfo[2] = drv->nr_blks / (0xff*0x3f);
- }
- put_user(diskinfo[0], &geo->heads);
- put_user(diskinfo[1], &geo->sectors);
- put_user(diskinfo[2], &geo->cylinders);
- put_user(get_start_sect(inode->i_bdev), &geo->start);
- return 0;
case IDAGETDRVINFO:
if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
return -EFAULT;
if (error)
goto out_passthru;
error = -EFAULT;
- if (copy_to_user(io, &my_io, sizeof(*my_io)))
+ if (copy_to_user(io, my_io, sizeof(*my_io)))
goto out_passthru;
error = 0;
out_passthru:
return error;
case IDAGETCTLRSIG:
if (!arg) return -EINVAL;
- put_user(host->ctlr_sig, (int*)arg);
+ put_user(host->ctlr_sig, (int __user *)arg);
return 0;
case IDAREVALIDATEVOLS:
if (iminor(inode) != 0)
return revalidate_allvol(host);
case IDADRIVERVERSION:
if (!arg) return -EINVAL;
- put_user(DRIVER_VERSION, (unsigned long*)arg);
+ put_user(DRIVER_VERSION, (unsigned long __user *)arg);
return 0;
case IDAGETPCIINFO:
{
pciinfo.bus = host->pci_dev->bus->number;
pciinfo.dev_fn = host->pci_dev->devfn;
pciinfo.board_id = host->board_id;
- if(copy_to_user((void *) arg, &pciinfo,
+ if(copy_to_user((void __user *) arg, &pciinfo,
sizeof( ida_pci_info_struct)))
return -EFAULT;
return(0);
cmd_free(h, c, 0);
return(error);
}
- if (copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size)) {
+ if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
kfree(p);
cmd_free(h, c, 0);
return -EFAULT;
cmd_free(h, c, 0);
return(error);
}
- if (copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size)) {
+ if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
kfree(p);
cmd_free(h, c, 0);
return -EFAULT;
case DIAG_PASS_THRU:
case SENSE_CONTROLLER_PERFORMANCE:
case READ_FLASH_ROM:
- if (copy_to_user((void*)io->sg[0].addr, p, io->sg[0].size)) {
+ if (copy_to_user(io->sg[0].addr, p, io->sg[0].size)) {
kfree(p);
return -EFAULT;
}