patch-2.2.0-pre7 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: 601
- Date:
Mon Jan 11 10:17:20 1999
- Orig file:
v2.2.0-pre6/linux/drivers/scsi/gdth_proc.c
- Orig date:
Mon Feb 23 18:12:07 1998
diff -u --recursive --new-file v2.2.0-pre6/linux/drivers/scsi/gdth_proc.c linux/drivers/scsi/gdth_proc.c
@@ -1,5 +1,5 @@
/* gdth_proc.c
- * $Id: gdth_proc.c,v 1.6 1997/10/31 10:36:24 achim Exp $
+ * $Id: gdth_proc.c,v 1.11 1998/12/17 15:52:35 achim Exp $
*/
#include "gdth_ioctl.h"
@@ -10,7 +10,7 @@
int hanum,busnum,i;
TRACE2(("gdth_proc_info() length %d ha %d offs %d inout %d\n",
- length,hostno,offset,inout));
+ length,hostno,(int)offset,inout));
for (i=0; i<gdth_ctr_vcount; ++i) {
if (gdth_ctr_vtab[i]->host_no == hostno)
@@ -69,7 +69,7 @@
{
int orig_length, drive, wb_mode;
char cmnd[12];
- int i, j, found;
+ int i, found;
gdth_ha_str *ha;
gdth_cmd_str gdtcmd;
gdth_cpar_str *pcpar;
@@ -96,28 +96,28 @@
} else {
printk("GDT: Flushing all host drives .. ");
}
- for (i = 0; i < MAXBUS; ++i) {
- for (j = 0; j < MAXID; ++j) {
- if (ha->id[i][j].type == CACHE_DTYP) {
- if (drive != -1 &&
- ha->id[i][j].hostdrive != (ushort)drive)
- continue;
- found = TRUE;
- gdtcmd.BoardNode = LOCALBOARD;
- gdtcmd.Service = CACHESERVICE;
- gdtcmd.OpCode = GDT_FLUSH;
- gdtcmd.u.cache.DeviceNo = ha->id[i][j].hostdrive;
- gdtcmd.u.cache.BlockNo = 1;
- gdtcmd.u.cache.sg_canz = 0;
- {
- struct semaphore sem = MUTEX_LOCKED;
- scp.request.rq_status = RQ_SCSI_BUSY;
- scp.request.sem = &sem;
- scsi_do_cmd(&scp, cmnd, &gdtcmd,
- sizeof(gdth_cmd_str), gdth_scsi_done,
- 30*HZ, 1);
- down(&sem);
- }
+ for (i = 0; i < MAX_HDRIVES; ++i) {
+ if (ha->hdr[i].present) {
+ if (drive != -1 && i != drive)
+ continue;
+ found = TRUE;
+ gdtcmd.BoardNode = LOCALBOARD;
+ gdtcmd.Service = CACHESERVICE;
+ gdtcmd.OpCode = GDT_FLUSH;
+ gdtcmd.u.cache.DeviceNo = i;
+ gdtcmd.u.cache.BlockNo = 1;
+ gdtcmd.u.cache.sg_canz = 0;
+ {
+ struct semaphore sem = MUTEX_LOCKED;
+ scp.request.rq_status = RQ_SCSI_BUSY;
+ scp.request.sem = &sem;
+ scp.SCp.this_residual = IOCTL_PRI;
+ GDTH_LOCK_SCSI_DOCMD();
+ scsi_do_cmd(&scp, cmnd, &gdtcmd,
+ sizeof(gdth_cmd_str), gdth_scsi_done,
+ 30*HZ, 1);
+ GDTH_UNLOCK_SCSI_DOCMD();
+ down(&sem);
}
}
}
@@ -179,8 +179,11 @@
struct semaphore sem = MUTEX_LOCKED;
scp.request.rq_status = RQ_SCSI_BUSY;
scp.request.sem = &sem;
+ scp.SCp.this_residual = IOCTL_PRI;
+ GDTH_LOCK_SCSI_DOCMD();
scsi_do_cmd(&scp, cmnd, &gdtcmd, sizeof(gdth_cmd_str),
gdth_scsi_done, 30*HZ, 1);
+ GDTH_UNLOCK_SCSI_DOCMD();
down(&sem);
}
kfree( pcpar );
@@ -195,15 +198,13 @@
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
{
char cmnd[12];
- int id;
- unchar i, j, k, found;
+ unchar i, j;
gdth_ha_str *ha;
gdth_iowr_str *piowr;
gdth_iord_str *piord;
gdth_cmd_str *pcmd;
- ulong *ppadd;
- ulong add_size, flags;
-
+ ulong32 *ppadd, add_size;
+ ulong flags;
TRACE2(("gdth_set_bin_info() ha %d\n",hanum));
ha = HADATA(gdth_ctr_tab[hanum]);
@@ -228,7 +229,7 @@
add_size = pcmd->u.cache.BlockCnt * SECTOR_SIZE;
if (ha->cache_feat & SCATTER_GATHER) {
ppadd = &pcmd->u.cache.sg_lst[0].sg_ptr;
- pcmd->u.cache.DestAddr = -1UL;
+ pcmd->u.cache.DestAddr = 0xffffffff;
pcmd->u.cache.sg_lst[0].sg_len = add_size;
pcmd->u.cache.sg_canz = 1;
} else {
@@ -239,7 +240,7 @@
add_size = pcmd->u.raw.sdlen;
if (ha->raw_feat & SCATTER_GATHER) {
ppadd = &pcmd->u.raw.sg_lst[0].sg_ptr;
- pcmd->u.raw.sdata = -1UL;
+ pcmd->u.raw.sdata = 0xffffffff;
pcmd->u.raw.sg_lst[0].sg_len = add_size;
pcmd->u.raw.sg_ranz = 1;
} else {
@@ -249,10 +250,9 @@
} else {
return(-EINVAL);
}
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) + add_size );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) + add_size ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str) + add_size;
if (add_size > 0) {
@@ -265,33 +265,33 @@
scp.request.rq_status = RQ_SCSI_BUSY;
scp.request.sem = &sem;
scp.SCp.this_residual = IOCTL_PRI;
+ GDTH_LOCK_SCSI_DOCMD();
scsi_do_cmd(&scp, cmnd, pcmd,
sizeof(gdth_cmd_str), gdth_scsi_done,
piowr->timeout*HZ, 1);
+ GDTH_UNLOCK_SCSI_DOCMD();
down(&sem);
- piord->status = (ulong)scp.SCp.Message;
+ piord->status = (ulong32)scp.SCp.Message;
}
break;
case GDTIOCTL_DRVERS:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
piord->iu.drvers.version = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
break;
case GDTIOCTL_CTRTYPE:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ 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) - 10);
+ 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 {
@@ -303,20 +303,18 @@
break;
case GDTIOCTL_CTRCNT:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
piord->iu.ctrcnt.count = (ushort)gdth_ctr_count;
break;
case GDTIOCTL_OSVERS:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
piord->iu.osvers.version = (unchar)(LINUX_VERSION_CODE >> 16);
@@ -325,39 +323,24 @@
break;
case GDTIOCTL_LOCKDRV:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
- for (i = k = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
- found = FALSE;
- for (j = 0; j < ha->bus_cnt; ++j) {
- for (k = 0; k < MAXID; ++k) {
- if (ha->id[j][k].type == CACHE_DTYP &&
- ha->id[j][k].hostdrive == piowr->iu.lockdrv.drives[i]) {
- found = TRUE;
- break;
- }
- }
- if (found)
- break;
- }
- if (!found)
+ piord = (gdth_iord_str *)ha->pscratch;
+ for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
+ j = piowr->iu.lockdrv.drives[i];
+ if (j >= MAX_HDRIVES || !ha->hdr[j].present)
continue;
-
if (piowr->iu.lockdrv.lock) {
- save_flags( flags );
- cli();
- ha->id[j][k].lock = 1;
- restore_flags( flags );
- gdth_wait_completion( hanum, j, k );
- gdth_stop_timeout( hanum, j, k );
+ GDTH_LOCK_HA(ha, flags);
+ ha->hdr[j].lock = 1;
+ GDTH_UNLOCK_HA(ha, flags);
+ gdth_wait_completion( hanum, ha->bus_cnt, j );
+ gdth_stop_timeout( hanum, ha->bus_cnt, j );
} else {
- save_flags( flags );
- cli();
- ha->id[j][k].lock = 0;
- restore_flags( flags );
- gdth_start_timeout( hanum, j, k );
+ GDTH_LOCK_HA(ha, flags);
+ ha->hdr[j].lock = 0;
+ GDTH_UNLOCK_HA(ha, flags);
+ gdth_start_timeout( hanum, ha->bus_cnt, j );
gdth_next( hanum );
}
}
@@ -366,46 +349,54 @@
break;
case GDTIOCTL_LOCKCHN:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- for (k = 0, j = piowr->iu.lockchn.channel; k < MAXID; ++k) {
- if (ha->id[j][k].type != RAW_DTYP)
- continue;
-
+ i = piowr->iu.lockchn.channel;
+ if (i < ha->bus_cnt) {
if (piowr->iu.lockchn.lock) {
- save_flags( flags );
- cli();
- ha->id[j][k].lock = 1;
- restore_flags( flags );
- gdth_wait_completion( hanum, j, k );
- gdth_stop_timeout( hanum, j, k );
+ GDTH_LOCK_HA(ha, flags);
+ ha->raw[i].lock = 1;
+ GDTH_UNLOCK_HA(ha, flags);
+ for (j = 0; j < ha->tid_cnt; ++j) {
+ gdth_wait_completion( hanum, i, j );
+ gdth_stop_timeout( hanum, i, j );
+ }
} else {
- save_flags( flags );
- cli();
- ha->id[j][k].lock = 0;
- restore_flags( flags );
- gdth_start_timeout( hanum, j, k );
- gdth_next( hanum );
+ GDTH_LOCK_HA(ha, flags);
+ ha->raw[i].lock = 0;
+ GDTH_UNLOCK_HA(ha, flags);
+ for (j = 0; j < ha->tid_cnt; ++j) {
+ gdth_start_timeout( hanum, i, j );
+ gdth_next( hanum );
+ }
}
}
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
break;
case GDTIOCTL_EVENT:
- id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
- if (id == -1)
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
return(-EBUSY);
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
- if (piowr->iu.event.erase == 0) {
- piord->iu.event.handle = gdth_read_event( piowr->iu.event.handle,
- (gdth_evt_str *)piord->iu.event.evt );
+ piord = (gdth_iord_str *)ha->pscratch;
+ if (piowr->iu.event.erase == 0xff) {
+ gdth_store_event(ha,
+ ((gdth_evt_str *)piowr->iu.event.evt)->event_source,
+ ((gdth_evt_str *)piowr->iu.event.evt)->event_idx,
+ &((gdth_evt_str *)piowr->iu.event.evt)->event_data);
+ if (((gdth_evt_str *)piowr->iu.event.evt)->event_source == ES_ASYNC)
+ gdth_log_event(&((gdth_evt_str *)piowr->iu.event.evt)->event_data);
+ } else if (piowr->iu.event.erase == 0xfe) {
+ gdth_clear_events();
+ } else if (piowr->iu.event.erase == 0) {
+ piord->iu.event.handle =
+ gdth_read_event(ha,piowr->iu.event.handle,
+ (gdth_evt_str *)piord->iu.event.evt);
} else {
piord->iu.event.handle = piowr->iu.event.handle;
- gdth_readapp_event( (unchar)piowr->iu.event.erase,
- (gdth_evt_str *)piord->iu.event.evt );
+ gdth_readapp_event(ha, (unchar)piowr->iu.event.erase,
+ (gdth_evt_str *)piord->iu.event.evt);
}
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
@@ -415,7 +406,7 @@
return(-EINVAL);
}
/* we return a buffer ID to detect the right buffer during READ-IOCTL */
- return id;
+ return 1;
}
static int gdth_get_info(char *buffer,char **start,off_t offset,
@@ -432,15 +423,15 @@
id = length;
/* look for buffer ID in length */
- if (id > 4) {
+ if (id > 1) {
#if LINUX_VERSION_CODE >= 0x020000
size = sprintf(buffer+len,
- "%s SCSI Disk Array Controller\n",
- gdth_ctr_name(hanum));
+ "%s Disk Array Controller\n",
+ ha->ctr_name);
#else
size = sprintf(buffer+len,
- "%s SCSI Disk Array Controller (SCSI Bus %d)\n",
- gdth_ctr_name(hanum),busnum);
+ "%s Disk Array Controller (Bus %d)\n",
+ ha->ctr_name,busnum);
#endif
len += size; pos = begin + len;
size = sprintf(buffer+len,
@@ -457,12 +448,12 @@
goto stop_output;
} else {
- piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
+ piord = (gdth_iord_str *)ha->pscratch;
if (piord == NULL)
goto stop_output;
length = piord->size;
memcpy(buffer+len, (char *)piord, length);
- gdth_ioctl_free(hanum, id);
+ gdth_ioctl_free(hanum);
len += length; pos = begin + len;
if (pos < offset) {
@@ -479,7 +470,7 @@
if (len > length)
len = length;
TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n",
- len,pos,begin,offset,length,size));
+ len,(int)pos,(int)begin,(int)offset,length,size));
return(len);
}
@@ -496,140 +487,152 @@
static int gdth_ioctl_alloc(int hanum, ushort size)
{
+ gdth_ha_str *ha;
ulong flags;
- int i;
+ int ret_val;
- if (size == 0)
+ if (size == 0 || size > GDTH_SCRATCH)
return -1;
- save_flags(flags);
- cli();
+ ha = HADATA(gdth_ctr_tab[hanum]);
+ GDTH_LOCK_HA(ha, flags);
- for (i = 0; i < 4; ++i) {
- if (gdth_ioctl_tab[i][hanum] == NULL) {
- gdth_ioctl_tab[i][hanum] = kmalloc( size, GFP_ATOMIC | GFP_DMA );
- break;
- }
- }
+ if (!ha->scratch_busy) {
+ ha->scratch_busy = TRUE;
+ ret_val = TRUE;
+ } else
+ ret_val = FALSE;
- restore_flags(flags);
- if (i == 4 || gdth_ioctl_tab[i][hanum] == NULL)
- return -1;
- return (i+1);
+ GDTH_UNLOCK_HA(ha, flags);
+ return ret_val;
}
-static void gdth_ioctl_free(int hanum, int idx)
+static void gdth_ioctl_free(int hanum)
{
+ gdth_ha_str *ha;
ulong flags;
- save_flags(flags);
- cli();
+ ha = HADATA(gdth_ctr_tab[hanum]);
+ GDTH_LOCK_HA(ha, flags);
- kfree( gdth_ioctl_tab[idx-1][hanum] );
- gdth_ioctl_tab[idx-1][hanum] = NULL;
+ ha->scratch_busy = FALSE;
- restore_flags(flags);
+ GDTH_UNLOCK_HA(ha, flags);
}
static void gdth_wait_completion(int hanum, int busnum, int id)
{
+ gdth_ha_str *ha;
ulong flags;
int i;
Scsi_Cmnd *scp;
- save_flags(flags);
- cli();
+ ha = HADATA(gdth_ctr_tab[hanum]);
+ GDTH_LOCK_HA(ha, flags);
for (i = 0; i < GDTH_MAXCMDS; ++i) {
- scp = gdth_cmd_tab[i][hanum].cmnd;
- if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&
+ scp = ha->cmd_tab[i].cmnd;
#if LINUX_VERSION_CODE >= 0x020000
+ if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&
scp->channel == (unchar)busnum)
#else
+ if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&
NUMDATA(scp->host)->busnum == (unchar)busnum)
#endif
{
- restore_flags(flags);
+ scp->SCp.have_data_in = 0;
+ GDTH_UNLOCK_HA(ha, flags);
while (!scp->SCp.have_data_in)
barrier();
- save_flags(flags);
- cli();
+ GDTH_LOCK_SCSI_DONE(flags);
+ scp->scsi_done(scp);
+ GDTH_UNLOCK_SCSI_DONE(flags);
+ GDTH_LOCK_HA(ha, flags);
}
}
- restore_flags(flags);
+ GDTH_UNLOCK_HA(ha, flags);
}
static void gdth_stop_timeout(int hanum, int busnum, int id)
{
+ gdth_ha_str *ha;
ulong flags;
Scsi_Cmnd *scp;
- gdth_ha_str *ha;
- save_flags(flags);
- cli();
ha = HADATA(gdth_ctr_tab[hanum]);
+ GDTH_LOCK_HA(ha, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
- if (scp->target == (unchar)id &&
#if LINUX_VERSION_CODE >= 0x020000
+ if (scp->target == (unchar)id &&
scp->channel == (unchar)busnum)
#else
+ if (scp->target == (unchar)id &&
NUMDATA(scp->host)->busnum == (unchar)busnum)
#endif
{
TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
- scp->SCp.buffers_residual = gdth_update_timeout(scp, 0);
+ scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
}
}
- restore_flags(flags);
+ GDTH_UNLOCK_HA(ha, flags);
}
static void gdth_start_timeout(int hanum, int busnum, int id)
{
+ gdth_ha_str *ha;
ulong flags;
Scsi_Cmnd *scp;
- gdth_ha_str *ha;
- save_flags(flags);
- cli();
ha = HADATA(gdth_ctr_tab[hanum]);
+ GDTH_LOCK_HA(ha, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
- if (scp->target == (unchar)id &&
#if LINUX_VERSION_CODE >= 0x020000
+ if (scp->target == (unchar)id &&
scp->channel == (unchar)busnum)
#else
+ if (scp->target == (unchar)id &&
NUMDATA(scp->host)->busnum == (unchar)busnum)
#endif
{
TRACE2(("gdth_start_timeout(): update_timeout()\n"));
- gdth_update_timeout(scp, scp->SCp.buffers_residual);
+ gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
}
}
- restore_flags(flags);
+ GDTH_UNLOCK_HA(ha, flags);
}
-static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout)
+static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout)
{
- ulong flags;
int oldto;
- save_flags(flags);
- cli();
+ oldto = scp->timeout_per_command;
+ scp->timeout_per_command = timeout;
- oldto = scp->timeout;
- scp->timeout = timeout;
+#if LINUX_VERSION_CODE >= 0x02014B
+ if (timeout == 0) {
+ del_timer(&scp->eh_timeout);
+ scp->eh_timeout.data = (unsigned long) NULL;
+ scp->eh_timeout.expires = 0;
+ } else {
+ if (scp->eh_timeout.data != (unsigned long) NULL)
+ del_timer(&scp->eh_timeout);
+ scp->eh_timeout.data = (unsigned long) scp;
+ scp->eh_timeout.expires = jiffies + timeout;
+ add_timer(&scp->eh_timeout);
+ }
+#else
if (timeout > 0) {
- if (timer_table[GDTH_TIMER].expires == 0) {
- timer_table[GDTH_TIMER].expires = jiffies + timeout;
- timer_active |= 1 << GDTH_TIMER;
+ if (timer_table[SCSI_TIMER].expires == 0) {
+ timer_table[SCSI_TIMER].expires = jiffies + timeout;
+ timer_active |= 1 << SCSI_TIMER;
} else {
- if (jiffies + timeout < timer_table[GDTH_TIMER].expires)
- timer_table[GDTH_TIMER].expires = jiffies + timeout;
+ if (jiffies + timeout < timer_table[SCSI_TIMER].expires)
+ timer_table[SCSI_TIMER].expires = jiffies + timeout;
}
}
+#endif
- restore_flags(flags);
return oldto;
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov