aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/gdth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r--drivers/scsi/gdth.c94
1 files changed, 55 insertions, 39 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 35a4b3073ec..0f1ae13ce7c 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -120,7 +120,7 @@
#include <linux/timer.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#ifdef GDTH_RTC
@@ -129,7 +129,6 @@
#include <linux/reboot.h>
#include <asm/dma.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/spinlock.h>
@@ -140,6 +139,7 @@
#include <scsi/scsi_host.h>
#include "gdth.h"
+static DEFINE_MUTEX(gdth_mutex);
static void gdth_delay(int milliseconds);
static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs);
static irqreturn_t gdth_interrupt(int irq, void *dev_id);
@@ -180,11 +180,11 @@ static const char *gdth_ctr_name(gdth_ha_str *ha);
static int gdth_open(struct inode *inode, struct file *filep);
static int gdth_close(struct inode *inode, struct file *filep);
-static int gdth_ioctl(struct inode *inode, struct file *filep,
- unsigned int cmd, unsigned long arg);
+static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd,
+ unsigned long arg);
static void gdth_flush(gdth_ha_str *ha);
-static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
+static int gdth_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
struct gdth_cmndinfo *cmndinfo);
static void gdth_scsi_done(struct scsi_cmnd *scp);
@@ -369,9 +369,10 @@ MODULE_LICENSE("GPL");
/* ioctl interface */
static const struct file_operations gdth_fops = {
- .ioctl = gdth_ioctl,
+ .unlocked_ioctl = gdth_unlocked_ioctl,
.open = gdth_open,
.release = gdth_close,
+ .llseek = noop_llseek,
};
#include "gdth_proc.h"
@@ -589,20 +590,18 @@ static struct pci_driver gdth_pci_driver = {
.remove = gdth_pci_remove_one,
};
-static void __devexit gdth_pci_remove_one(struct pci_dev *pdev)
+static void gdth_pci_remove_one(struct pci_dev *pdev)
{
gdth_ha_str *ha = pci_get_drvdata(pdev);
- pci_set_drvdata(pdev, NULL);
-
list_del(&ha->list);
gdth_remove_one(ha);
pci_disable_device(pdev);
}
-static int __devinit gdth_pci_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int gdth_pci_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
u16 vendor = pdev->vendor;
u16 device = pdev->device;
@@ -854,8 +853,8 @@ static int __init gdth_init_isa(u32 bios_adr,gdth_ha_str *ha)
#endif /* CONFIG_ISA */
#ifdef CONFIG_PCI
-static int __devinit gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
- gdth_ha_str *ha)
+static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
+ gdth_ha_str *ha)
{
register gdt6_dpram_str __iomem *dp6_ptr;
register gdt6c_dpram_str __iomem *dp6c_ptr;
@@ -1106,14 +1105,8 @@ static int __devinit gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
pci_read_config_word(pdev, PCI_COMMAND, &command);
command |= 6;
pci_write_config_word(pdev, PCI_COMMAND, command);
- if (pci_resource_start(pdev, 8) == 1UL)
- pci_resource_start(pdev, 8) = 0UL;
- i = 0xFEFF0001UL;
- pci_write_config_dword(pdev, PCI_ROM_ADDRESS, i);
- gdth_delay(1);
- pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
- pci_resource_start(pdev, 8));
-
+ gdth_delay(1);
+
dp6m_ptr = ha->brd;
/* Ensure that it is safe to access the non HW portions of DPMEM.
@@ -1238,7 +1231,7 @@ static int __devinit gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
/* controller protocol functions */
-static void __devinit gdth_enable_int(gdth_ha_str *ha)
+static void gdth_enable_int(gdth_ha_str *ha)
{
unsigned long flags;
gdt2_dpram_str __iomem *dp2_ptr;
@@ -1554,7 +1547,7 @@ static int gdth_internal_cmd(gdth_ha_str *ha, u8 service, u16 opcode,
/* search for devices */
-static int __devinit gdth_search_drives(gdth_ha_str *ha)
+static int gdth_search_drives(gdth_ha_str *ha)
{
u16 cdev_cnt, i;
int ok;
@@ -2308,10 +2301,10 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
return;
}
local_irq_save(flags);
- address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
+ address = kmap_atomic(sg_page(sl)) + sl->offset;
memcpy(address, buffer, cpnow);
flush_dcache_page(sg_page(sl));
- kunmap_atomic(address, KM_BIO_SRC_IRQ);
+ kunmap_atomic(address);
local_irq_restore(flags);
if (cpsum == cpcount)
break;
@@ -3842,7 +3835,7 @@ int __init option_setup(char *str)
TRACE2(("option_setup() str %s\n", str ? str:"NULL"));
- while (cur && isdigit(*cur) && i <= MAXHA) {
+ while (cur && isdigit(*cur) && i < MAXHA) {
ints[i++] = simple_strtoul(cur, NULL, 0);
if ((cur = strchr(cur, ',')) != NULL) cur++;
}
@@ -4002,7 +3995,7 @@ static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,se
}
-static int gdth_queuecommand(struct scsi_cmnd *scp,
+static int gdth_queuecommand_lck(struct scsi_cmnd *scp,
void (*done)(struct scsi_cmnd *))
{
gdth_ha_str *ha = shost_priv(scp->device->host);
@@ -4020,6 +4013,8 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
return __gdth_queuecommand(ha, scp, cmndinfo);
}
+static DEF_SCSI_QCMD(gdth_queuecommand)
+
static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
struct gdth_cmndinfo *cmndinfo)
{
@@ -4042,12 +4037,12 @@ static int gdth_open(struct inode *inode, struct file *filep)
{
gdth_ha_str *ha;
- lock_kernel();
+ mutex_lock(&gdth_mutex);
list_for_each_entry(ha, &gdth_instances, list) {
if (!ha->sdev)
ha->sdev = scsi_get_host_dev(ha->shost);
}
- unlock_kernel();
+ mutex_unlock(&gdth_mutex);
TRACE(("gdth_open()\n"));
return 0;
@@ -4175,6 +4170,14 @@ static int ioc_general(void __user *arg, char *cmnd)
ha = gdth_find_ha(gen.ionode);
if (!ha)
return -EFAULT;
+
+ if (gen.data_len > INT_MAX)
+ return -EINVAL;
+ if (gen.sense_len > INT_MAX)
+ return -EINVAL;
+ if (gen.data_len + gen.sense_len > INT_MAX)
+ return -EINVAL;
+
if (gen.data_len + gen.sense_len != 0) {
if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len,
FALSE, &paddr)))
@@ -4261,8 +4264,10 @@ static int ioc_general(void __user *arg, char *cmnd)
}
rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info);
- if (rval < 0)
+ if (rval < 0) {
+ gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
return rval;
+ }
gen.status = rval;
if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf,
@@ -4462,8 +4467,7 @@ free_fail:
return rc;
}
-static int gdth_ioctl(struct inode *inode, struct file *filep,
- unsigned int cmd, unsigned long arg)
+static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
gdth_ha_str *ha;
Scsi_Cmnd *scp;
@@ -4611,6 +4615,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
return 0;
}
+static long gdth_unlocked_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+
+ mutex_lock(&gdth_mutex);
+ ret = gdth_ioctl(file, cmd, arg);
+ mutex_unlock(&gdth_mutex);
+
+ return ret;
+}
/* flush routine */
static void gdth_flush(gdth_ha_str *ha)
@@ -4659,7 +4674,8 @@ static struct scsi_host_template gdth_template = {
.eh_bus_reset_handler = gdth_eh_bus_reset,
.slave_configure = gdth_slave_configure,
.bios_param = gdth_bios_param,
- .proc_info = gdth_proc_info,
+ .show_info = gdth_show_info,
+ .write_info = gdth_set_info,
.eh_timed_out = gdth_timed_out,
.proc_name = "gdth",
.can_queue = GDTH_MAXCMDS,
@@ -4668,6 +4684,7 @@ static struct scsi_host_template gdth_template = {
.cmd_per_lun = GDTH_MAXC_P_L,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .no_write_same = 1,
};
#ifdef CONFIG_ISA
@@ -4694,7 +4711,7 @@ static int __init gdth_isa_probe_one(u32 isa_bios)
printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n",
isa_bios, ha->irq, ha->drq);
- error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha);
+ error = request_irq(ha->irq, gdth_interrupt, 0, "gdth", ha);
if (error) {
printk("GDT-ISA: Unable to allocate IRQ\n");
goto out_host_put;
@@ -4826,7 +4843,7 @@ static int __init gdth_eisa_probe_one(u16 eisa_slot)
printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
eisa_slot >> 12, ha->irq);
- error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha);
+ error = request_irq(ha->irq, gdth_interrupt, 0, "gdth", ha);
if (error) {
printk("GDT-EISA: Unable to allocate IRQ\n");
goto out_host_put;
@@ -4904,7 +4921,7 @@ static int __init gdth_eisa_probe_one(u16 eisa_slot)
error = scsi_add_host(shp, NULL);
if (error)
- goto out_free_coal_stat;
+ goto out_free_ccb_phys;
list_add_tail(&ha->list, &gdth_instances);
gdth_timer_init();
@@ -4936,8 +4953,7 @@ static int __init gdth_eisa_probe_one(u16 eisa_slot)
#endif /* CONFIG_EISA */
#ifdef CONFIG_PCI
-static int __devinit gdth_pci_probe_one(gdth_pci_str *pcistr,
- gdth_ha_str **ha_out)
+static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
{
struct Scsi_Host *shp;
gdth_ha_str *ha;
@@ -4963,7 +4979,7 @@ static int __devinit gdth_pci_probe_one(gdth_pci_str *pcistr,
ha->irq);
error = request_irq(ha->irq, gdth_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "gdth", ha);
+ IRQF_SHARED, "gdth", ha);
if (error) {
printk("GDT-PCI: Unable to allocate IRQ\n");
goto out_host_put;