00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00124 #include "StdAfx.h"
00125 #include "Disk.h"
00126
00130 CDisk::CDisk(CConfigurator* cfg, CSystem* sys, CDiskController* ctrl,
00131 int idebus, int idedev) : CSystemComponent(cfg, sys)
00132 {
00133 char* a;
00134 char* b;
00135 char* c;
00136 char* d;
00137
00138 myCfg = cfg;
00139 myCtrl = ctrl;
00140 myBus = idebus;
00141 myDev = idedev;
00142 atapi_mode = false;
00143
00144 a = myCfg->get_myName();
00145 b = myCfg->get_myValue();
00146 c = myCfg->get_myParent()->get_myName();
00147 d = myCfg->get_myParent()->get_myValue();
00148
00149 free(devid_string);
00150 CHECK_ALLOCATION(devid_string = (char*) malloc(
00151 strlen(a) + strlen(b) + strlen(c) + strlen(d) + 6));
00152 sprintf(devid_string, "%s(%s).%s(%s)", c, d, a, b);
00153
00154 serial_number = myCfg->get_text_value("serial_num", "ES40EM00000");
00155 revision_number = myCfg->get_text_value("rev_num", "0.0");
00156 read_only = myCfg->get_bool_value("read_only");
00157 is_cdrom = myCfg->get_bool_value("cdrom");
00158
00159 state.block_size = is_cdrom ? 2048 : 512;
00160 state.scsi.sense.available = false;
00161
00162 myCtrl->register_disk(this, myBus, myDev);
00163 }
00164
00168 CDisk::~CDisk(void)
00169 {
00170 free(devid_string);
00171 }
00172
00176 void CDisk::calc_cylinders()
00177 {
00178 cylinders = byte_size / state.block_size / sectors / heads;
00179
00180 off_t_large chs_size = sectors * cylinders * heads * state.block_size;
00181 if(chs_size < byte_size)
00182 cylinders++;
00183 }
00184
00191 void CDisk::scsi_select_me(int bus)
00192 {
00193 state.scsi.msgo.written = 0;
00194 state.scsi.msgi.available = 0;
00195 state.scsi.msgi.read = 0;
00196 state.scsi.cmd.written = 0;
00197 state.scsi.dati.available = 0;
00198 state.scsi.dati.read = 0;
00199 state.scsi.dato.expected = 0;
00200 state.scsi.dato.written = 0;
00201 state.scsi.stat.available = 0;
00202 state.scsi.stat.read = 0;
00203 state.scsi.lun_selected = false;
00204
00205
00206
00207
00208 if(atapi_mode)
00209 scsi_set_phase(bus, SCSI_PHASE_COMMAND);
00210 else
00211 scsi_set_phase(bus, SCSI_PHASE_MSG_OUT);
00212 }
00213
00214 static u32 disk_magic1 = 0xD15D15D1;
00215 static u32 disk_magic2 = 0x15D15D5;
00216
00220 int CDisk::SaveState(FILE* f)
00221 {
00222 long ss = sizeof(state);
00223
00224 fwrite(&disk_magic1, sizeof(u32), 1, f);
00225 fwrite(&ss, sizeof(long), 1, f);
00226 fwrite(&state, sizeof(state), 1, f);
00227 fwrite(&disk_magic2, sizeof(u32), 1, f);
00228 printf("%s: %d bytes saved.\n", devid_string, (int) ss);
00229 return 0;
00230 }
00231
00235 int CDisk::RestoreState(FILE* f)
00236 {
00237 long ss;
00238 u32 m1;
00239 u32 m2;
00240 size_t r;
00241
00242 r = fread(&m1, sizeof(u32), 1, f);
00243 if(r != 1)
00244 {
00245 printf("%s: unexpected end of file!\n", devid_string);
00246 return -1;
00247 }
00248
00249 if(m1 != disk_magic1)
00250 {
00251 printf("%s: MAGIC 1 does not match!\n", devid_string);
00252 return -1;
00253 }
00254
00255 fread(&ss, sizeof(long), 1, f);
00256 if(r != 1)
00257 {
00258 printf("%s: unexpected end of file!\n", devid_string);
00259 return -1;
00260 }
00261
00262 if(ss != sizeof(state))
00263 {
00264 printf("%s: STRUCT SIZE does not match!\n", devid_string);
00265 return -1;
00266 }
00267
00268 fread(&state, sizeof(state), 1, f);
00269 if(r != 1)
00270 {
00271 printf("%s: unexpected end of file!\n", devid_string);
00272 return -1;
00273 }
00274
00275 r = fread(&m2, sizeof(u32), 1, f);
00276 if(r != 1)
00277 {
00278 printf("%s: unexpected end of file!\n", devid_string);
00279 return -1;
00280 }
00281
00282 if(m2 != disk_magic2)
00283 {
00284 printf("%s: MAGIC 1 does not match!\n", devid_string);
00285 return -1;
00286 }
00287
00288
00289 determine_layout();
00290
00291 printf("%s: %d bytes restored.\n", devid_string, (int) ss);
00292 return 0;
00293 }
00294
00305 size_t CDisk::scsi_expected_xfer_me(int bus)
00306 {
00307 switch(scsi_get_phase(0))
00308 {
00309 case SCSI_PHASE_DATA_OUT:
00310 return state.scsi.dato.expected - state.scsi.dato.written;
00311
00312 case SCSI_PHASE_DATA_IN:
00313 return state.scsi.dati.available - state.scsi.dati.read;
00314
00315 case SCSI_PHASE_COMMAND:
00316 return 256 - state.scsi.cmd.written;
00317
00318 case SCSI_PHASE_STATUS:
00319 return state.scsi.stat.available - state.scsi.stat.read;
00320
00321 case SCSI_PHASE_MSG_OUT:
00322 return 256 - state.scsi.msgo.written;
00323
00324 case SCSI_PHASE_MSG_IN:
00325 return state.scsi.msgi.available - state.scsi.msgi.read;
00326
00327 default:
00328 FAILURE_2(IllegalState, "%s: transfer requested in phase %d\n",
00329 devid_string, scsi_get_phase(0));
00330 }
00331 }
00332
00342 void* CDisk::scsi_xfer_ptr_me(int bus, size_t bytes)
00343 {
00344 void* res = 0;
00345
00346 switch(scsi_get_phase(0))
00347 {
00348 case SCSI_PHASE_DATA_OUT:
00349 res = &(state.scsi.dato.data[state.scsi.dato.written]);
00350 state.scsi.dato.written += bytes;
00351 break;
00352
00353 case SCSI_PHASE_DATA_IN:
00354 res = &(state.scsi.dati.data[state.scsi.dati.read]);
00355 state.scsi.dati.read += bytes;
00356 break;
00357
00358 case SCSI_PHASE_COMMAND:
00359 res = &(state.scsi.cmd.data[state.scsi.cmd.written]);
00360 state.scsi.cmd.written += bytes;
00361 break;
00362
00363 case SCSI_PHASE_STATUS:
00364 res = &(state.scsi.stat.data[state.scsi.stat.read]);
00365 state.scsi.stat.read += bytes;
00366 break;
00367
00368 case SCSI_PHASE_MSG_OUT:
00369 res = &(state.scsi.msgo.data[state.scsi.msgo.written]);
00370 state.scsi.msgo.written += bytes;
00371 break;
00372
00373 case SCSI_PHASE_MSG_IN:
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 res = &(state.scsi.msgi.data[state.scsi.msgi.read]);
00400 state.scsi.msgi.read += bytes;
00401 break;
00402
00403 default:
00404 FAILURE_2(IllegalState, "%s: transfer requested in phase %d\n",
00405 devid_string, scsi_get_phase(0));
00406 }
00407
00408 return res;
00409 }
00410
00422 void CDisk::scsi_xfer_done_me(int bus)
00423 {
00424 int res;
00425 int newphase = scsi_get_phase(0);
00426
00427 switch(scsi_get_phase(0))
00428 {
00429 case SCSI_PHASE_DATA_OUT:
00430 if(state.scsi.dato.written < state.scsi.dato.expected)
00431 break;
00432
00433 res = do_scsi_command();
00434 if(res == 2)
00435 FAILURE(IllegalState, "do_command returned 2 after DATA OUT phase");
00436
00437 if(state.scsi.dati.available)
00438 newphase = SCSI_PHASE_DATA_IN;
00439 else
00440 newphase = SCSI_PHASE_STATUS;
00441 break;
00442
00443 case SCSI_PHASE_DATA_IN:
00444 if(state.scsi.dati.read < state.scsi.dati.available)
00445 break;
00446
00447 newphase = SCSI_PHASE_STATUS;
00448 break;
00449
00450 case SCSI_PHASE_COMMAND:
00451 res = do_scsi_command();
00452 if(res == 2)
00453 newphase = SCSI_PHASE_DATA_OUT;
00454 else if(state.scsi.dati.available)
00455 newphase = SCSI_PHASE_DATA_IN;
00456 else
00457 newphase = SCSI_PHASE_STATUS;
00458 break;
00459
00460 case SCSI_PHASE_STATUS:
00461 if(state.scsi.stat.read < state.scsi.stat.available)
00462 break;
00463
00464 if(atapi_mode)
00465 {
00466 scsi_free(0);
00467 return;
00468 }
00469
00470 newphase = SCSI_PHASE_MSG_IN;
00471 break;
00472
00473 case SCSI_PHASE_MSG_OUT:
00474 newphase = do_scsi_message();
00475 break;
00476
00477 case SCSI_PHASE_MSG_IN:
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 if(state.scsi.msgi.read < state.scsi.msgi.available)
00490 break;
00491
00492 if(state.scsi.cmd.written)
00493 {
00494 scsi_free(0);
00495 return;
00496 }
00497 else
00498 newphase = SCSI_PHASE_COMMAND;
00499 break;
00500
00501 default:
00502 FAILURE_2(IllegalState, "%s: transfer requested in phase %d\n",
00503 devid_string, scsi_get_phase(0));
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 if(newphase != scsi_get_phase(0))
00515 {
00516
00517
00518
00519
00520
00521
00522
00523 scsi_set_phase(0, newphase);
00524 }
00525
00526
00527 }
00528
00529
00530 #define SCSICMD_TEST_UNIT_READY 0x00
00531 #define SCSICMD_REQUEST_SENSE 0x03
00532 #define SCSICMD_INQUIRY 0x12
00533
00534 #define SCSICMD_READ 0x08
00535 #define SCSICMD_READ_10 0x28
00536 #define SCSICMD_READ_12 0xA8
00537 #define SCSICMD_READ_16 0x88
00538 #define SCSICMD_READ_32 0x7F
00539 #define SCSICMD_READ_LONG 0x3E
00540 #define SCSICMD_READ_CD 0xBE
00541
00542 #define SCSICMD_WRITE 0x0A
00543 #define SCSICMD_WRITE_10 0x2A
00544 #define SCSICMD_WRITE_12 0xAA
00545 #define SCSICMD_WRITE_LONG 0x3F
00546
00547 #define SCSICMD_MODE_SELECT 0x15
00548 #define SCSICMD_MODE_SENSE 0x1a
00549 #define SCSICMD_START_STOP_UNIT 0x1b
00550 #define SCSICMD_PREVENT_ALLOW_REMOVE 0x1e
00551 #define SCSICMD_MODE_SENSE_10 0x5a
00552
00553 #define SCSICMD_SYNCHRONIZE_CACHE 0x35
00554
00555
00556 #define SCSIBLOCKCMD_READ_CAPACITY 0x25
00557
00558
00559 #define SCSICDROM_READ_SUBCHANNEL 0x42
00560 #define SCSICDROM_READ_TOC 0x43
00561
00562
00563 #define SCSICDRRW_FORMAT 0x04
00564 #define SCSICDRRW_READ_DISC_INFO 0x51
00565 #define SCSICDRRW_READ_TRACK_INFO 0x52
00566 #define SCSICDRRW_RESERVE_TRACK 0x53
00567 #define SCSICDRRW_SEND_OPC_INFO 0x54
00568 #define SCSICDRRW_REPAIR_TRACK 0x58
00569 #define SCSICDRRW_READ_MASTER_CUE 0x59
00570 #define SCSICDRRW_CLOSE_TRACK 0x5b
00571 #define SCSICDRRW_READ_BUFFER_CAP 0x5c
00572 #define SCSICDRRW_SEND_CUE_SHEET 0x5d
00573 #define SCSICDRRW_BLANK 0xa1
00574
00575
00576 #define SCSICMD_REWIND 0x01
00577 #define SCSICMD_READ_BLOCK_LIMITS 0x05
00578 #define SCSICMD_SPACE 0x11
00579
00580
00581 #define SCSIMP_VENDOR 0x00
00582 #define SCSIMP_READ_WRITE_ERRREC 0x01
00583 #define SCSIMP_DISCONNECT_RECONNECT 0x02
00584 #define SCSIMP_FORMAT_PARAMS 0x03
00585 #define SCSIMP_RIGID_GEOMETRY 0x04
00586 #define SCSIMP_FLEX_PARAMS 0x05
00587 #define SCSIMP_CACHING 0x08
00588 #define SCSIMP_CDROM_CAP 0x2A
00589
00590 #define SCSI_OK 0
00591 #define SCSI_ILL_CMD - 1
00592 #define SCSI_LBA_RANGE - 2
00593 #define SCSI_TOO_BIG - 3
00594
00595 void CDisk::do_scsi_error(int errcode)
00596 {
00597 state.scsi.stat.available = 1;
00598 state.scsi.stat.data[0] = 0;
00599 state.scsi.stat.read = 0;
00600 state.scsi.msgi.available = 1;
00601 state.scsi.msgi.data[0] = 0;
00602 state.scsi.msgi.read = 0;
00603
00604 if(errcode == SCSI_OK)
00605 {
00606 #if defined(DEBUG_SCSI)
00607 printf("%s: Command returns OK status.\n", devid_string);
00608 #endif
00609 return;
00610 }
00611
00612 state.scsi.stat.data[0] = 0x02;
00613 state.scsi.sense.data[0] = 0xf0;
00614 state.scsi.sense.data[1] = 0x00;
00615 state.scsi.sense.data[3] = 0x00;
00616 state.scsi.sense.data[4] = 0x00;
00617 state.scsi.sense.data[5] = 0x00;
00618 state.scsi.sense.data[6] = 0x00;
00619 state.scsi.sense.data[7] = 10;
00620 state.scsi.sense.data[8] = 0x00;
00621 state.scsi.sense.data[9] = 0x00;
00622 state.scsi.sense.data[10] = 0x00;
00623 state.scsi.sense.data[11] = 0x00;
00624 state.scsi.sense.data[14] = 0x00;
00625 state.scsi.sense.data[15] = 0x00;
00626 state.scsi.sense.data[16] = 0x00;
00627 state.scsi.sense.data[17] = 0x00;
00628 state.scsi.sense.available = 18;
00629
00630 switch(errcode)
00631 {
00632 case SCSI_ILL_CMD:
00633 state.scsi.sense.data[2] = 0x05;
00634 state.scsi.sense.data[12] = 0x20;
00635 state.scsi.sense.data[13] = 0x00;
00636 #if defined(DEBUG_SCSI)
00637 printf("%s: Command returns check sense status (sense: ILLEGAL COMMAND).\n",
00638 devid_string);
00639 #endif
00640 break;
00641
00642 case SCSI_LBA_RANGE:
00643 state.scsi.sense.data[2] = 0x05;
00644 state.scsi.sense.data[12] = 0x21;
00645 state.scsi.sense.data[13] = 0x00;
00646 #if defined(DEBUG_SCSI)
00647 printf("%s: Command returns check sense status (sense: LBA OUT OF RANGE).\n",
00648 devid_string);
00649 #endif
00650 break;
00651
00652 case SCSI_TOO_BIG:
00653 state.scsi.sense.data[2] = 0x05;
00654 state.scsi.sense.data[12] = 0x55;
00655 state.scsi.sense.data[13] = 0x00;
00656 #if defined(DEBUG_SCSI)
00657 printf("%s: Command returns check sense status (sense: SYSTEM RESOURCE FAILURE).\n",
00658 devid_string);
00659 #endif
00660 }
00661 }
00662
00666 static u32 lba2msf(off_t_large lba)
00667 {
00668 #define PREGAP_SECTORS 150
00669 #define CD_FRAMES_PER_SEC 75
00670 #define CD_MAX_LSN 450150
00671
00672 #define bin2bcd(x) ((x / 10) << 4) | (x % 10)
00673 int m;
00674
00675 int s;
00676
00677 int f;
00678 lba -= PREGAP_SECTORS;
00679 if(lba >= -PREGAP_SECTORS)
00680 {
00681 m = (lba + PREGAP_SECTORS) / (CD_FRAMES_PER_SEC * 60);
00682 lba -= m * (CD_FRAMES_PER_SEC * 60);
00683 s = (lba + PREGAP_SECTORS) / CD_FRAMES_PER_SEC;
00684 lba -= s * CD_FRAMES_PER_SEC;
00685 f = lba + PREGAP_SECTORS;
00686 }
00687 else
00688 {
00689 m = (lba + CD_MAX_LSN) / (CD_FRAMES_PER_SEC * 60);
00690 lba -= m * (CD_FRAMES_PER_SEC * 60);
00691 s = (lba + CD_MAX_LSN) / CD_FRAMES_PER_SEC;
00692 lba -= s * CD_FRAMES_PER_SEC;
00693 f = lba + CD_MAX_LSN;
00694 }
00695
00696 if(m > 99)
00697 m = 99;
00698
00699
00700 return bin2bcd(m) << 16 | bin2bcd(s) << 8 | bin2bcd(f);
00701 }
00702
00715 int CDisk::do_scsi_command()
00716 {
00717 unsigned int retlen = 0;
00718 int q;
00719 int pagecode;
00720 u32 ofs = 0;
00721
00722 #if defined(DEBUG_SCSI)
00723 printf("%s: %d-byte command ", devid_string, state.scsi.cmd.written);
00724 for(unsigned int x = 0; x < state.scsi.cmd.written; x++)
00725 printf("%02x ", state.scsi.cmd.data[x]);
00726 printf("\n");
00727 #endif
00728 if(state.scsi.cmd.written < 1)
00729 return 0;
00730
00731 if(state.scsi.cmd.data[1] & 0xe0)
00732 {
00733 #if defined(DEBUG_SCSI)
00734 printf("%s: LUN selected...\n", devid_string);
00735 #endif
00736 state.scsi.lun_selected = true;
00737 }
00738
00739 if(state.scsi.lun_selected && state.scsi.cmd.data[0] != SCSICMD_INQUIRY
00740 && state.scsi.cmd.data[0] != SCSICMD_REQUEST_SENSE)
00741 {
00742 FAILURE_1(NotImplemented, "%s: LUN not supported!\n", devid_string);
00743 }
00744
00745 switch(state.scsi.cmd.data[0])
00746 {
00747 case SCSICMD_TEST_UNIT_READY:
00748 #if defined(DEBUG_SCSI)
00749 printf("%s: TEST UNIT READY.\n", devid_string);
00750 #endif
00751
00752
00753 do_scsi_error(SCSI_OK);
00754 break;
00755
00756 case SCSICMD_REQUEST_SENSE:
00757 #if defined(DEBUG_SCSI)
00758 printf("%s: REQUEST SENSE.\n", devid_string);
00759 #endif
00760 retlen = state.scsi.cmd.data[4];
00761
00762
00763 if(!state.scsi.sense.available)
00764 {
00765 #if defined(DEBUG_SCSI)
00766 printf("%s: NO SENSE.\n", devid_string);
00767 #endif
00768 state.scsi.sense.data[0] = 0xf0;
00769 state.scsi.sense.data[1] = 0x00;
00770 state.scsi.sense.data[2] = 0x00;
00771 state.scsi.sense.data[3] = 0x00;
00772 state.scsi.sense.data[4] = 0x00;
00773 state.scsi.sense.data[5] = 0x00;
00774 state.scsi.sense.data[6] = 0x00;
00775 state.scsi.sense.data[7] = 10;
00776 state.scsi.sense.data[8] = 0x00;
00777 state.scsi.sense.data[9] = 0x00;
00778 state.scsi.sense.data[10] = 0x00;
00779 state.scsi.sense.data[11] = 0x00;
00780 state.scsi.sense.data[12] = 0x00;
00781 state.scsi.sense.data[13] = 0x00;
00782 state.scsi.sense.data[14] = 0x00;
00783 state.scsi.sense.data[15] = 0x00;
00784 state.scsi.sense.data[16] = 0x00;
00785 state.scsi.sense.data[17] = 0x00;
00786 state.scsi.sense.available = 18;
00787 }
00788
00789 #if defined(DEBUG_SCSI)
00790 printf("%s: Returning data: ", devid_string);
00791 for(unsigned int x1 = 0; x1 < state.scsi.sense.available; x1++)
00792 printf("%02x ", state.scsi.sense.data[x1]);
00793 printf("\n");
00794 #endif
00795 state.scsi.dati.read = 0;
00796 state.scsi.dati.available = retlen;
00797 memcpy(state.scsi.dati.data, state.scsi.sense.data,
00798 state.scsi.sense.available);
00799 for(unsigned int x2 = state.scsi.sense.available; x2 < retlen; x2++)
00800 state.scsi.dati.data[x2] = 0;
00801
00802 do_scsi_error(SCSI_OK);
00803 break;
00804
00805 case SCSICMD_INQUIRY:
00806 {
00807 #if defined(DEBUG_SCSI)
00808 printf("%s: INQUIRY.\n", devid_string);
00809 #endif
00810 if((state.scsi.cmd.data[1] & 0x1e) != 0x00)
00811 {
00812 FAILURE_2(NotImplemented,
00813 "%s: Don't know how to handle INQUIRY with cmd[1]=0x%02x.\n",
00814 devid_string, state.scsi.cmd.data[1]);
00815 break;
00816 }
00817
00818 u8 qual_dev = state.scsi.lun_selected ? 0x7F : (cdrom() ? 0x05 : 0x00);
00819
00820 retlen = state.scsi.cmd.data[4];
00821 state.scsi.dati.data[0] = qual_dev;
00822 if(state.scsi.cmd.data[1] & 0x01)
00823 {
00824
00825
00826 switch(state.scsi.cmd.data[2])
00827 {
00828 case 0x00:
00829
00830
00831
00832
00833 state.scsi.dati.data[1] = 0x00;
00834 state.scsi.dati.data[2] = 0x00;
00835 state.scsi.dati.data[3] = 0x02;
00836 state.scsi.dati.data[4] = 0x00;
00837 state.scsi.dati.data[5] = 0x80;
00838 break;
00839
00840 case 0x80:
00841 char serial_number[20];
00842 sprintf(serial_number, "SRL%04x", scsi_initiator_id[0] * 0x0101);
00843
00844
00845 state.scsi.dati.data[1] = 0x80;
00846 state.scsi.dati.data[2] = 0x00;
00847 state.scsi.dati.data[3] = (u8) strlen(serial_number);
00848 memcpy(&state.scsi.dati.data[4], serial_number, strlen(serial_number));
00849 break;
00850
00851 default:
00852 #if 1
00853 FAILURE_1(NotImplemented,
00854 "Don't know format for vital product data page %02x!!\n", state.scsi.cmd.data[2]);
00855 #else
00856 state.scsi.dati.data[1] = state.scsi.cmd.data[2];
00857 state.scsi.dati.data[2] = 0x00;
00858 #endif
00859 }
00860 }
00861 else
00862 {
00863
00864
00865 if(retlen < 36)
00866 {
00867 printf("%s: SCSI inquiry len=%i, <36!\n", devid_string, retlen);
00868 retlen = 36;
00869 }
00870
00871 state.scsi.dati.data[1] = 0;
00872 state.scsi.dati.data[2] = 0x02;
00873 state.scsi.dati.data[3] = 0x02;
00874 state.scsi.dati.data[4] = 32;
00875 state.scsi.dati.data[5] = 0;
00876 state.scsi.dati.data[6] = 0x04;
00877 state.scsi.dati.data[7] = 0x60;
00878
00879
00880 memcpy(&(state.scsi.dati.data[8]), "DEC RZ58 (C) DEC2000", 28);
00881
00882
00883 if(cdrom())
00884 {
00885 state.scsi.dati.data[1] = 0x80;
00886
00887
00888 memcpy(&(state.scsi.dati.data[8]), "DEC RRD42 (C) DEC 4.5d", 28);
00889 }
00890 }
00891
00892 state.scsi.dati.read = 0;
00893 state.scsi.dati.available = retlen;
00894
00895 #if defined(DEBUG_SCSI)
00896 printf("%s: Returning data: ", devid_string);
00897 for(unsigned int x1 = 0; x1 < 36; x1++)
00898 printf("%02x ", state.scsi.dati.data[x1]);
00899 printf("\n");
00900 #endif
00901 do_scsi_error(SCSI_OK);
00902 }
00903 break;
00904
00905 case SCSICMD_MODE_SENSE:
00906 case SCSICMD_MODE_SENSE_10:
00907 #if defined(DEBUG_SCSI)
00908 printf("%s: MODE SENSE.\n", devid_string);
00909 #endif
00910 {
00911 int num_blk_desc = 1;
00912
00913 if(state.scsi.cmd.data[0] == SCSICMD_MODE_SENSE)
00914 {
00915 q = 4;
00916 retlen = state.scsi.cmd.data[4];
00917 state.scsi.dati.data[0] = retlen;
00918 state.scsi.dati.data[1] = cdrom() ? 0x01 : 0x00;
00919 state.scsi.dati.data[2] = 0x00;
00920 state.scsi.dati.data[3] = 8 * num_blk_desc;
00921 }
00922 else
00923 {
00924 q = 8;
00925 retlen = state.scsi.cmd.data[7] * 256 + state.scsi.cmd.data[8];
00926 state.scsi.dati.data[0] = (u8) (retlen >> 8);
00927 state.scsi.dati.data[1] = (u8) retlen;
00928 state.scsi.dati.data[2] = cdrom() ? 0x01 : 0x00;
00929 state.scsi.dati.data[3] = 0x00;
00930 state.scsi.dati.data[4] = 0x00;
00931 state.scsi.dati.data[5] = 0x00;
00932 state.scsi.dati.data[6] = (u8) ((8 * num_blk_desc) >> 8);
00933 state.scsi.dati.data[7] = (u8) (8 * num_blk_desc);
00934 }
00935
00936 if((state.scsi.cmd.data[2] & 0xc0) > 0x40)
00937 {
00938 FAILURE_2(NotImplemented, "%s: mode sense, cmd[2] = 0x%02x.\n",
00939 devid_string, state.scsi.cmd.data[2]);
00940 }
00941
00942 bool changeable = ((state.scsi.cmd.data[2] & 0xc0) == 0x40);
00943
00944
00945 if(retlen > DATI_BUFSZ)
00946 {
00947 printf("%s: read too big (%d)\n", devid_string, retlen);
00948 do_scsi_error(SCSI_TOO_BIG);
00949 break;
00950 }
00951
00952 state.scsi.dati.read = 0;
00953 state.scsi.dati.available = retlen;
00954 pagecode = state.scsi.cmd.data[2] & 0x3f;
00955
00956
00957 state.scsi.dati.data[q++] = 0x00;
00958 state.scsi.dati.data[q++] = 0;
00959 state.scsi.dati.data[q++] = 0;
00960 state.scsi.dati.data[q++] = 0;
00961 state.scsi.dati.data[q++] = 0x00;
00962 state.scsi.dati.data[q++] = (u8) (get_block_size() >> 16) & 255;
00963 state.scsi.dati.data[q++] = (u8) (get_block_size() >> 8) & 255;
00964 state.scsi.dati.data[q++] = (u8) (get_block_size() >> 0) & 255;
00965
00966 for(unsigned int x1 = q; x1 < retlen; x1++)
00967 state.scsi.dati.data[x1] = 0;
00968
00969 do_scsi_error(SCSI_OK);
00970
00971
00972
00973 switch(pagecode)
00974 {
00975 case SCSIMP_VENDOR:
00976
00977 break;
00978
00979 case SCSIMP_READ_WRITE_ERRREC:
00980 state.scsi.dati.data[q + 0] = pagecode;
00981 state.scsi.dati.data[q + 1] = 10;
00982 break;
00983
00984 case SCSIMP_FORMAT_PARAMS:
00985 state.scsi.dati.data[q + 0] = pagecode;
00986 state.scsi.dati.data[q + 1] = 22;
00987 if(!changeable)
00988 {
00989
00990
00991 state.scsi.dati.data[q + 10] = 0;
00992 state.scsi.dati.data[q + 11] = (u8) get_sectors();
00993
00994
00995 state.scsi.dati.data[q + 12] = (u8) (get_block_size() >> 8) & 255;
00996 state.scsi.dati.data[q + 13] = (u8) (get_block_size() >> 0) & 255;
00997 }
00998 break;
00999
01000 case SCSIMP_RIGID_GEOMETRY:
01001 state.scsi.dati.data[q + 0] = pagecode;
01002 state.scsi.dati.data[q + 1] = 22;
01003 if(!changeable)
01004 {
01005 state.scsi.dati.data[q + 2] = (u8) (get_cylinders() >> 16) & 255;
01006 state.scsi.dati.data[q + 3] = (u8) (get_cylinders() >> 8) & 255;
01007 state.scsi.dati.data[q + 4] = (u8) get_cylinders() & 255;
01008 state.scsi.dati.data[q + 5] = (u8) get_heads();
01009
01010
01011 state.scsi.dati.data[q + 20] = (7200 >> 8) & 255;
01012 state.scsi.dati.data[q + 21] = 7200 & 255;
01013 }
01014 break;
01015
01016 case SCSIMP_FLEX_PARAMS:
01017 if(cdrom())
01018 {
01019 FAILURE_1(NotImplemented,
01020 "%s: CD-ROM write parameter page not implemented.\n", devid_string);
01021 }
01022
01023 state.scsi.dati.data[q + 0] = pagecode;
01024 state.scsi.dati.data[q + 1] = 0x1e;
01025 if(!changeable)
01026 {
01027
01028
01029 state.scsi.dati.data[q + 2] = ((5000) >> 8) & 255;
01030 state.scsi.dati.data[q + 3] = (5000) & 255;
01031
01032 state.scsi.dati.data[q + 4] = (u8) get_heads();
01033 state.scsi.dati.data[q + 5] = (u8) get_sectors();
01034
01035
01036 state.scsi.dati.data[q + 6] = (u8) (get_block_size() >> 8) & 255;
01037 state.scsi.dati.data[q + 7] = (u8) (get_block_size() >> 0) & 255;
01038
01039 state.scsi.dati.data[q + 8] = (u8) (get_cylinders() >> 8) & 255;
01040 state.scsi.dati.data[q + 9] = (u8) get_cylinders() & 255;
01041
01042
01043 state.scsi.dati.data[q + 28] = (7200 >> 8) & 255;
01044 state.scsi.dati.data[q + 29] = 7200 & 255;
01045 }
01046 break;
01047
01048 case SCSIMP_CACHING:
01049 state.scsi.dati.data[q + 0] = pagecode;
01050 state.scsi.dati.data[q + 1] = 0x12;
01051 if(!changeable)
01052 {
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 state.scsi.dati.data[q + 2] = 0x0a;
01064
01065 state.scsi.dati.data[q + 3] = 0;
01066 state.scsi.dati.data[q + 4] = 0x00;
01067 state.scsi.dati.data[q + 5] = 0x00;
01068 state.scsi.dati.data[q + 6] = 0;
01069 state.scsi.dati.data[q + 7] = 0;
01070
01071 state.scsi.dati.data[q + 8] = 0;
01072 state.scsi.dati.data[q + 9] = 0;
01073
01074 state.scsi.dati.data[q + 10] = 0;
01075 state.scsi.dati.data[q + 11] = 0;
01076
01077 state.scsi.dati.data[q + 12] = 0;
01078 state.scsi.dati.data[q + 13] = 0;
01079 state.scsi.dati.data[q + 14] = 0;
01080 state.scsi.dati.data[q + 15] = 0;
01081
01082 state.scsi.dati.data[q + 16] = 0;
01083 state.scsi.dati.data[q + 17] = 0;
01084 state.scsi.dati.data[q + 18] = 0;
01085 state.scsi.dati.data[q + 19] = 0;
01086 }
01087 break;
01088
01089 case SCSIMP_CDROM_CAP:
01090 state.scsi.dati.data[q + 0] = pagecode;
01091 state.scsi.dati.data[q + 1] = 0x14;
01092 if(!changeable)
01093 {
01094 state.scsi.dati.data[q + 2] = 0x03;
01095 state.scsi.dati.data[q + 3] = 0x00;
01096 state.scsi.dati.data[q + 4] = 0x00;
01097 state.scsi.dati.data[q + 5] = 0x00;
01098 state.scsi.dati.data[q + 6] = state.scsi.locked ? 0x23 : 0x21;
01099 state.scsi.dati.data[q + 7] = 0x00;
01100 state.scsi.dati.data[q + 8] = (u8) (2800 >> 8);
01101 state.scsi.dati.data[q + 9] = (u8) (2800 >> 0);
01102 state.scsi.dati.data[q + 10] = (u8) (0 >> 8);
01103 state.scsi.dati.data[q + 11] = (u8) (0 >> 0);
01104 state.scsi.dati.data[q + 12] = (u8) (64 >> 8);
01105 state.scsi.dati.data[q + 13] = (u8) (64 >> 0);
01106 state.scsi.dati.data[q + 14] = (u8) (2800 >> 8);
01107 state.scsi.dati.data[q + 15] = (u8) (2800 >> 0);
01108 state.scsi.dati.data[q + 16] = 0;
01109 state.scsi.dati.data[q + 17] = 0;
01110 state.scsi.dati.data[q + 18] = (u8) (0 >> 8);
01111 state.scsi.dati.data[q + 19] = (u8) (0 >> 0);
01112 state.scsi.dati.data[q + 20] = (u8) (0 >> 8);
01113 state.scsi.dati.data[q + 21] = (u8) (0 >> 0);
01114 }
01115 break;
01116
01117 default:
01118 FAILURE_2(NotImplemented,
01119 "%s: MODE_SENSE for page %i is not yet implemented!\n", devid_string,
01120 pagecode);
01121 }
01122
01123 #if defined(DEBUG_SCSI)
01124 printf("%s: Returning data: ", devid_string);
01125 for(unsigned int x1 = 0; x1 < q + 30; x1++)
01126 printf("%02x ", state.scsi.dati.data[x1]);
01127 printf("\n");
01128 #endif
01129 }
01130 break;
01131
01132 case SCSICMD_PREVENT_ALLOW_REMOVE:
01133 if(state.scsi.cmd.data[4] & 1)
01134 {
01135 state.scsi.locked = true;
01136 #if defined(DEBUG_SCSI)
01137 printf("%s: PREVENT MEDIA REMOVAL.\n", devid_string);
01138 #endif
01139 }
01140 else
01141 {
01142 state.scsi.locked = false;
01143 #if defined(DEBUG_SCSI)
01144 printf("%s: ALLOW MEDIA REMOVAL.\n", devid_string);
01145 #endif
01146 }
01147
01148 do_scsi_error(SCSI_OK);
01149 break;
01150
01151 case SCSICMD_MODE_SELECT:
01152
01153
01154 state.scsi.dato.expected = 12;
01155 if(state.scsi.dato.written < state.scsi.dato.expected)
01156 return 2;
01157
01158 #if defined(DEBUG_SCSI)
01159 printf("%s: MODE SELECT.\n", devid_string);
01160 printf("Data: ");
01161 for(unsigned int x = 0; x < state.scsi.dato.written; x++)
01162 printf("%02x ", state.scsi.dato.data[x]);
01163 printf("\n");
01164 #endif
01165 if(state.scsi.cmd.written == 6 && state.scsi.dato.written == 12
01166 && state.scsi.dato.data[0] == 0x00
01167
01168 && state.scsi.dato.data[2] == 0x00
01169 && state.scsi.dato.data[3] == 0x08
01170 && state.scsi.dato.data[4] == 0x00
01171 && state.scsi.dato.data[5] == 0x00
01172 && state.scsi.dato.data[6] == 0x00
01173 && state.scsi.dato.data[7] == 0x00
01174 && state.scsi.dato.data[8] == 0x00)
01175 {
01176 set_block_size((state.scsi.dato.data[9] << 16) |
01177 (state.scsi.dato.data[10] << 8) | state.scsi.dato.data[11]);
01178 #if defined(DEBUG_SCSI)
01179 printf("%s: Block size set to %d.\n", devid_string, get_block_size());
01180 #endif
01181 }
01182 else
01183 {
01184 unsigned int x;
01185 printf("%s: MODE SELECT ignored.\nCommand: ", devid_string);
01186 for(x = 0; x < state.scsi.cmd.written; x++)
01187 printf("%02x ", state.scsi.cmd.data[x]);
01188 printf("\nData: ");
01189 for(x = 0; x < state.scsi.dato.written; x++)
01190 printf("%02x ", state.scsi.dato.data[x]);
01191 printf("\nThis might be an attempt to change our blocksize or something like that...\nPlease check the above data, then press enter.\n>");
01192 getchar();
01193 }
01194
01195
01196 do_scsi_error(SCSI_OK);
01197 break;
01198
01199 case SCSIBLOCKCMD_READ_CAPACITY:
01200 #if defined(DEBUG_SCSI)
01201 printf("%s: READ CAPACITY.\n", devid_string);
01202 #endif
01203 if(state.scsi.cmd.data[8] & 1)
01204 {
01205 FAILURE_1(NotImplemented,
01206 "%s: Don't know how to handle READ CAPACITY with PMI bit set.\n",
01207 devid_string);
01208 break;
01209 }
01210
01211
01212
01213 state.scsi.dati.data[0] = (u8) ((get_lba_size() - 1) >> 24) & 255;
01214 state.scsi.dati.data[1] = (u8) ((get_lba_size() - 1) >> 16) & 255;
01215 state.scsi.dati.data[2] = (u8) ((get_lba_size() - 1) >> 8) & 255;
01216 state.scsi.dati.data[3] = (u8) ((get_lba_size() - 1) >> 0) & 255;
01217
01218 state.scsi.dati.data[4] = (u8) (get_block_size() >> 24) & 255;
01219 state.scsi.dati.data[5] = (u8) (get_block_size() >> 16) & 255;
01220 state.scsi.dati.data[6] = (u8) (get_block_size() >> 8) & 255;
01221 state.scsi.dati.data[7] = (u8) (get_block_size() >> 0) & 255;
01222
01223 state.scsi.dati.read = 0;
01224 state.scsi.dati.available = 8;
01225
01226 #if defined(DEBUG_SCSI)
01227 printf("%s: Returning data: ", devid_string);
01228 for(unsigned int x1 = 0; x1 < 8; x1++)
01229 printf("%02x ", state.scsi.dati.data[x1]);
01230 printf("\n");
01231 #endif
01232 do_scsi_error(SCSI_OK);
01233 break;
01234
01235 case SCSICMD_READ:
01236 case SCSICMD_READ_10:
01237 case SCSICMD_READ_12:
01238 case SCSICMD_READ_CD:
01239 #if defined(DEBUG_SCSI)
01240 printf("%s: READ.\n", devid_string);
01241 #endif
01242
01243
01244
01245
01246
01247
01248 if(state.scsi.cmd.data[0] == SCSICMD_READ)
01249 {
01250
01251
01252
01253
01254
01255
01256
01257 ofs = ((state.scsi.cmd.data[1] & 0x1f) << 16) + (state.scsi.cmd.data[2] << 8) + state.scsi.cmd.data[3];
01258 retlen = state.scsi.cmd.data[4];
01259 if(retlen == 0)
01260 retlen = 256;
01261 }
01262 else if(state.scsi.cmd.data[0] == SCSICMD_READ_10)
01263 {
01264
01265
01266
01267 ofs = (state.scsi.cmd.data[2] << 24) + (state.scsi.cmd.data[3] << 16) + (state.scsi.cmd.data[4] << 8) + state.scsi.cmd.data[5];
01268 retlen = (state.scsi.cmd.data[7] << 8) + state.scsi.cmd.data[8];
01269 }
01270 else if(state.scsi.cmd.data[0] == SCSICMD_READ_12)
01271 {
01272
01273
01274
01275 ofs = (state.scsi.cmd.data[2] << 24) + (state.scsi.cmd.data[3] << 16) + (state.scsi.cmd.data[4] << 8) + state.scsi.cmd.data[5];
01276 retlen = (state.scsi.cmd.data[6] << 24) + (state.scsi.cmd.data[7] << 16) + (state.scsi.cmd.data[8] << 8) + state.scsi.cmd.data[9];
01277 }
01278 else if(state.scsi.cmd.data[0] == SCSICMD_READ_CD)
01279 {
01280 if(state.scsi.cmd.data[9] != 0x10)
01281 {
01282 FAILURE_2(NotImplemented, "%s: READ CD issued with data type %02x.\n",
01283 devid_string, state.scsi.cmd.data[9]);
01284 }
01285
01286
01287
01288 ofs = (state.scsi.cmd.data[2] << 24) + (state.scsi.cmd.data[3] << 16) + (state.scsi.cmd.data[4] << 8) + state.scsi.cmd.data[5];
01289 retlen = (state.scsi.cmd.data[6] << 16) +
01290 (state.scsi.cmd.data[7] << 8) +
01291 state.scsi.cmd.data[8];
01292 }
01293
01294
01295 if((ofs + retlen) > get_lba_size())
01296 {
01297 do_scsi_error(SCSI_LBA_RANGE);
01298 break;
01299 }
01300
01301
01302 if(retlen > DATI_BUFSZ)
01303 {
01304 printf("%s: read too big (%d)\n", devid_string, retlen);
01305 do_scsi_error(SCSI_TOO_BIG);
01306 break;
01307 }
01308
01309
01310 seek_block(ofs);
01311 read_blocks(state.scsi.dati.data, retlen);
01312 state.scsi.dati.read = 0;
01313 state.scsi.dati.available = retlen * get_block_size();
01314
01315 #if defined(DEBUG_SCSI)
01316 printf("%s: READ ofs=%d size=%d\n", devid_string, ofs, retlen);
01317 #endif
01318 do_scsi_error(SCSI_OK);
01319 break;
01320
01321 case SCSICMD_READ_LONG:
01322 #if defined(DEBUG_SCSI)
01323 printf("%s: READ_LONG.\n", devid_string);
01324 #endif
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 ofs = (state.scsi.cmd.data[2] << 24) + (state.scsi.cmd.data[3] << 16) + (state.scsi.cmd.data[4] << 8) + state.scsi.cmd.data[5];
01335 retlen = (state.scsi.cmd.data[7] << 8) + state.scsi.cmd.data[8];
01336
01337 state.scsi.stat.available = 1;
01338 state.scsi.stat.data[0] = 0;
01339 state.scsi.stat.read = 0;
01340 state.scsi.msgi.available = 1;
01341 state.scsi.msgi.data[0] = 0;
01342 state.scsi.msgi.read = 0;
01343
01344
01345 if(retlen != 514)
01346 {
01347 do_scsi_error(SCSI_ILL_CMD);
01348 break;
01349 }
01350
01351
01352 if((ofs + 1) > get_lba_size())
01353 {
01354 do_scsi_error(SCSI_LBA_RANGE);
01355 break;
01356 }
01357
01358
01359 if(retlen > DATI_BUFSZ)
01360 {
01361 printf("%s: read too big (%d)\n", devid_string, retlen);
01362 do_scsi_error(SCSI_TOO_BIG);
01363 break;
01364 }
01365
01366
01367 seek_block(ofs);
01368 read_blocks(state.scsi.dati.data, 1);
01369 for(unsigned int x1 = get_block_size(); x1 < retlen; x1++)
01370 state.scsi.dati.data[x1] = 0;
01371 state.scsi.dati.read = 0;
01372 state.scsi.dati.available = retlen;
01373 do_scsi_error(SCSI_OK);
01374 break;
01375
01376 case SCSICMD_WRITE:
01377 case SCSICMD_WRITE_10:
01378 #if defined(DEBUG_SCSI)
01379 printf("%s: WRITE.\n", devid_string);
01380 #endif
01381 if(state.scsi.cmd.data[0] == SCSICMD_WRITE)
01382 {
01383
01384
01385
01386
01387
01388
01389
01390 ofs = ((state.scsi.cmd.data[1] & 0x1f) << 16) + (state.scsi.cmd.data[2] << 8) + state.scsi.cmd.data[3];
01391 retlen = state.scsi.cmd.data[4];
01392 if(retlen == 0)
01393 retlen = 256;
01394 }
01395 else
01396 {
01397
01398
01399
01400
01401 ofs = (state.scsi.cmd.data[2] << 24) + (state.scsi.cmd.data[3] << 16) + (state.scsi.cmd.data[4] << 8) + state.scsi.cmd.data[5];
01402 retlen = (state.scsi.cmd.data[7] << 8) + state.scsi.cmd.data[8];
01403 }
01404
01405
01406 if(((ofs + retlen)) > get_lba_size())
01407 {
01408 do_scsi_error(SCSI_LBA_RANGE);
01409 break;
01410 }
01411
01412
01413 if(retlen * get_block_size() > DATO_BUFSZ)
01414 {
01415 printf("%s: write too big (%d)\n", devid_string,
01416 (int) (retlen * get_block_size()));
01417 do_scsi_error(SCSI_TOO_BIG);
01418 break;
01419 }
01420
01421 state.scsi.dato.expected = retlen * get_block_size();
01422
01423 if(state.scsi.dato.written < state.scsi.dato.expected)
01424 return 2;
01425
01426
01427 seek_block(ofs);
01428 write_blocks(state.scsi.dato.data, retlen);
01429
01430 #if defined(DEBUG_SCSI)
01431 printf("%s: WRITE ofs=%d size=%d\n", devid_string, ofs, retlen);
01432 #endif
01433 do_scsi_error(SCSI_OK);
01434 break;
01435
01436 case SCSICMD_SYNCHRONIZE_CACHE:
01437 #if defined(DEBUG_SCSI)
01438 printf("%s: SYNCHRONIZE CACHE.\n", devid_string);
01439 #endif
01440 do_scsi_error(SCSI_OK);
01441 break;
01442
01443 case SCSICDROM_READ_TOC:
01444 {
01445 #if defined(DEBUG_SCSI)
01446 printf("%s: CDROM READ TOC.\n", devid_string);
01447 #endif
01448 if(state.scsi.cmd.data[2] & 0x0f)
01449 {
01450 FAILURE_2(NotImplemented,
01451 "%s: I don't understand READ TOC/PMA/ATIP with format %01x.\n",
01452 devid_string, state.scsi.cmd.data[2] & 0x0f);
01453 }
01454
01455 if(state.scsi.cmd.data[6] > 1 && state.scsi.cmd.data[6] != 0xAA)
01456 {
01457 FAILURE_2(InvalidArgument, "%s: I don't know CD-ROM track 0x%02x.\n",
01458 devid_string, state.scsi.cmd.data[6]);
01459 }
01460
01461 retlen = state.scsi.cmd.data[7] * 256 + state.scsi.cmd.data[8];
01462
01463 state.scsi.dati.available = retlen;
01464 state.scsi.dati.read = 0;
01465
01466 int q = 2;
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 state.scsi.dati.data[q++] = 1;
01477 state.scsi.dati.data[q++] = 1;
01478 if(state.scsi.cmd.data[6] <= 1)
01479 {
01480 state.scsi.dati.data[q++] = 0;
01481 state.scsi.dati.data[q++] = 0x14;
01482 state.scsi.dati.data[q++] = 1;
01483 state.scsi.dati.data[q++] = 0;
01484 if(state.scsi.cmd.data[1] & 0x02)
01485 {
01486 u32 x = lba2msf(0);
01487 state.scsi.dati.data[q++] = 0;
01488 state.scsi.dati.data[q++] = (x & 0xff0000) >> 16;
01489 state.scsi.dati.data[q++] = (x & 0xff00) >> 8;
01490 state.scsi.dati.data[q++] = x & 0xff;
01491 }
01492 else
01493 {
01494 state.scsi.dati.data[q++] = 0 >> 24;
01495 state.scsi.dati.data[q++] = 0 >> 16;
01496 state.scsi.dati.data[q++] = 0 >> 8;
01497 state.scsi.dati.data[q++] = 0;
01498 }
01499 }
01500
01501 state.scsi.dati.data[q++] = 0;
01502 state.scsi.dati.data[q++] = 0x16;
01503 state.scsi.dati.data[q++] = 0xAA;
01504 state.scsi.dati.data[q++] = 0;
01505 if(state.scsi.cmd.data[1] & 0x02)
01506 {
01507 u32 x = lba2msf(get_lba_size());
01508 state.scsi.dati.data[q++] = 0;
01509 state.scsi.dati.data[q++] = (x & 0xff0000) >> 16;
01510 state.scsi.dati.data[q++] = (x & 0xff00) >> 8;
01511 state.scsi.dati.data[q++] = x & 0xff;
01512 }
01513 else
01514 {
01515 state.scsi.dati.data[q++] = (u8) (get_lba_size() >> 24);
01516 state.scsi.dati.data[q++] = (u8) (get_lba_size() >> 16);
01517 state.scsi.dati.data[q++] = (u8) (get_lba_size() >> 8);
01518 state.scsi.dati.data[q++] = (u8) get_lba_size();
01519 }
01520
01521 state.scsi.dati.data[0] = (u8) (q >> 8);
01522 state.scsi.dati.data[1] = (u8) q;
01523
01524 #if defined(DEBUG_SCSI)
01525 printf("%s: Returning data: ", devid_string);
01526 for(unsigned int x1 = 0; x1 < q; x1++)
01527 printf("%02x ", state.scsi.dati.data[x1]);
01528 printf("\n");
01529 #endif
01530 do_scsi_error(SCSI_OK);
01531 }
01532 break;
01533
01534 case SCSICDRRW_FORMAT:
01535 case SCSICDRRW_READ_DISC_INFO:
01536 case SCSICDRRW_READ_TRACK_INFO:
01537 case SCSICDRRW_RESERVE_TRACK:
01538 case SCSICDRRW_SEND_OPC_INFO:
01539 case SCSICDRRW_REPAIR_TRACK:
01540 case SCSICDRRW_READ_MASTER_CUE:
01541 case SCSICDRRW_CLOSE_TRACK:
01542 case SCSICDRRW_READ_BUFFER_CAP:
01543 case SCSICDRRW_SEND_CUE_SHEET:
01544 case SCSICDRRW_BLANK:
01545
01546
01547
01548 #if defined(DEBUG_SCSI)
01549 printf("%s: CD-R/RW specific.\n", devid_string);
01550 #endif
01551 do_scsi_error(SCSI_ILL_CMD);
01552 break;
01553
01554 default:
01555 FAILURE_2(NotImplemented, "%s: Unknown SCSI command 0x%02x.\n",
01556 devid_string, state.scsi.cmd.data[0]);
01557 }
01558
01559 return 0;
01560 }
01561
01569 int CDisk::do_scsi_message()
01570 {
01571 unsigned int msg;
01572 unsigned int msglen;
01573
01574 msg = 0;
01575 while(msg < state.scsi.msgo.written)
01576 {
01577 if(state.scsi.msgo.data[msg] & 0x80)
01578 {
01579
01580
01581 #if defined(DEBUG_SCSI)
01582 printf("%s: MSG: identify", devid_string);
01583 #endif
01584 if(state.scsi.msgo.data[msg] & 0x40)
01585 {
01586 #if defined(DEBUG_SCSI)
01587 printf(" w/disconnect priv");
01588 #endif
01589
01590
01591 }
01592
01593 if(state.scsi.msgo.data[msg] & 0x07)
01594 {
01595
01596
01597 #if defined(DEBUG_SCSI)
01598 printf(" for lun %d%", state.scsi.msgo.data[msg] & 0x07);
01599 #endif
01600 state.scsi.lun_selected = true;
01601 }
01602
01603 #if defined(DEBUG_SCSI)
01604 printf("\n");
01605 #endif
01606 msg++;
01607 }
01608 else
01609 {
01610 switch(state.scsi.msgo.data[msg])
01611 {
01612 case 0x01:
01613 #if defined(DEBUG_SCSI)
01614 printf("%s: MSG: extended: ", devid_string);
01615 #endif
01616 msglen = state.scsi.msgo.data[msg + 1];
01617 msg += 2;
01618 switch(state.scsi.msgo.data[msg])
01619 {
01620 case 0x01:
01621 {
01622 #if defined(DEBUG_SCSI)
01623 printf("SDTR.\n");
01624 #endif
01625 state.scsi.msgi.available = msglen + 2;
01626 state.scsi.msgi.data[0] = 0x01;
01627 state.scsi.msgi.data[1] = msglen;
01628 for(unsigned int x = 0; x < msglen; x++)
01629 state.scsi.msgi.data[2 + x] = state.scsi.msgo.data[msg + x];
01630 }
01631 break;
01632
01633 case 0x03:
01634 {
01635 #if defined(DEBUG_SCSI)
01636 printf("WDTR.\n");
01637 #endif
01638 state.scsi.msgi.available = msglen + 2;
01639 state.scsi.msgi.data[0] = 0x01;
01640 state.scsi.msgi.data[1] = msglen;
01641 for(unsigned int x = 0; x < msglen; x++)
01642 state.scsi.msgi.data[2 + x] = state.scsi.msgo.data[msg + x];
01643 }
01644 break;
01645
01646 default:
01647 FAILURE_2(NotImplemented,
01648 "%s: MSG: don't understand extended message %02x.\n", devid_string,
01649 state.scsi.msgo.data[msg]);
01650 }
01651
01652 msg += msglen;
01653 break;
01654
01655 default:
01656 FAILURE_2(NotImplemented, "%s: MSG: don't understand message %02x.\n",
01657 devid_string, state.scsi.msgo.data[msg]);
01658 }
01659 }
01660 }
01661
01662
01663 if(state.scsi.msgi.available)
01664 return SCSI_PHASE_MSG_IN;
01665 else
01666 return SCSI_PHASE_COMMAND;
01667 }
01668
01669 static int primes_54[54] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
01670 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
01671 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
01672 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
01673 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
01674 233, 239, 241, 251};
01675
01676
01677 static int pri16[16][6] = { {4,0,0,0, 0, 0},
01678 {0,1,1,0, 0, 0},
01679 {1,0,0,1, 0, 0},
01680 {0,0,0,0, 0, 1},
01681 {2,1,0,0, 0, 0},
01682 {0,0,0,0, 1, 0},
01683 {1,0,1,0, 0, 0},
01684 {0,2,0,0, 0, 0},
01685 {3,0,0,0, 0, 0},
01686 {0,0,0,1, 0, 0},
01687 {1,1,0,0, 0, 0},
01688 {0,0,1,0, 0, 0},
01689 {2,0,0,0, 0, 0},
01690 {0,1,0,0, 0, 0},
01691 {1,0,0,0, 0, 0},
01692 {0,0,0,0, 0, 0}};
01693 static off_t_large get_primes(off_t_large value, int pri[54])
01694 {
01695 int i;
01696 for(i = 0; i < 54; i++)
01697 {
01698 pri[i] = 0;
01699 while(!(value % primes_54[i]))
01700 {
01701 pri[i]++;
01702 value /= primes_54[i];
01703 }
01704 }
01705
01706 return value;
01707 }
01708
01712 #define MAX_HD 16
01713 #define MAX_SEC 50
01714
01715 void CDisk::determine_layout()
01716 {
01717 int disk_primes[54];
01718 int compare_primes[54];
01719
01720 long heads_sectors = 0;
01721 long c_heads = 0;
01722 bool b;
01723 int prime;
01724
01725 get_primes(get_lba_size(), disk_primes);
01726
01727 for(heads_sectors = MAX_SEC * MAX_HD; heads_sectors > 0; heads_sectors--)
01728 {
01729 if(get_primes(heads_sectors, compare_primes) > 1)
01730 continue;
01731
01732 for(c_heads = MAX_HD; c_heads > 0; c_heads--)
01733 {
01734 b = true;
01735 for(prime = 0; prime < 6; prime++)
01736 {
01737 if(pri16[16 - c_heads][prime] > compare_primes[prime])
01738 {
01739 b = false;
01740 break;
01741 }
01742 }
01743
01744 if(b)
01745 break;
01746 }
01747
01748 if(heads_sectors / c_heads > MAX_SEC)
01749 continue;
01750
01751 b = true;
01752 for(prime = 0; prime < 54; prime++)
01753 {
01754 if(compare_primes[prime] > disk_primes[prime])
01755 {
01756 b = false;
01757 break;
01758 }
01759 }
01760
01761 if(b)
01762 break;
01763 }
01764
01765 heads = c_heads;
01766 sectors = heads_sectors / c_heads;
01767
01768
01769
01770 cylinders = get_lba_size() / heads / sectors;
01771 }