|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* ! 25: * dx - menu based device exerciser tool. ! 26: * ! 27: * HISTORY ! 28: * 19-Mar-91 Doug Mitchell at NeXT ! 29: * Created. ! 30: */ ! 31: ! 32: #import <bsd/sys/types.h> ! 33: #import <bsd/libc.h> ! 34: #import <driverkit/IOClient.h> ! 35: #import <driverkit/SCSIDiskClient.h> ! 36: #import <bsd/dev/SCSITypes.h> ! 37: #import <mach/mach_error.h> ! 38: #import "defaults.h" ! 39: #import "buflib.h" ! 40: ! 41: /* ! 42: * prototypes for private functions. ! 43: */ ! 44: static void usage(char **argv); ! 45: static void print_menu(); ! 46: static void setupCDB(); ! 47: static void setupScsiReq(scsiReq_t *scsiReq, SCSIDmaDir_t dir); ! 48: ! 49: /* ! 50: * Menu stuff. ! 51: */ ! 52: struct menu_entry { ! 53: char menu_c; ! 54: char *name; ! 55: void (*men_fcn)(); ! 56: }; ! 57: ! 58: /* ! 59: * User commands. ! 60: */ ! 61: static void dxRead(); ! 62: static void dxWrite(); ! 63: static void cdbRead(); ! 64: static void cdbWrite(); ! 65: static void setTarget(); ! 66: static void setLun(); ! 67: static void setCount(); ! 68: static void setBlock(); ! 69: static void dxQuery(); ! 70: static void dxCheckReady(); ! 71: static void setByteCount(); ! 72: static void setLoopCount(); ! 73: static void getForm(); ! 74: static void setForm(); ! 75: static void getRemove(); ! 76: static void fillWbuf(); ! 77: static void dumpRbuf(); ! 78: static void quit(); ! 79: static void getDname(); ! 80: static void dxEject(); ! 81: ! 82: struct menu_entry me_array[] = { ! 83: ! 84: {'r', "Read " , dxRead }, {'w', "Write " , dxWrite }, ! 85: {'R', "cdbRead " , cdbRead }, {'W', "cdbWrite " , cdbWrite }, ! 86: {'c', "Set Count " , setCount }, {'b', "Set Block " , setBlock }, ! 87: {'T', "Set Target " , setTarget }, {'L', "Set lun " , setLun }, ! 88: {'Q', "Query " , dxQuery }, {'u', "Check Ready " , dxCheckReady }, ! 89: {'y', "Max ByteCount" , setByteCount}, {'l', "Loop Count " , setLoopCount }, ! 90: {'f', "Get Formatted" , getForm }, {'F', "Set Formatted" , setForm }, ! 91: {'v', "Get Removable" , getRemove }, {'C', "Set up CDB " , setupCDB }, ! 92: {'D', "GetDriveName " , getDname }, {'e', "Eject " , dxEject }, ! 93: {'1', "Fill buffer " , fillWbuf }, {'2', "Dump Buffer " , dumpRbuf }, ! 94: {'x', "Exit " , quit }, {'h', "Help " , print_menu }, ! 95: {0, NULL , NULL } ! 96: }; ! 97: ! 98: #define BUFSIZE (64 * 1024) ! 99: ! 100: /* ! 101: * Static variables. ! 102: */ ! 103: int ioTimeout = 10; ! 104: int target = 0; ! 105: int lun = 0; ! 106: id clientId; ! 107: int count = 1024; ! 108: int block = 0; ! 109: int byteCountMax = 4096; ! 110: int loopCount = 1; ! 111: u_char cdb[12]; ! 112: char *hostname=HOST_DEFAULT; ! 113: char *devname=DEVICE_DEFAULT; ! 114: char *rbuf, *wbuf; ! 115: IOErrorString errorstr; ! 116: ! 117: int main(int argc, char **argv) ! 118: { ! 119: int arg; ! 120: char instr[80]; ! 121: struct menu_entry *mep; ! 122: int ok; ! 123: IOReturn rtn; ! 124: kern_return_t krtn; ! 125: ! 126: /* ! 127: * Get standard defaults from environment or defaults.h ! 128: */ ! 129: get_default_t("hostname", &hostname, HOST_DEFAULT); ! 130: get_default_t("devname", &devname, DEVICE_DEFAULT); ! 131: ! 132: for(arg=1; arg<argc; arg++) { ! 133: switch(argv[arg][0]) { ! 134: case 'h': ! 135: hostname = &argv[arg][2]; ! 136: break; ! 137: case 'd': ! 138: devname = &argv[arg][2]; ! 139: break; ! 140: default: ! 141: usage(argv); ! 142: } ! 143: } ! 144: ! 145: /* ! 146: * Instantiate and init the client object. Use SCSIDiskClient as ! 147: * default. ! 148: */ ! 149: rtn = [SCSIDiskClient clientOpen:devname ! 150: hostName:hostname ! 151: intentions:IO_INT_READ|IO_INT_WRITE ! 152: idp:&clientId]; ! 153: if(rtn) { ! 154: /* ! 155: * try opening read only. ! 156: */ ! 157: rtn = [SCSIDiskClient clientOpen:devname ! 158: hostName:hostname ! 159: intentions:IO_INT_READ ! 160: idp:&clientId]; ! 161: if(rtn) { ! 162: [SCSIDiskClient ioError:rtn ! 163: logString:"Open" ! 164: outString:errorstr]; ! 165: printf("%s...aborting\n", errorstr); ! 166: exit(1); ! 167: } ! 168: else ! 169: printf("...Warning: Device is Read-Only\n"); ! 170: } ! 171: ! 172: /* ! 173: * Allocate and init read and write buffers. ! 174: */ ! 175: krtn = vm_allocate(task_self(), ! 176: (vm_address_t *)&rbuf, ! 177: (vm_size_t)BUFSIZE, ! 178: TRUE); ! 179: if(krtn) { ! 180: mach_error("vm_allocate", krtn); ! 181: exit(1); ! 182: } ! 183: krtn = vm_allocate(task_self(), ! 184: (vm_address_t *)&wbuf, ! 185: (vm_size_t)BUFSIZE, ! 186: TRUE); ! 187: if(krtn) { ! 188: mach_error("vm_allocate", krtn); ! 189: exit(1); ! 190: } ! 191: bzero(rbuf, BUFSIZE); ! 192: bzero(wbuf, BUFSIZE); ! 193: ! 194: /* ! 195: * Enter main loop. ! 196: */ ! 197: print_menu(); ! 198: while(1) { ! 199: printf("Enter Selection: "); ! 200: gets(instr); ! 201: mep = me_array; ! 202: ok = 0; ! 203: while(mep->menu_c) { ! 204: if(mep->menu_c == instr[0]) { ! 205: ok = 1; ! 206: (*mep->men_fcn)(); ! 207: break; ! 208: } ! 209: else ! 210: mep++; ! 211: } ! 212: if(!ok) ! 213: printf("***Illegal Selection\n"); ! 214: } ! 215: return(0); ! 216: } ! 217: ! 218: static void usage(char **argv) ! 219: { ! 220: printf("usage: %s d[h=hostname] [d=devname]\n", argv[0]); ! 221: exit(1); ! 222: } ! 223: ! 224: static void print_menu() { ! 225: ! 226: struct menu_entry *mep; ! 227: ! 228: printf("\n"); ! 229: mep = me_array; ! 230: while(mep->menu_c) { ! 231: printf(" %c: %s ",mep->menu_c,mep->name); ! 232: mep++; ! 233: if(mep->menu_c) { ! 234: printf(" %c: %s ",mep->menu_c,mep->name); ! 235: mep++; ! 236: } ! 237: printf("\n"); ! 238: } ! 239: printf("\n"); ! 240: } /* print_menu() */ ! 241: ! 242: static void cdbRead() ! 243: { ! 244: scsiReq_t scsiReq; ! 245: scStatus rtn; ! 246: ! 247: setupScsiReq(&scsiReq, SCSI_DMA_READ); ! 248: rtn = [clientId sdCdbRead:&scsiReq buf:rbuf]; ! 249: if(rtn) { ! 250: [IOClient ioError:rtn ! 251: logString:"sdCdbRead" ! 252: outString:errorstr]; ! 253: printf("%s", errorstr); ! 254: } ! 255: else if(scsiReq.ioStatus) ! 256: printf("...sdCdbRead: ioStatus = %d\n", scsiReq.ioStatus); ! 257: else ! 258: printf("...OK\n"); ! 259: } ! 260: ! 261: static void cdbWrite() ! 262: { ! 263: scsiReq_t scsiReq; ! 264: scStatus rtn; ! 265: ! 266: setupScsiReq(&scsiReq, SCSI_DMA_WRITE); ! 267: rtn = [clientId sdCdbWrite:&scsiReq buf:wbuf]; ! 268: if(rtn) ! 269: if(rtn) { ! 270: [IOClient ioError:rtn ! 271: logString:"sdCdbWrite" ! 272: outString:errorstr]; ! 273: printf("%s", errorstr); ! 274: } ! 275: else if(scsiReq.ioStatus) ! 276: printf("...sdCdbWrite: ioStatus = %d\n", scsiReq.ioStatus); ! 277: else ! 278: printf("...OK\n"); ! 279: } ! 280: ! 281: static void setTarget() ! 282: { ! 283: char instr[100]; ! 284: ! 285: printf("Enter new target (CR = %d): ", target); ! 286: gets(instr); ! 287: if(instr[0]) ! 288: target = atoi(instr); ! 289: } ! 290: ! 291: static void setLun() ! 292: { ! 293: char instr[100]; ! 294: ! 295: printf("Enter new lun (CR = %d): ", lun); ! 296: gets(instr); ! 297: if(instr[0]) ! 298: lun = atoi(instr); ! 299: } ! 300: ! 301: static void setCount() ! 302: { ! 303: printf("Enter new count (CR = %d): ", count); ! 304: count = get_num(count, DEC); ! 305: } ! 306: ! 307: static void setBlock() ! 308: { ! 309: printf("Enter new block (CR = %d): ", block); ! 310: block = get_num(block, DEC); ! 311: } ! 312: ! 313: static void dxQuery() ! 314: { ! 315: u_int queryData; ! 316: IOReturn rtn; ! 317: ! 318: rtn = [clientId ioQuery:&queryData]; ! 319: if(rtn) { ! 320: [IOClient ioError:rtn ! 321: logString:"ioQuery" ! 322: outString:errorstr]; ! 323: printf(errorstr); ! 324: return; ! 325: } ! 326: printf(" queryData = 0x%X\n", queryData); ! 327: if(queryData & DQF_READABLE) ! 328: printf("\tDQF_READABLE\n"); ! 329: if(queryData & DQF_WRITEABLE) ! 330: printf("\tDQF_WRITABLE\n"); ! 331: if(queryData & DQF_RAND_ACC) ! 332: printf("\tDQF_RAND_ACC\n"); ! 333: if(queryData & DQF_CAN_QUEUE) ! 334: printf("\tDQF_CAN_QUEUE\n"); ! 335: if(queryData & DQF_CAN_RD_LOCK) ! 336: printf("\tDQF_CAN_RD_LOCK\n"); ! 337: if(queryData & DQF_CAN_WRT_LOCK) ! 338: printf("\tDQF_CAN_WRT_LOCK\n"); ! 339: if(queryData & DQF_IS_RD_LOCK) ! 340: printf("\tDQF_IS_RD_LOCK\n"); ! 341: if(queryData & DQF_IS_WRT_LOCK) ! 342: printf("\tDQF_IS_WRT_LOCK\n"); ! 343: if(queryData & DQF_EXCLUSIVE) ! 344: printf("\tDQF_EXCLUSIVE\n"); ! 345: #ifdef notdef ! 346: printf(" block_size = 0x%X dev_size = %d\n", ! 347: queryData.block_size, queryData.dev_size); ! 348: #endif notdef ! 349: } ! 350: ! 351: static void dxRead() ! 352: { ! 353: u_int bytesXfr; ! 354: IOReturn rtn; ! 355: ! 356: rtn = [clientId ioRead:block ! 357: bytesReq:count ! 358: buf:rbuf ! 359: bytesXfr:&bytesXfr]; ! 360: if(rtn) { ! 361: [IOClient ioError:rtn ! 362: logString:"ioRead" ! 363: outString:errorstr]; ! 364: printf("%s", errorstr); ! 365: return; ! 366: } ! 367: if(bytesXfr != count) { ! 368: printf("bytesXfr = 0x%x, expected 0x%x\n", ! 369: bytesXfr, count); ! 370: } ! 371: } ! 372: ! 373: static void dxWrite() ! 374: { ! 375: u_int bytesXfr; ! 376: IOReturn rtn; ! 377: ! 378: rtn = [clientId ioWrite:block ! 379: bytesReq:count ! 380: buf:wbuf ! 381: bytesXfr:&bytesXfr]; ! 382: if(rtn) { ! 383: [IOClient ioError:rtn ! 384: logString:"ioWrite" ! 385: outString:errorstr]; ! 386: printf("%s", errorstr); ! 387: return; ! 388: } ! 389: if(bytesXfr != count) { ! 390: printf("bytesXfr = 0x%x, expected 0x%x\n", ! 391: bytesXfr, count); ! 392: } ! 393: } ! 394: ! 395: static void dxCheckReady() ! 396: { ! 397: DiskReadyState ready; ! 398: IOReturn rtn; ! 399: ! 400: rtn = [clientId updateReadyState:&ready]; ! 401: if(rtn) { ! 402: [IOClient ioError:rtn ! 403: logString:"CheckReady" ! 404: outString:errorstr]; ! 405: printf("%s", errorstr); ! 406: return; ! 407: } ! 408: switch(ready) { ! 409: case IO_Ready: ! 410: printf("...Disk Ready\n"); ! 411: break; ! 412: case IO_NotReady: ! 413: printf("...Disk Not Ready\n"); ! 414: break; ! 415: case IO_NoDisk: ! 416: printf("...No Disk\n"); ! 417: break; ! 418: case IO_Ejecting: ! 419: printf("...Ejecting\n"); ! 420: break; ! 421: } ! 422: return; ! 423: } ! 424: ! 425: static void setByteCount() ! 426: { ! 427: printf("Enter new max byte count (CR = %d): ", byteCountMax); ! 428: byteCountMax = get_num(byteCountMax, DEC); ! 429: ! 430: } ! 431: ! 432: static void setLoopCount() ! 433: { ! 434: printf("Enter new loop count (CR = %d): ", loopCount); ! 435: loopCount = get_num(loopCount, DEC); ! 436: } ! 437: ! 438: static void setupCDB() ! 439: { ! 440: char instr[80]; ! 441: int i; ! 442: ! 443: printf("Hit ESC anytime to quit.\n"); ! 444: for(i=0; i<12; i++) { ! 445: printf("Enter CDB byte %d (CR = 0x%x): ", i, cdb[i]); ! 446: gets(instr); ! 447: switch(instr[0]) { ! 448: case '\0': ! 449: break; /* take default */ ! 450: case 0x1b: ! 451: return; /* ESC - done */ ! 452: default: ! 453: cdb[i] = atoh(instr); ! 454: break; ! 455: } ! 456: } ! 457: } ! 458: ! 459: static void getForm() ! 460: { ! 461: u_int formFlag; ! 462: IOReturn rtn; ! 463: ! 464: rtn = [clientId getFormatted:&formFlag]; ! 465: if(rtn) { ! 466: [IOClient ioError:rtn ! 467: logString:"getFormatted" ! 468: outString:errorstr]; ! 469: printf("%s", errorstr); ! 470: return; ! 471: } ! 472: if(formFlag) ! 473: printf("...Disk Formatted\n"); ! 474: else ! 475: printf("...Disk Unformatted\n"); ! 476: } ! 477: ! 478: static void setForm() ! 479: { ! 480: u_int formFlag; ! 481: IOReturn rtn; ! 482: char instr[80]; ! 483: ! 484: printf("New formatted value (0/1): "); ! 485: gets(instr); ! 486: if(instr[0] == '1') ! 487: formFlag = 1; ! 488: else ! 489: formFlag = 0; ! 490: rtn = [clientId setFormatted:formFlag]; ! 491: if(rtn) { ! 492: [IOClient ioError:rtn ! 493: logString:"setFormatted" ! 494: outString:errorstr]; ! 495: printf("%s", errorstr); ! 496: return; ! 497: } ! 498: else ! 499: printf("...OK\n"); ! 500: } ! 501: ! 502: static void getRemove() ! 503: { ! 504: u_int removeFlag; ! 505: IOReturn rtn; ! 506: ! 507: rtn = [clientId getRemovable:&removeFlag]; ! 508: if(rtn) { ! 509: [IOClient ioError:rtn ! 510: logString:"getRemovable" ! 511: outString:errorstr]; ! 512: printf("%s", errorstr); ! 513: return; ! 514: } ! 515: if(removeFlag) ! 516: printf("...Removable Disk\n"); ! 517: else ! 518: printf("...Fixed Disk\n"); ! 519: } ! 520: ! 521: static void fillWbuf() ! 522: { ! 523: char instr[80]; ! 524: int i; ! 525: ! 526: printf("z = zero\ni = incrementing\nd = decrementing\n"); ! 527: printf("Enter pattern: "); ! 528: gets(instr); ! 529: switch(instr[0]) { ! 530: case 'z': ! 531: bzero(wbuf, BUFSIZE); ! 532: break; ! 533: case 'i': ! 534: for(i=0; i<BUFSIZE; i++) ! 535: wbuf[i] = i; ! 536: break; ! 537: case 'd': ! 538: for(i=0; i<BUFSIZE; i++) ! 539: wbuf[i] = BUFSIZE - i; ! 540: break; ! 541: default: ! 542: printf("***Illegal selection***\n"); ! 543: break; ! 544: } ! 545: } ! 546: ! 547: static void dumpRbuf() ! 548: { ! 549: dump_buf((u_char *)rbuf, BUFSIZE); ! 550: } ! 551: ! 552: static void getDname() ! 553: { ! 554: /* const char *name; */ ! 555: ! 556: printf("...getDriveName not supported\n"); ! 557: return; ! 558: #ifdef notdef ! 559: name = [clientId getDriveName]; ! 560: if(name == NULL) { ! 561: printf("NULL drivename\n"); ! 562: return; ! 563: } ! 564: printf("Drive Name = %s\n", name); ! 565: return; ! 566: #endif notdef ! 567: } ! 568: ! 569: static void dxEject() ! 570: { ! 571: IOReturn rtn; ! 572: ! 573: rtn = [clientId eject]; ! 574: if(rtn) { ! 575: [IOClient ioError:rtn ! 576: logString:"eject" ! 577: outString:errorstr]; ! 578: printf("%s", errorstr); ! 579: return; ! 580: } ! 581: printf("...OK\n"); ! 582: } ! 583: ! 584: /* ! 585: * Internal functions. ! 586: */ ! 587: static void setupScsiReq(scsiReq_t *scsiReq, SCSIDmaDir_t dir) ! 588: { ! 589: bzero(scsiReq, sizeof(scsiReq_t)); ! 590: scsiReq->target = target; ! 591: scsiReq->lun = lun; ! 592: scsiReq->cdb = *(cdb_t *)cdb; ! 593: scsiReq->dmaDir = dir; ! 594: scsiReq->dmaMax = byteCountMax; ! 595: scsiReq->ioTimeout = ioTimeout; ! 596: scsiReq->disconnect = 1; ! 597: } ! 598: ! 599: static void quit() ! 600: { ! 601: exit(0); ! 602: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.