Commit 463563fa authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Martin K. Petersen

scsi: gdth: remove gdth_{alloc,free}_ioctl

Out of the three callers once insists on the scratch buffer, and the
others are fine with a new allocation.  Switch those two to just use
pci_alloc_consistent directly, and open code the scratch buffer
allocation in the remaining one.  This avoids a case where we might
be doing a memory allocation under a spinlock with irqs disabled.

[mkp: typo]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 8d22022c
...@@ -4239,7 +4239,7 @@ static int ioc_general(void __user *arg, char *cmnd) ...@@ -4239,7 +4239,7 @@ static int ioc_general(void __user *arg, char *cmnd)
gdth_ioctl_general gen; gdth_ioctl_general gen;
gdth_ha_str *ha; gdth_ha_str *ha;
char *buf = NULL; char *buf = NULL;
u64 paddr; dma_addr_t paddr;
int rval; int rval;
if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)))
...@@ -4256,8 +4256,8 @@ static int ioc_general(void __user *arg, char *cmnd) ...@@ -4256,8 +4256,8 @@ static int ioc_general(void __user *arg, char *cmnd)
return -EINVAL; return -EINVAL;
if (gen.data_len + gen.sense_len > 0) { if (gen.data_len + gen.sense_len > 0) {
buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, buf = pci_alloc_consistent(ha->pdev,
&paddr); gen.data_len + gen.sense_len, &paddr);
if (!buf) if (!buf)
return -EFAULT; return -EFAULT;
...@@ -4292,7 +4292,7 @@ static int ioc_general(void __user *arg, char *cmnd) ...@@ -4292,7 +4292,7 @@ static int ioc_general(void __user *arg, char *cmnd)
rval = 0; rval = 0;
out_free_buf: out_free_buf:
gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); pci_free_consistent(ha->pdev, gen.data_len + gen.sense_len, buf, paddr);
return rval; return rval;
} }
......
...@@ -31,7 +31,6 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, ...@@ -31,7 +31,6 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
int i, found; int i, found;
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
gdth_cpar_str *pcpar; gdth_cpar_str *pcpar;
u64 paddr;
char cmnd[MAX_COMMAND_SIZE]; char cmnd[MAX_COMMAND_SIZE];
memset(cmnd, 0xff, 12); memset(cmnd, 0xff, 12);
...@@ -113,13 +112,23 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, ...@@ -113,13 +112,23 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
} }
if (wb_mode) { if (wb_mode) {
if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr)) unsigned long flags;
return(-EBUSY);
BUILD_BUG_ON(sizeof(gdth_cpar_str) > GDTH_SCRATCH);
spin_lock_irqsave(&ha->smp_lock, flags);
if (ha->scratch_busy) {
spin_unlock_irqrestore(&ha->smp_lock, flags);
return -EBUSY;
}
ha->scratch_busy = TRUE;
spin_unlock_irqrestore(&ha->smp_lock, flags);
pcpar = (gdth_cpar_str *)ha->pscratch; pcpar = (gdth_cpar_str *)ha->pscratch;
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = paddr; gdtcmd.u.ioctl.p_param = ha->scratch_phys;
gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
gdtcmd.u.ioctl.channel = INVALID_CHANNEL; gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
...@@ -127,7 +136,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, ...@@ -127,7 +136,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
gdth_execute(host, &gdtcmd, cmnd, 30, NULL); gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr); spin_lock_irqsave(&ha->smp_lock, flags);
ha->scratch_busy = FALSE;
spin_unlock_irqrestore(&ha->smp_lock, flags);
printk("Done.\n"); printk("Done.\n");
return(orig_length); return(orig_length);
} }
...@@ -143,7 +155,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host) ...@@ -143,7 +155,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
int id, i, j, k, sec, flag; int id, i, j, k, sec, flag;
int no_mdrv = 0, drv_no, is_mirr; int no_mdrv = 0, drv_no, is_mirr;
u32 cnt; u32 cnt;
u64 paddr; dma_addr_t paddr;
int rc = -ENOMEM; int rc = -ENOMEM;
gdth_cmd_str *gdtcmd; gdth_cmd_str *gdtcmd;
...@@ -232,7 +244,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host) ...@@ -232,7 +244,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
seq_puts(m, "\nPhysical Devices:"); seq_puts(m, "\nPhysical Devices:");
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(ha, size, FALSE, &paddr); buf = pci_alloc_consistent(ha->pdev, size, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < ha->bus_cnt; ++i) { for (i = 0; i < ha->bus_cnt; ++i) {
...@@ -500,7 +512,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host) ...@@ -500,7 +512,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
} }
} }
} }
gdth_ioctl_free(ha, size, buf, paddr); pci_free_consistent(ha->pdev, size, buf, paddr);
for (i = 0; i < MAX_HDRIVES; ++i) { for (i = 0; i < MAX_HDRIVES; ++i) {
if (!(ha->hdr[i].present)) if (!(ha->hdr[i].present))
...@@ -553,47 +565,6 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host) ...@@ -553,47 +565,6 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
return rc; return rc;
} }
static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
u64 *paddr)
{
unsigned long flags;
char *ret_val;
if (size == 0)
return NULL;
spin_lock_irqsave(&ha->smp_lock, flags);
if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
ha->scratch_busy = TRUE;
ret_val = ha->pscratch;
*paddr = ha->scratch_phys;
} else if (scratch) {
ret_val = NULL;
} else {
dma_addr_t dma_addr;
ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr);
*paddr = dma_addr;
}
spin_unlock_irqrestore(&ha->smp_lock, flags);
return ret_val;
}
static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr)
{
unsigned long flags;
if (buf == ha->pscratch) {
spin_lock_irqsave(&ha->smp_lock, flags);
ha->scratch_busy = FALSE;
spin_unlock_irqrestore(&ha->smp_lock, flags);
} else {
pci_free_consistent(ha->pdev, size, buf, paddr);
}
}
#ifdef GDTH_IOCTL_PROC #ifdef GDTH_IOCTL_PROC
static int gdth_ioctl_check_bin(gdth_ha_str *ha, u16 size) static int gdth_ioctl_check_bin(gdth_ha_str *ha, u16 size)
{ {
......
...@@ -12,9 +12,6 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, ...@@ -12,9 +12,6 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
int length, gdth_ha_str *ha); int length, gdth_ha_str *ha);
static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
u64 *paddr);
static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr);
static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id); static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment