static int ipslr_write_args(ipslr_handle_t *p, int n, ...) { va_list ap; uint8_t cmd[8] = { 0xf0, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t buf[4*n]; int res; int i; uint32_t data; va_start(ap, n); if (is_k10d(p) || is_k20d(p)) { /* All at once */ for (i=0; i<n; i++) { data = va_arg(ap, uint32_t); buf[4*i+0] = data >> 24; buf[4*i+1] = data >> 16; buf[4*i+2] = data >> 8; buf[4*i+3] = data; } cmd[4] = 4*n; res = scsi_write(p, cmd, sizeof(cmd), buf, 4*n); if (res != PSLR_OK) { va_end(ap); return res; } } else { /* Arguments one by one */ for (i=0; i<n; i++) {
static inline bool scsi_cmd_write16(SCSI* scsi) { bool res = false; if (scsi->cmd.cmd_type == SCSI_CMD_16) res = scsi_write(scsi, scsi->cmd.additional_data, scsi->cmd.len); else scsi_error(scsi, SENSE_KEY_ILLEGAL_REQUEST, ASQ_CDB_DECRYPTION_ERROR); #if (SCSI_DEBUG_FLOW) printf("SCSI write16 0x%08X, %x sector(s)\n\r", scsi->cmd.address, scsi->cmd.len); #endif return res; }
res = scsi_write(p, cmd, sizeof(cmd), buf, 4*n); if (res != PSLR_OK) { va_end(ap); return res; } } else { /* Arguments one by one */ for (i=0; i<n; i++) { data = va_arg(ap, uint32_t); buf[0] = data >> 24; buf[1] = data >> 16; buf[2] = data >> 8; buf[3] = data; cmd[4] = 4; cmd[2] = i*4; res = scsi_write(p, cmd, sizeof(cmd), buf, 4); if (res != PSLR_OK) { va_end(ap); return res; } } } va_end(ap); return PSLR_OK; } /* ----------------------------------------------------------------------- */ static int command(ipslr_handle_t *p, int a, int b, int c) { uint8_t cmd[8] = { 0xf0, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int fsrestore(int argc, char *argv[]) { int i, j, status; int block, bytes; int blk, nblks, size, mark; struct partition *pp; printf("Current SCSI device = ID %d\n", scsi_device); getline("Is it sure ? (y/n) ", cons_buf); if ((cons_buf[0] != 'y') && (cons_buf[0] != 'Y')) return ST_ERROR; st_rewind(rst0); st_skip(rst0); status = stread(rst0, index, LABEL_SIZE); st_skip(rst0); for (i = 0; i < MAXPARTITIONS; i++) { pp = &(lp->d_partitions[i]); if (pp->p_size > 0) { printf("%c: ", i + 'A'); printf("size = %d(0x%s), ", pp->p_size, hexstr(pp->p_size, 8)); printf("offset = %d(0x%s)\n", pp->p_offset, hexstr(pp->p_offset, 8)); blk = pp->p_offset; nblks = pp->p_size; size = nblks << DEV_BSHIFT; block = BUF_BLOCK; bytes = BUF_BYTES; mark = nblks / block; if (nblks % block) mark++; for (j = 0; j < mark; j++) printf("-"); for (j = 0; j < mark; j++) printf("%c", '\x08'); while (nblks > 0) { if (nblks < block) { block = nblks; bytes = nblks << DEV_BSHIFT; } if (stread(rst0, dump_buf, bytes) != bytes) { printf("tape read failed !!!\n"); return ST_ERROR; } if (!scsi_write(blk, dump_buf, bytes)) { printf("disk write failed !!!\n"); return ST_ERROR; } blk += block; nblks -= block; size -= bytes; printf("#"); } st_skip(rst0); printf("\n\n"); } } return ST_NORMAL; }
/********************************************************************************* * scsi command intepreter */ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { switch (argc) { case 0: case 1: return CMD_RET_USAGE; case 2: if (strncmp(argv[1],"res",3) == 0) { printf("\nReset SCSI\n"); scsi_bus_reset(); scsi_scan(1); return 0; } if (strncmp(argv[1],"inf",3) == 0) { int i; for (i=0; i<CONFIG_SYS_SCSI_MAX_DEVICE; ++i) { if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN) continue; /* list only known devices */ printf ("SCSI dev. %d: ", i); dev_print(&scsi_dev_desc[i]); } return 0; } if (strncmp(argv[1],"dev",3) == 0) { if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CONFIG_SYS_SCSI_MAX_DEVICE)) { printf("\nno SCSI devices available\n"); return 1; } printf ("\n Device %d: ", scsi_curr_dev); dev_print(&scsi_dev_desc[scsi_curr_dev]); return 0; } if (strncmp(argv[1],"scan",4) == 0) { scsi_scan(1); return 0; } if (strncmp(argv[1],"part",4) == 0) { int dev, ok; for (ok=0, dev=0; dev<CONFIG_SYS_SCSI_MAX_DEVICE; ++dev) { if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) { ok++; if (dev) printf("\n"); debug ("print_part of %x\n",dev); print_part(&scsi_dev_desc[dev]); } } if (!ok) printf("\nno SCSI devices available\n"); return 1; } return CMD_RET_USAGE; case 3: if (strncmp(argv[1],"dev",3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); printf ("\nSCSI device %d: ", dev); if (dev >= CONFIG_SYS_SCSI_MAX_DEVICE) { printf("unknown device\n"); return 1; } printf ("\n Device %d: ", dev); dev_print(&scsi_dev_desc[dev]); if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { return 1; } scsi_curr_dev = dev; printf("... is now current device\n"); return 0; } if (strncmp(argv[1],"part",4) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) { print_part(&scsi_dev_desc[dev]); } else { printf ("\nSCSI device %d not available\n", dev); } return 1; } return CMD_RET_USAGE; default: /* at least 4 args */ if (strcmp(argv[1],"read") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); ulong blk = simple_strtoul(argv[3], NULL, 16); ulong cnt = simple_strtoul(argv[4], NULL, 16); ulong n; printf ("\nSCSI read: device %d block # %ld, count %ld ... ", scsi_curr_dev, blk, cnt); n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr); printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); return 0; } else if (strcmp(argv[1], "write") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); ulong blk = simple_strtoul(argv[3], NULL, 16); ulong cnt = simple_strtoul(argv[4], NULL, 16); ulong n; printf("\nSCSI write: device %d block # %ld, " "count %ld ... ", scsi_curr_dev, blk, cnt); n = scsi_write(scsi_curr_dev, blk, cnt, (ulong *)addr); printf("%ld blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return 0; } } /* switch */ return CMD_RET_USAGE; }
void DevOperate(DiscDCB *dcb, DiscReq *req) { BYTE capacity_data[CAPACITY_LENGTH]; WORD command_status,second_status; WORD block_addr, block_len; WORD done = 0; WORD size; BYTE *buf = req->Buf; INT res; BYTE sense_data[SENSE_LENGTH]; FormatReq *freq; Wait(&dcb->Lock); /* Select the appropriate command */ switch( req->DevReq.Request & FG_Mask) { case FG_Read: #ifdef DEBUG IOdebug("read pos = %d size = %d",req->Pos / dcb->SectorSize,req->Size / dcb->SectorSize); #endif size = req->Size; while( done < size ) { WORD tfr = size - done; WORD position = (req->Pos / dcb->SectorSize) + (done/dcb->SectorSize); command_status = 8;/* make loop happen once*/ if ( tfr > MAX_TFR ) { tfr = MAX_TFR; } while (command_status == 8) { res = scsi_read(dcb->Link,dcb->Table,dcb->DeviceId,0,position,tfr,dcb->SectorSize,buf,&command_status); } if ( ( res < 0 ) || ( command_status ne 0 )) { command_status = 8; while (command_status == 8) { res = scsi_read(dcb->Link,dcb->Table,dcb->DeviceId,0,position,tfr,dcb->SectorSize,buf,&command_status); } } done += tfr; buf += tfr; } req->DevReq.Result = command_status; if ( req->DevReq.Result eq 0 ) req->Actual = req->Size; else req->Actual = 0; break; case FG_Write: #ifdef DEBUG IOdebug("write pos = %d size = %d",req->Pos / dcb->SectorSize,req->Size / dcb->SectorSize); #endif size = req->Size; while( done < size ) { WORD tfr = size - done; WORD position = (req->Pos / dcb->SectorSize) + (done/dcb->SectorSize); command_status = 8; /* make loop happen once*/ if ( tfr > MAX_TFR ) { tfr = MAX_TFR; } while (command_status == 8) { res = scsi_write(dcb->Link,dcb->Table,dcb->DeviceId,0,position,tfr,dcb->SectorSize,buf,&command_status); } if ( ( res < 0 ) || ( command_status ne 0 )) { command_status = 8; while (command_status == 8) { res = scsi_write(dcb->Link,dcb->Table,dcb->DeviceId,0,position,tfr,dcb->SectorSize,buf,&command_status); } } done += tfr; buf += tfr; } req->DevReq.Result = command_status; if ( req->DevReq.Result eq 0 ) req->Actual = req->Size; else req->Actual = 0; break; case FG_GetSize: #ifdef DEBUG IOdebug("read capacity request"); #endif command_status = 8; while (command_status == 8) { scsi_read_capacity( dcb->Link, dcb->Table, dcb->DeviceId, 0, /* lun */ 8, /* capacity length */ capacity_data, &command_status); } if ( command_status eq 0 ) { block_addr = capacity_data[0] * 0x1000000 + capacity_data[1] * 0x10000 + capacity_data[2] * 0x100 + capacity_data[3]; block_len = capacity_data[4] * 0x1000000 + capacity_data[5] * 0x10000 + capacity_data[6] * 0x100 + capacity_data[7]; req->DevReq.Result = block_addr * block_len; } break; case FG_Format: IOdebug("\rFormatting disk please wait ...."); freq = (FormatReq *)req; command_status = 8;/* so the loop happens once*/ while (command_status == 8) { scsi_mode_select( dcb->Link, dcb->Table, dcb->DeviceId, 0, 0, /* format whole disk */ dcb->SectorSize, &command_status); } command_status = 8;/* so the loop happens once*/ while (command_status == 8) { scsi_format( dcb->Link, dcb->Table, dcb->DeviceId, 0, freq->Interleave, &command_status); } /* If the disk supports the busy status we need to wait until busy goes away before giving the message that we are verifying */ command_status = 8; while (command_status == 8) { scsi_test_unit_ready( dcb->Link, dcb->Table, dcb->DeviceId, 0, &command_status); } /* some disks will queue one command so we need to wait twice to cope with this */ command_status = 8; while (command_status != 0) { IOdebug("status = %d",command_status); scsi_test_unit_ready( dcb->Link, dcb->Table, dcb->DeviceId, 0, &command_status); scsi_request_sense( dcb->Link, dcb->Table, dcb->DeviceId, 0, SENSE_LENGTH, sense_data, &command_status); IOdebug("sense =%x",sense_data[2]); } { WORD total_blocks; WORD i,j; WORD ten_cent,done = 0; BYTE *data; IOdebug("\rVerifying disk please wait ...."); data = Malloc(dcb->SectorSize); command_status = 8; /* do at least once*/ while (command_status == 8 ) { res = scsi_write(dcb->Link,dcb->Table,dcb->DeviceId,0,1,dcb->SectorSize,dcb->SectorSize,data,&command_status); } total_blocks = (dcb->SectorsPerTrack * dcb->TracksPerCyl * dcb->Cylinders); /* IOdebug("\rdisk size is %d blocks",total_blocks);*/ ten_cent = total_blocks / 10; for ( i = 1; i < total_blocks; i++) { command_status = 8; /* you know by now*/ while (command_status == 8) { res = scsi_write_quick(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&command_status); } second_status = 8; while (second_status == 8) { res = scsi_read_quick(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&second_status); } if (( i % ten_cent ) eq 0) { done += 10; IOdebug("\rVerified %d percent of disk\v",done); } if ((command_status ne 0) || (second_status ne 0)) { command_status = 8; while (command_status == 8 ) { scsi_write_quick(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&command_status); } second_status = 8; while (second_status == 8) { scsi_read_quick(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&second_status); } if (( command_status ne 0 ) || (second_status ne 0)) { IOdebug("Verifier found bad block at %d",i); for( j = 0; j < 10; j++) { command_status = 8; while (command_status == 8) { scsi_reassign_block(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&command_status); } command_status = 8; while (command_status == 8) { scsi_write_quick(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&command_status); } second_status = 8; while (second_status == 8) { scsi_read_quick(dcb->Link,dcb->Table,dcb->DeviceId,0,i,&second_status); } if ((command_status eq 0) && (second_status eq 0))break; } if (( command_status eq 0 ) && (second_status eq 0)) IOdebug("Block %d reassigned OK",i); else IOdebug("Failed to reassign block %d",i); } } } } IOdebug("Verification complete "); req->DevReq.Result = 0; break; default: break; } /* Unlock the driver */ Signal(&dcb->Lock); /* Client action */ (*req->DevReq.Action)(req); return; }
int scsi_write_sector(uint_32 lba, const uint_8 *buffer) { int r = 0; r = scsi_write(lba,1,buffer); return r; }
void scsi_proc(void) { if (USBD_ep_buffer_full(BOMS_EP_DATA_OUT)) { if (sizeof(BOMSCmd) == USBD_transfer(BOMS_EP_DATA_OUT, (uint8_t *)&BOMSCmd, sizeof(BOMSCmd))) { if (BOMSCmd.dCBWSignature == BOMS_USBC) { if (BOMSCmd.CBWCB.unit_ready.op_code == BOMS_SCSI_TEST_UNIT_READY) // SCSI Test Unit Ready { scsi_test_unit_ready(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_READ) // SCSI Read { scsi_read(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_WRITE) // SCSI Write { scsi_write(&BOMSCmd); } else if (BOMSCmd.CBWCB.inquiry.op_code == BOMS_SCSI_INQUIRY) // SCSI Inquiry { scsi_inquiry(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_REQUEST_SENSE) // SCSI Request Sense { scsi_request_sense(&BOMSCmd); } else if (BOMSCmd.CBWCB.read_capacity.op_code == BOMS_SCSI_READ_CAPACITY) // SCSI Read Capacity (10) { scsi_read_capacity(&BOMSCmd); } else if (BOMSCmd.CBWCB.read_capacity.op_code == BOMS_SCSI_READ_FORMAT_CAPACITY) // SCSI Read Format Capacity (10) { scsi_read_format_capacity(&BOMSCmd); } else if (BOMSCmd.CBWCB.mode_sense.op_code == BOMS_SCSI_MODE_SENSE) // SCSI Mode Sense { scsi_mode_sense(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_READ_CAPACITY_16) // SCSI Read Capacity (16) { scsi_read_capacity(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_PREVENT_ALLOW_REMOVAL) // SCSI Prevent Allow Removal { scsi_prevent_allow_removal(&BOMSCmd); } else { // Send IN a zero length packet. if (BOMSCmd.dCBWDataTransferLength) { USBD_stall_endpoint(BOMS_EP_DATA_IN); } boms_send_status(BOMS_STATUS_COMMAND_FAILED, &BOMSCmd); scsi_sense_illegal_request_command(); } } else { // Was not a USBC signature. boms_send_status(BOMS_STATUS_PHASE_ERROR, &BOMSCmd); scsi_sense_illegal_request_cdb(); } }else{ // Wrong command size. boms_send_status(BOMS_STATUS_COMMAND_FAILED, &BOMSCmd); scsi_sense_illegal_request_parm(); } } }