OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [scsi/] [gdth_proc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* gdth_proc.c
2
 * $Id: gdth_proc.c,v 1.1.1.1 2001-09-10 07:44:33 simons Exp $
3
 */
4
 
5
#include "gdth_ioctl.h"
6
 
7
int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
8
                   int hostno,int inout)
9
{
10
    int hanum,busnum,i;
11
 
12
    TRACE2(("gdth_proc_info() length %d ha %d offs %d inout %d\n",
13
            length,hostno,(int)offset,inout));
14
 
15
    for (i=0; i<gdth_ctr_vcount; ++i) {
16
        if (gdth_ctr_vtab[i]->host_no == hostno)
17
            break;
18
    }
19
    if (i==gdth_ctr_vcount)
20
        return(-EINVAL);
21
 
22
    hanum = NUMDATA(gdth_ctr_vtab[i])->hanum;
23
    busnum= NUMDATA(gdth_ctr_vtab[i])->busnum;
24
 
25
    if (inout)
26
        return(gdth_set_info(buffer,length,i,hanum,busnum));
27
    else
28
        return(gdth_get_info(buffer,start,offset,length,i,hanum,busnum));
29
}
30
 
31
static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
32
{
33
    int             ret_val;
34
    Scsi_Cmnd       scp;
35
    Scsi_Device     sdev;
36
    gdth_iowr_str   *piowr;
37
 
38
    TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
39
    piowr = (gdth_iowr_str *)buffer;
40
 
41
    memset(&sdev,0,sizeof(Scsi_Device));
42
    memset(&scp, 0,sizeof(Scsi_Cmnd));
43
    sdev.host = gdth_ctr_vtab[vh];
44
    sdev.id = sdev.host->this_id;
45
    scp.cmd_len = 12;
46
    scp.host = gdth_ctr_vtab[vh];
47
    scp.target = sdev.host->this_id;
48
    scp.device = &sdev;
49
    scp.use_sg = 0;
50
 
51
    if (length >= 4) {
52
        if (strncmp(buffer,"gdth",4) == 0) {
53
            buffer += 5;
54
            length -= 5;
55
            ret_val = gdth_set_asc_info( buffer, length, hanum, scp );
56
        } else if (piowr->magic == GDTIOCTL_MAGIC) {
57
            ret_val = gdth_set_bin_info( buffer, length, hanum, scp );
58
        } else {
59
            printk("GDT: Wrong signature: %6s\n",buffer);
60
            ret_val = -EINVAL;
61
        }
62
    } else {
63
        ret_val = -EINVAL;
64
    }
65
    return ret_val;
66
}
67
 
68
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
69
{
70
    int             orig_length, drive, wb_mode;
71
    char            cmnd[12];
72
    int             i, j, found;
73
    gdth_ha_str     *ha;
74
    gdth_cmd_str    gdtcmd;
75
    gdth_cpar_str   *pcpar;
76
 
77
    TRACE2(("gdth_set_asc_info() ha %d\n",hanum));
78
    ha = HADATA(gdth_ctr_tab[hanum]);
79
    memset(cmnd, 0,10);
80
    orig_length = length + 5;
81
    drive = -1;
82
    wb_mode = 0;
83
    found = FALSE;
84
 
85
    if (length >= 5 && strncmp(buffer,"flush",5)==0) {
86
        buffer += 6;
87
        length -= 6;
88
        if (length && *buffer>='0' && *buffer<='9') {
89
            drive = (int)(*buffer-'0');
90
            ++buffer; --length;
91
            if (length && *buffer>='0' && *buffer<='9') {
92
                drive = drive*10 + (int)(*buffer-'0');
93
                ++buffer; --length;
94
            }
95
            printk("GDT: Flushing host drive %d .. ",drive);
96
        } else {
97
            printk("GDT: Flushing all host drives .. ");
98
        }
99
        for (i = 0; i < MAXBUS; ++i) {
100
            for (j = 0; j < MAXID; ++j) {
101
                if (ha->id[i][j].type == CACHE_DTYP) {
102
                    if (drive != -1 &&
103
                        ha->id[i][j].hostdrive != (ushort)drive)
104
                        continue;
105
                    found = TRUE;
106
                    gdtcmd.BoardNode = LOCALBOARD;
107
                    gdtcmd.Service = CACHESERVICE;
108
                    gdtcmd.OpCode = GDT_FLUSH;
109
                    gdtcmd.u.cache.DeviceNo = ha->id[i][j].hostdrive;
110
                    gdtcmd.u.cache.BlockNo = 1;
111
                    gdtcmd.u.cache.sg_canz = 0;
112
                    {
113
                        struct semaphore sem = MUTEX_LOCKED;
114
                        scp.request.rq_status = RQ_SCSI_BUSY;
115
                        scp.request.sem = &sem;
116
                        scp.SCp.this_residual = IOCTL_PRI;
117
                        scsi_do_cmd(&scp, cmnd, &gdtcmd,
118
                                    sizeof(gdth_cmd_str), gdth_scsi_done,
119
                                    30*HZ, 1);
120
                        down(&sem);
121
                    }
122
                }
123
            }
124
        }
125
        if (!found)
126
            printk("\nNo host drive found !\n");
127
        else
128
            printk("Done.\n");
129
        return(orig_length);
130
    }
131
 
132
    if (length >= 7 && strncmp(buffer,"wbp_off",7)==0) {
133
        buffer += 8;
134
        length -= 8;
135
        printk("GDT: Disabling write back permanently .. ");
136
        wb_mode = 1;
137
    } else if (length >= 6 && strncmp(buffer,"wbp_on",6)==0) {
138
        buffer += 7;
139
        length -= 7;
140
        printk("GDT: Enabling write back permanently .. ");
141
        wb_mode = 2;
142
    } else if (length >= 6 && strncmp(buffer,"wb_off",6)==0) {
143
        buffer += 7;
144
        length -= 7;
145
        printk("GDT: Disabling write back commands .. ");
146
        if (ha->cache_feat & GDT_WR_THROUGH) {
147
            gdth_write_through = TRUE;
148
            printk("Done.\n");
149
        } else {
150
            printk("Not supported !\n");
151
        }
152
        return(orig_length);
153
    } else if (length >= 5 && strncmp(buffer,"wb_on",5)==0) {
154
        buffer += 6;
155
        length -= 6;
156
        printk("GDT: Enabling write back commands .. ");
157
        gdth_write_through = FALSE;
158
        printk("Done.\n");
159
        return(orig_length);
160
    }
161
 
162
    if (wb_mode) {
163
        pcpar = (gdth_cpar_str *)kmalloc( sizeof(gdth_cpar_str),
164
            GFP_ATOMIC | GFP_DMA );
165
        if (pcpar == NULL) {
166
            TRACE2(("gdth_set_info(): Unable to allocate memory.\n"));
167
            printk("Unable to allocate memory.\n");
168
            return(-EINVAL);
169
        }
170
        memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
171
        gdtcmd.BoardNode = LOCALBOARD;
172
        gdtcmd.Service = CACHESERVICE;
173
        gdtcmd.OpCode = GDT_IOCTL;
174
        gdtcmd.u.ioctl.p_param = virt_to_bus(pcpar);
175
        gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
176
        gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
177
        gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
178
        pcpar->write_back = wb_mode==1 ? 0:1;
179
        {
180
            struct semaphore sem = MUTEX_LOCKED;
181
            scp.request.rq_status = RQ_SCSI_BUSY;
182
            scp.request.sem = &sem;
183
            scp.SCp.this_residual = IOCTL_PRI;
184
            scsi_do_cmd(&scp, cmnd, &gdtcmd, sizeof(gdth_cmd_str),
185
                        gdth_scsi_done, 30*HZ, 1);
186
            down(&sem);
187
        }
188
        kfree( pcpar );
189
        printk("Done.\n");
190
        return(orig_length);
191
    }
192
 
193
    printk("GDT: Unknown command: %s  Length: %d\n",buffer,length);
194
    return(-EINVAL);
195
}
196
 
197
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
198
{
199
    char            cmnd[12];
200
    int             id;
201
    unchar          i, j, k, found;
202
    gdth_ha_str     *ha;
203
    gdth_iowr_str   *piowr;
204
    gdth_iord_str   *piord;
205
    gdth_cmd_str    *pcmd;
206
    ulong           *ppadd;
207
    ulong           add_size, flags;
208
 
209
 
210
    TRACE2(("gdth_set_bin_info() ha %d\n",hanum));
211
    ha = HADATA(gdth_ctr_tab[hanum]);
212
    memset(cmnd, 0,10);
213
    piowr = (gdth_iowr_str *)buffer;
214
    piord = NULL;
215
    pcmd = NULL;
216
 
217
    if (length < GDTOFFSOF(gdth_iowr_str,iu))
218
        return(-EINVAL);
219
 
220
    switch (piowr->ioctl) {
221
      case GDTIOCTL_GENERAL:
222
        if (length < GDTOFFSOF(gdth_iowr_str,iu.general.data[0]))
223
            return(-EINVAL);
224
        pcmd = (gdth_cmd_str *)piowr->iu.general.command;
225
        pcmd->Service = piowr->service;
226
        if (pcmd->OpCode == GDT_IOCTL) {
227
            ppadd = &pcmd->u.ioctl.p_param;
228
            add_size = pcmd->u.ioctl.param_size;
229
        } else if (piowr->service == CACHESERVICE) {
230
            add_size = pcmd->u.cache.BlockCnt * SECTOR_SIZE;
231
            if (ha->cache_feat & SCATTER_GATHER) {
232
                ppadd = &pcmd->u.cache.sg_lst[0].sg_ptr;
233
                pcmd->u.cache.DestAddr = -1UL;
234
                pcmd->u.cache.sg_lst[0].sg_len = add_size;
235
                pcmd->u.cache.sg_canz = 1;
236
            } else {
237
                ppadd = &pcmd->u.cache.DestAddr;
238
                pcmd->u.cache.sg_canz = 0;
239
            }
240
        } else if (piowr->service == SCSIRAWSERVICE) {
241
            add_size = pcmd->u.raw.sdlen;
242
            if (ha->raw_feat & SCATTER_GATHER) {
243
                ppadd = &pcmd->u.raw.sg_lst[0].sg_ptr;
244
                pcmd->u.raw.sdata = -1UL;
245
                pcmd->u.raw.sg_lst[0].sg_len = add_size;
246
                pcmd->u.raw.sg_ranz = 1;
247
            } else {
248
                ppadd = &pcmd->u.raw.sdata;
249
                pcmd->u.raw.sg_ranz = 0;
250
            }
251
        } else {
252
            return(-EINVAL);
253
        }
254
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) + add_size );
255
        if (id == -1)
256
            return(-EBUSY);
257
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
258
 
259
        piord->size = sizeof(gdth_iord_str) + add_size;
260
        if (add_size > 0) {
261
            memcpy(piord->iu.general.data, piowr->iu.general.data, add_size);
262
            *ppadd = virt_to_bus(piord->iu.general.data);
263
        }
264
        /* do IOCTL */
265
        {
266
            struct semaphore sem = MUTEX_LOCKED;
267
            scp.request.rq_status = RQ_SCSI_BUSY;
268
            scp.request.sem = &sem;
269
            scp.SCp.this_residual = IOCTL_PRI;
270
            scsi_do_cmd(&scp, cmnd, pcmd,
271
                        sizeof(gdth_cmd_str), gdth_scsi_done,
272
                        piowr->timeout*HZ, 1);
273
            down(&sem);
274
            piord->status = (ulong)scp.SCp.Message;
275
        }
276
        break;
277
 
278
      case GDTIOCTL_DRVERS:
279
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
280
        if (id == -1)
281
            return(-EBUSY);
282
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
283
        piord->size = sizeof(gdth_iord_str);
284
        piord->status = S_OK;
285
        piord->iu.drvers.version = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
286
        break;
287
 
288
      case GDTIOCTL_CTRTYPE:
289
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
290
        if (id == -1)
291
            return(-EBUSY);
292
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
293
        piord->size = sizeof(gdth_iord_str);
294
        piord->status = S_OK;
295
        if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
296
            piord->iu.ctrtype.type = (unchar)((ha->stype>>20) - 0x10);
297
        } else if (ha->type != GDT_PCIMPR) {
298
            piord->iu.ctrtype.type = (unchar)((ha->stype<<8) + 6);
299
        } else {
300
            piord->iu.ctrtype.type = 0xfe;
301
            piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
302
        }
303
        piord->iu.ctrtype.info = ha->brd_phys;
304
        piord->iu.ctrtype.oem_id = (ushort)GDT3_ID;
305
        break;
306
 
307
      case GDTIOCTL_CTRCNT:
308
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
309
        if (id == -1)
310
            return(-EBUSY);
311
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
312
        piord->size = sizeof(gdth_iord_str);
313
        piord->status = S_OK;
314
        piord->iu.ctrcnt.count = (ushort)gdth_ctr_count;
315
        break;
316
 
317
      case GDTIOCTL_OSVERS:
318
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
319
        if (id == -1)
320
            return(-EBUSY);
321
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
322
        piord->size = sizeof(gdth_iord_str);
323
        piord->status = S_OK;
324
        piord->iu.osvers.version = (unchar)(LINUX_VERSION_CODE >> 16);
325
        piord->iu.osvers.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
326
        piord->iu.osvers.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
327
        break;
328
 
329
      case GDTIOCTL_LOCKDRV:
330
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
331
        if (id == -1)
332
            return(-EBUSY);
333
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
334
        for (i = k = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
335
            found = FALSE;
336
            for (j = 0; j < ha->bus_cnt; ++j) {
337
                for (k = 0; k < MAXID; ++k) {
338
                    if (ha->id[j][k].type == CACHE_DTYP &&
339
                        ha->id[j][k].hostdrive == piowr->iu.lockdrv.drives[i]) {
340
                        found = TRUE;
341
                        break;
342
                    }
343
                }
344
                if (found)
345
                    break;
346
            }
347
            if (!found)
348
                continue;
349
 
350
            if (piowr->iu.lockdrv.lock) {
351
                save_flags( flags );
352
                cli();
353
                ha->id[j][k].lock = 1;
354
                restore_flags( flags );
355
                gdth_wait_completion( hanum, j, k );
356
                gdth_stop_timeout( hanum, j, k );
357
            } else {
358
                save_flags( flags );
359
                cli();
360
                ha->id[j][k].lock = 0;
361
                restore_flags( flags );
362
                gdth_start_timeout( hanum, j, k );
363
                gdth_next( hanum );
364
            }
365
        }
366
        piord->size = sizeof(gdth_iord_str);
367
        piord->status = S_OK;
368
        break;
369
 
370
      case GDTIOCTL_LOCKCHN:
371
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
372
        if (id == -1)
373
            return(-EBUSY);
374
        for (k = 0, j = piowr->iu.lockchn.channel; k < MAXID; ++k) {
375
            if (ha->id[j][k].type != RAW_DTYP)
376
                continue;
377
 
378
            if (piowr->iu.lockchn.lock) {
379
                save_flags( flags );
380
                cli();
381
                ha->id[j][k].lock = 1;
382
                restore_flags( flags );
383
                gdth_wait_completion( hanum, j, k );
384
                gdth_stop_timeout( hanum, j, k );
385
            } else {
386
                save_flags( flags );
387
                cli();
388
                ha->id[j][k].lock = 0;
389
                restore_flags( flags );
390
                gdth_start_timeout( hanum, j, k );
391
                gdth_next( hanum );
392
            }
393
        }
394
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
395
        piord->size = sizeof(gdth_iord_str);
396
        piord->status = S_OK;
397
        break;
398
 
399
      case GDTIOCTL_EVENT:
400
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );
401
        if (id == -1)
402
            return(-EBUSY);
403
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
404
        if (piowr->iu.event.erase == 0) {
405
            piord->iu.event.handle = gdth_read_event( piowr->iu.event.handle,
406
                (gdth_evt_str *)piord->iu.event.evt );
407
        } else {
408
            piord->iu.event.handle = piowr->iu.event.handle;
409
            gdth_readapp_event( (unchar)piowr->iu.event.erase,
410
                (gdth_evt_str *)piord->iu.event.evt );
411
        }
412
        piord->size = sizeof(gdth_iord_str);
413
        piord->status = S_OK;
414
        break;
415
 
416
      default:
417
        return(-EINVAL);
418
    }
419
    /* we return a buffer ID to detect the right buffer during READ-IOCTL */
420
    return id;
421
}
422
 
423
static int gdth_get_info(char *buffer,char **start,off_t offset,
424
                         int length,int vh,int hanum,int busnum)
425
{
426
    int size = 0,len = 0;
427
    off_t begin = 0,pos = 0;
428
    gdth_ha_str *ha;
429
    gdth_iord_str *piord;
430
    int id;
431
 
432
    TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));
433
    ha = HADATA(gdth_ctr_tab[hanum]);
434
    id = length;
435
 
436
    /* look for buffer ID in length */
437
    if (id > 4) {
438
#if LINUX_VERSION_CODE >= 0x020000
439
        size = sprintf(buffer+len,
440
                       "%s SCSI Disk Array Controller\n",
441
                       ha->ctr_name);
442
#else
443
        size = sprintf(buffer+len,
444
                       "%s SCSI Disk Array Controller (SCSI Bus %d)\n",
445
                       ha->ctr_name,busnum);
446
#endif
447
        len += size;  pos = begin + len;
448
        size = sprintf(buffer+len,
449
                       "Firmware Version: %d.%2d\tDriver Version: %s\n",
450
                       (unchar)(ha->cpar.version>>8),
451
                       (unchar)(ha->cpar.version),GDTH_VERSION_STR);
452
        len += size;  pos = begin + len;
453
 
454
        if (pos < offset) {
455
            len = 0;
456
            begin = pos;
457
        }
458
        if (pos > offset + length)
459
            goto stop_output;
460
 
461
    } else {
462
        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];
463
        if (piord == NULL)
464
            goto stop_output;
465
        length = piord->size;
466
        memcpy(buffer+len, (char *)piord, length);
467
        gdth_ioctl_free(hanum, id);
468
        len += length; pos = begin + len;
469
 
470
        if (pos < offset) {
471
            len = 0;
472
            begin = pos;
473
        }
474
        if (pos > offset + length)
475
            goto stop_output;
476
    }
477
 
478
stop_output:
479
    *start = buffer +(offset-begin);
480
    len -= (offset-begin);
481
    if (len > length)
482
        len = length;
483
    TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n",
484
            len,(int)pos,(int)begin,(int)offset,length,size));
485
    return(len);
486
}
487
 
488
 
489
void gdth_scsi_done(Scsi_Cmnd *scp)
490
{
491
    TRACE2(("gdth_scsi_done()\n"));
492
 
493
    scp->request.rq_status = RQ_SCSI_DONE;
494
 
495
    if (scp->request.sem != NULL)
496
        up(scp->request.sem);
497
}
498
 
499
static int gdth_ioctl_alloc(int hanum, ushort size)
500
{
501
    ulong flags;
502
    int i;
503
 
504
    if (size == 0)
505
        return -1;
506
 
507
    save_flags(flags);
508
    cli();
509
 
510
    for (i = 0; i < 4; ++i) {
511
        if (gdth_ioctl_tab[i][hanum] == NULL) {
512
            gdth_ioctl_tab[i][hanum] = kmalloc( size, GFP_ATOMIC | GFP_DMA );
513
            break;
514
        }
515
    }
516
 
517
    restore_flags(flags);
518
    if (i == 4 || gdth_ioctl_tab[i][hanum] == NULL)
519
        return -1;
520
    return (i+1);
521
}
522
 
523
static void gdth_ioctl_free(int hanum, int idx)
524
{
525
    ulong flags;
526
 
527
    save_flags(flags);
528
    cli();
529
 
530
    kfree( gdth_ioctl_tab[idx-1][hanum] );
531
    gdth_ioctl_tab[idx-1][hanum] = NULL;
532
 
533
    restore_flags(flags);
534
}
535
 
536
static void gdth_wait_completion(int hanum, int busnum, int id)
537
{
538
    ulong flags;
539
    int i;
540
    Scsi_Cmnd *scp;
541
 
542
    save_flags(flags);
543
    cli();
544
 
545
    for (i = 0; i < GDTH_MAXCMDS; ++i) {
546
        scp = gdth_cmd_tab[i][hanum].cmnd;
547
#if LINUX_VERSION_CODE >= 0x020000
548
        if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&
549
            scp->channel == (unchar)busnum)
550
#else
551
        if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&
552
            NUMDATA(scp->host)->busnum == (unchar)busnum)
553
#endif
554
        {
555
            scp->SCp.have_data_in = 0;
556
            restore_flags(flags);
557
            while (!scp->SCp.have_data_in)
558
                barrier();
559
            scp->scsi_done(scp);
560
            save_flags(flags);
561
            cli();
562
        }
563
    }
564
    restore_flags(flags);
565
}
566
 
567
static void gdth_stop_timeout(int hanum, int busnum, int id)
568
{
569
    ulong flags;
570
    Scsi_Cmnd *scp;
571
    gdth_ha_str *ha;
572
 
573
    save_flags(flags);
574
    cli();
575
    ha = HADATA(gdth_ctr_tab[hanum]);
576
 
577
    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
578
#if LINUX_VERSION_CODE >= 0x020000
579
        if (scp->target == (unchar)id &&
580
            scp->channel == (unchar)busnum)
581
#else
582
        if (scp->target == (unchar)id &&
583
            NUMDATA(scp->host)->busnum == (unchar)busnum)
584
#endif
585
        {
586
            TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
587
            scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
588
        }
589
    }
590
    restore_flags(flags);
591
}
592
 
593
static void gdth_start_timeout(int hanum, int busnum, int id)
594
{
595
    ulong flags;
596
    Scsi_Cmnd *scp;
597
    gdth_ha_str *ha;
598
 
599
    save_flags(flags);
600
    cli();
601
    ha = HADATA(gdth_ctr_tab[hanum]);
602
 
603
    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
604
#if LINUX_VERSION_CODE >= 0x020000
605
        if (scp->target == (unchar)id &&
606
            scp->channel == (unchar)busnum)
607
#else
608
        if (scp->target == (unchar)id &&
609
            NUMDATA(scp->host)->busnum == (unchar)busnum)
610
#endif
611
        {
612
            TRACE2(("gdth_start_timeout(): update_timeout()\n"));
613
            gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
614
        }
615
    }
616
    restore_flags(flags);
617
}
618
 
619
static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout)
620
{
621
    ulong flags;
622
    int oldto;
623
 
624
    save_flags(flags);
625
    cli();
626
    oldto = scp->timeout_per_command;
627
    scp->timeout_per_command = timeout;
628
 
629
#if LINUX_VERSION_CODE >= 0x02014B
630
    if (timeout == 0) {
631
        del_timer(&scp->eh_timeout);
632
        scp->eh_timeout.data = (unsigned long) NULL;
633
        scp->eh_timeout.expires = 0;
634
    } else {
635
        if (scp->eh_timeout.data != (unsigned long) NULL)
636
            del_timer(&scp->eh_timeout);
637
        scp->eh_timeout.data = (unsigned long) scp;
638
        scp->eh_timeout.expires = jiffies + timeout;
639
        add_timer(&scp->eh_timeout);
640
    }
641
#else
642
    if (timeout > 0) {
643
        if (timer_table[SCSI_TIMER].expires == 0) {
644
            timer_table[SCSI_TIMER].expires = jiffies + timeout;
645
            timer_active |= 1 << SCSI_TIMER;
646
        } else {
647
            if (jiffies + timeout < timer_table[SCSI_TIMER].expires)
648
                timer_table[SCSI_TIMER].expires = jiffies + timeout;
649
        }
650
    }
651
#endif
652
 
653
    restore_flags(flags);
654
    return oldto;
655
}
656
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.