Annotation of Gnu-Mach/linux/src/drivers/scsi/gdth_proc.c, revision 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.