Annotation of Gnu-Mach/linux/src/drivers/scsi/gdth_proc.c, revision 1.1.1.1

1.1       root        1: /* gdth_proc.c 
                      2:  * $Id: gdth_proc.c,v 1.1 1999/04/26 05:54:38 tb 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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.