patch-2.4.10 linux/drivers/scsi/gdth_proc.c
Next file: linux/drivers/scsi/gdth_proc.h
Previous file: linux/drivers/scsi/gdth_ioctl.h
Back to the patch index
Back to the overall index
- Lines: 443
- Date:
Fri Sep 7 09:28:37 2001
- Orig file:
v2.4.9/linux/drivers/scsi/gdth_proc.c
- Orig date:
Sun Aug 12 13:28:00 2001
diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/gdth_proc.c linux/drivers/scsi/gdth_proc.c
@@ -1,9 +1,11 @@
/* gdth_proc.c
- * $Id: gdth_proc.c,v 1.27 2001/03/14 10:47:00 achim Exp $
+ * $Id: gdth_proc.c,v 1.33 2001/08/10 07:54:39 achim Exp $
*/
#include "gdth_ioctl.h"
+#if LINUX_VERSION_CODE >= 0x020407
#include <linux/completion.h>
+#endif
int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
int hostno,int inout)
@@ -48,7 +50,7 @@
sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
- return -ENOMEM;
+ return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
#else
@@ -176,7 +178,7 @@
}
if (wb_mode) {
- if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str)))
+ if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE))
return(-EBUSY);
pcpar = (gdth_cpar_str *)ha->pscratch;
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
@@ -192,7 +194,7 @@
#else
gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
#endif
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, ha->pscratch);
printk("Done.\n");
return(orig_length);
}
@@ -270,7 +272,8 @@
} else {
return(-EINVAL);
}
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2 ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2,
+ TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
@@ -294,7 +297,7 @@
break;
case GDTIOCTL_DRVERS:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -303,25 +306,33 @@
break;
case GDTIOCTL_CTRTYPE:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
piord->iu.ctrtype.type = (unchar)((ha->stype>>20) - 0x10);
- } else if (ha->type != GDT_PCIMPR) {
- piord->iu.ctrtype.type = (unchar)((ha->stype<<8) + 6);
} else {
- piord->iu.ctrtype.type = 0xfe;
- piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+ if (ha->type != GDT_PCIMPR) {
+ piord->iu.ctrtype.type = (unchar)((ha->stype<<4) + 6);
+ } else {
+ piord->iu.ctrtype.type =
+ (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
+ if (ha->stype >= 0x300)
+ piord->iu.ctrtype.ext_type = 0x6000 | ha->subdevice_id;
+ else
+ piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+ }
+ piord->iu.ctrtype.device_id = ha->stype;
+ piord->iu.ctrtype.sub_device_id = ha->subdevice_id;
}
piord->iu.ctrtype.info = ha->brd_phys;
- piord->iu.ctrtype.oem_id = (ushort)GDT3_ID;
+ piord->iu.ctrtype.oem_id = ha->oem_id;
break;
case GDTIOCTL_CTRCNT:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -330,7 +341,7 @@
break;
case GDTIOCTL_OSVERS:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -341,7 +352,7 @@
break;
case GDTIOCTL_LOCKDRV:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
@@ -367,7 +378,7 @@
break;
case GDTIOCTL_LOCKCHN:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
i = piowr->iu.lockchn.channel;
if (i < ha->bus_cnt) {
@@ -395,7 +406,7 @@
break;
case GDTIOCTL_EVENT:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
if (piowr->iu.event.erase == 0xff) {
@@ -430,7 +441,7 @@
break;
case GDTIOCTL_SCSI:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -451,7 +462,7 @@
break;
case GDTIOCTL_RESET_BUS:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -475,7 +486,7 @@
break;
case GDTIOCTL_HDRLIST:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -509,7 +520,7 @@
break;
case GDTIOCTL_RESCAN:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -635,7 +646,7 @@
break;
case GDTIOCTL_RESET_DRV:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
@@ -684,6 +695,7 @@
char hrec[161];
struct timeval tv;
+ char *buf;
gdth_dskstat_str *pds;
gdth_diskinfo_str *pdi;
gdth_arrayinf_str *pai;
@@ -701,6 +713,8 @@
#if LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
scp = scsi_allocate_device(sdev, 1, FALSE);
+ if (!scp)
+ return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
#else
@@ -784,12 +798,13 @@
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < ha->bus_cnt; ++i) {
/* 2.a statistics (and retries/reassigns) */
TRACE2(("pdr_statistics() chn %d\n",i));
- pds = (gdth_dskstat_str *)(ha->pscratch + GDTH_SCRATCH/4);
+ pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pds);
@@ -819,7 +834,7 @@
/* 2.b drive info */
TRACE2(("scsi_drv_info() chn %d dev %d\n",
i, ha->raw[i].id_list[j]));
- pdi = (gdth_diskinfo_str *)ha->pscratch;
+ pdi = (gdth_diskinfo_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pdi);
@@ -874,7 +889,7 @@
/* 2.c grown defects */
TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
i, ha->raw[i].id_list[j]));
- pdef = (gdth_defcnt_str *)ha->pscratch;
+ pdef = (gdth_defcnt_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pdef);
@@ -905,7 +920,7 @@
goto stop_output;
}
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
if (!flag) {
size = sprintf(buffer+len, "\n --\n");
@@ -917,7 +932,8 @@
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!ha->hdr[i].is_logdrv)
@@ -928,7 +944,7 @@
do {
/* 3.a log. drive info */
TRACE2(("cache_drv_info() drive no %d\n",drv_no));
- pcdi = (gdth_cdrinfo_str *)ha->pscratch;
+ pcdi = (gdth_cdrinfo_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pcdi);
@@ -1018,7 +1034,7 @@
if (pos > offset + length)
goto stop_output;
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
if (!flag) {
size = sprintf(buffer+len, "\n --\n");
@@ -1030,14 +1046,15 @@
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
continue;
/* 4.a array drive info */
TRACE2(("array_info() drive no %d\n",i));
- pai = (gdth_arrayinf_str *)ha->pscratch;
+ pai = (gdth_arrayinf_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pai);
@@ -1095,7 +1112,7 @@
goto stop_output;
}
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
if (!flag) {
size = sprintf(buffer+len, "\n --\n");
@@ -1107,7 +1124,8 @@
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!ha->hdr[i].is_logdrv ||
@@ -1115,7 +1133,7 @@
continue;
/* 5.a get host drive list */
TRACE2(("host_get() drv_no %d\n",i));
- phg = (gdth_hget_str *)ha->pscratch;
+ phg = (gdth_hget_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(phg);
@@ -1146,7 +1164,7 @@
}
}
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
for (i = 0; i < MAX_HDRIVES; ++i) {
if (!(ha->hdr[i].present))
@@ -1210,7 +1228,7 @@
goto stop_output;
length = piord->size;
memcpy(buffer+len, (char *)piord, length);
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, ha->pscratch);
len = length;
}
@@ -1232,7 +1250,13 @@
char *cmnd, int timeout)
{
unsigned bufflen;
+#if LINUX_VERSION_CODE >= 0x020407
DECLARE_COMPLETION(wait);
+#elif LINUX_VERSION_CODE >= 0x020322
+ DECLARE_MUTEX_LOCKED(sem);
+#else
+ struct semaphore sem = MUTEX_LOCKED;
+#endif
TRACE2(("gdth_do_cmd()\n"));
if (gdtcmd != NULL) {
@@ -1243,7 +1267,12 @@
bufflen = 0;
}
scp->request.rq_status = RQ_SCSI_BUSY;
+#if LINUX_VERSION_CODE >= 0x020407
scp->request.waiting = &wait;
+ scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
+ wait_for_completion(&wait);
+#else
+ scp->request.sem = &sem;
#if LINUX_VERSION_CODE >= 0x020322
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
#else
@@ -1251,7 +1280,8 @@
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
GDTH_UNLOCK_SCSI_DOCMD();
#endif
- wait_for_completion(&wait);
+ down(&sem);
+#endif
}
void gdth_scsi_done(Scsi_Cmnd *scp)
@@ -1260,15 +1290,20 @@
scp->request.rq_status = RQ_SCSI_DONE;
+#if LINUX_VERSION_CODE >= 0x020407
if (scp->request.waiting != NULL)
complete(scp->request.waiting);
+#else
+ if (scp->request.sem != NULL)
+ up(scp->request.sem);
+#endif
}
-static int gdth_ioctl_alloc(int hanum, ushort size)
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
{
gdth_ha_str *ha;
ulong flags;
- int ret_val;
+ char *ret_val;
if (size == 0 || size > GDTH_SCRATCH)
return FALSE;
@@ -1276,17 +1311,26 @@
ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags);
- if (!ha->scratch_busy) {
- ha->scratch_busy = TRUE;
- ret_val = TRUE;
- } else
- ret_val = FALSE;
+ if (scratch) {
+ if (!ha->scratch_busy) {
+ ha->scratch_busy = TRUE;
+ ret_val = ha->pscratch;
+ } else
+ ret_val = NULL;
+ } else {
+#if LINUX_VERSION_CODE >= 0x020322
+ ret_val = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA,
+ GDTH_SCRATCH_ORD);
+#else
+ ret_val = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+#endif
+ }
GDTH_UNLOCK_HA(ha, flags);
return ret_val;
}
-static void gdth_ioctl_free(int hanum)
+static void gdth_ioctl_free(int hanum, char *buf)
{
gdth_ha_str *ha;
ulong flags;
@@ -1294,7 +1338,15 @@
ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags);
- ha->scratch_busy = FALSE;
+ if (buf == ha->pscratch) {
+ ha->scratch_busy = FALSE;
+ } else {
+#if LINUX_VERSION_CODE >= 0x020322
+ free_pages((unsigned long)buf, GDTH_SCRATCH_ORD);
+#else
+ scsi_init_free((void *)buf, GDTH_SCRATCH);
+#endif
+ }
GDTH_UNLOCK_HA(ha, flags);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)