|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.