Beispiel #1
0
void test_execute_Inquiry(char* path, int evpd, int page_code) {

  struct sg_io_hdr* p_hdr = init_io_hdr();

  set_xfer_data(p_hdr, data_buffer, BLOCK_LEN * 256);
  set_sense_data(p_hdr, sense_buffer, SENSE_LEN);

  int status = 0;

  int fd = open(path, O_RDWR);
  if (fd > 0) {
    status = execute_Inquiry(fd, page_code, evpd, p_hdr);
    printf("the return status is %d\n", status);
    if (status != 0) {
      show_sense_buffer(p_hdr);
    } else {
      show_vendor(p_hdr);
      show_product(p_hdr);
      show_product_rev(p_hdr);
    }
  } else {
    printf("failed to open sg file %s\n", path);
  }
  close(fd);
  destroy_io_hdr(p_hdr);
}
Beispiel #2
0
UINT8 omti8621_device::check_disk_address(const UINT8 *cdb)
{
	UINT8 sense_code = OMTI_SENSE_CODE_NO_ERROR;
	UINT8 lun = get_lun(cdb);
	UINT16 head = cdb[1] & 0x1f;
	UINT16 sector = cdb[2] & 0x3f;
	UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3);
	UINT8 block_count = cdb[4];
	omti_disk_image_device *disk = our_disks[lun];

	UINT32 disk_track = cylinder * disk->m_heads + head;
	UINT32 disk_addr = (disk_track * disk->m_sectors) + sector;

	if (block_count > OMTI_MAX_BLOCK_COUNT) {
		LOG(("########### check_disk_address: unexpected block count %x", block_count));
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	}

	if (lun > OMTI_MAX_LUN) {
		sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY;
	} else  if (!disk->m_image->exists()) {
		sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY;
	} else  if (sector >= OMTI_MAX_BLOCK_COUNT) {
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	} else if (head >= disk->m_heads) {
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	} else if (cylinder >= disk->m_cylinders) {
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	} else if ( disk_track == diskaddr_format_bad_track && disk_track != 0) {
		sense_code = OMTI_SENSE_CODE_BAD_TRACK;
	} else if (disk_addr == diskaddr_ecc_error && disk_addr != 0) {
		sense_code = OMTI_SENSE_CODE_ECC_ERROR;
	} else if (disk_track == alternate_track_address[1] && disk_track != 0) {
		sense_code = OMTI_SENSE_CODE_ALTERNATE_TRACK;
	}

	if (sense_code == OMTI_SENSE_CODE_NO_ERROR) {
		clear_sense_data();
	} else {
		command_status |= OMTI_COMMAND_STATUS_ERROR;
		set_sense_data(sense_code, cdb);
	}
	return sense_code == OMTI_SENSE_CODE_NO_ERROR;
}
Beispiel #3
0
void omti8621_device::do_command(const UINT8 cdb[], const UINT16 cdb_length)
{
	UINT8 lun = get_lun(cdb);
	omti_disk_image_device *disk = our_disks[lun];
	int command_duration = 0; // ms

	log_command( cdb, cdb_length);

	// default to read status and status is successful completion
	omti_state = OMTI_STATE_STATUS;
	status_port |= OMTI_STATUS_IO | OMTI_STATUS_CD;
	command_status = lun ? OMTI_COMMAND_STATUS_LUN : 0;

	if (mask_port & OMTI_MASK_INTE) {
		set_interrupt(CLEAR_LINE);
	}

	if (!disk->m_image->exists()) {
		command_status |= OMTI_COMMAND_STATUS_ERROR; // no such drive
	}

	switch (cdb[0]) {
	case OMTI_CMD_TEST_DRIVE_READY: // 0x00
		if (!disk->m_image->exists())
		{
			set_sense_data(OMTI_SENSE_CODE_DRIVE_NOT_READY, cdb);
		}
		break;

	case OMTI_CMD_RECALIBRATE: // 0x01
		break;

	case OMTI_CMD_REQUEST_SENSE: // 0x03
		set_data_transfer(sense_data, sizeof(sense_data));
		break;

	case OMTI_CMD_READ_VERIFY: // 0x05
		check_disk_address(cdb);
		break;

	case OMTI_CMD_FORMAT_TRACK: // 0x06
		format_track(cdb);
		break;

	case OMTI_CMD_FORMAT_BAD_TRACK: // 0x07
		diskaddr_format_bad_track = get_disk_address(cdb);
		break;

	case OMTI_CMD_READ: // 0x08
		if (check_disk_address(cdb)) {
			// read data from controller
			read_sectors_from_disk(get_disk_address(cdb), cdb[4], lun);
			set_data_transfer(&sector_buffer[0],  OMTI_DISK_SECTOR_SIZE*cdb[4]);
		}
		break;

	case OMTI_CMD_WRITE: // 0x0A
		log_data();
		if (check_disk_address(cdb)) {
			write_sectors_to_disk(get_disk_address(cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_SEEK: // 0x0B
		check_disk_address(cdb);
		break;

	case OMTI_CMD_READ_SECTOR_BUFFER: // 0x0E
		set_data_transfer(&sector_buffer[0], OMTI_DISK_SECTOR_SIZE*cdb[4]);
		break;

	case OMTI_CMD_WRITE_SECTOR_BUFFER: // 0x0F
		log_data();
		break;

	case OMTI_CMD_COPY: // 0x20
		if (check_disk_address(cdb) && check_disk_address(cdb+4)) {
			// copy sectors
			copy_sectors (get_disk_address(cdb+4), get_disk_address(cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_READ_ESDI_DEFECT_LIST: // 0x37
		set_esdi_defect_list(get_lun(cdb), cdb[1] & 0x1f);
		set_data_transfer(disk->m_esdi_defect_list, sizeof(disk->m_esdi_defect_list));
		break;

#if 0   // this command seems unused by Domain/OS, and it's unclear what the intent of the code is (it makes some versions of GCC quite unhappy)
	case OMTI_CMD_ASSIGN_ALTERNATE_TRACK: // 0x11
		log_data();
		alternate_track_address[0] = get_disk_track(cdb);
		alternate_track_address[1] = get_disk_track(alternate_track_buffer-1);
		break;
#endif

	case OMTI_CMD_READ_DATA_TO_BUFFER: // 0x1E
		if (check_disk_address(cdb)) {
			// read data from controller
			read_sectors_from_disk (get_disk_address(cdb), cdb[4], lun);
			// Domain/OS doesn't expect zero access time
			command_duration += 1; // 1 ms is enough, average time would be 30 ms)
		}
		break;

	case OMTI_CMD_WRITE_DATA_FROM_BUFFER: // 0x1F
		log_data();
		if (check_disk_address(cdb)) {
			write_sectors_to_disk(get_disk_address(cdb), cdb[4], lun);
		}
		break;

	case  OMTI_CMD_RAM_DIAGNOSTICS: // 0xE0
		break;

	case OMTI_CMD_CONTROLLER_INT_DIAGNOSTIC: // 0xE4
		break;

	case OMTI_CMD_READ_LONG: // 0xE5
		if (check_disk_address(cdb)) {
			// read data from controller
			read_sectors_from_disk(get_disk_address(cdb), cdb[4], lun);
			set_data_transfer(&sector_buffer[0], OMTI_DISK_SECTOR_SIZE+6);
		}
		break;

	case OMTI_CMD_WRITE_LONG: // 0xE6
		log_data();
		if (check_disk_address(cdb)) {
			UINT32 diskaddr =  get_disk_address(cdb);
			write_sectors_to_disk(diskaddr, cdb[4], lun);
			// this will spoil the ECC code
			diskaddr_ecc_error = diskaddr;
		}
		break;

	case OMTI_CMD_READ_CONFIGURATION: // 0xEC
		set_configuration_data(get_lun(cdb));
		set_data_transfer(disk->m_config_data, sizeof(disk->m_config_data));
		break;

	case OMTI_CMD_INVALID_COMMAND: // 0xFF
		set_sense_data(OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;

	default:
		LOG(("do_command: UNEXPECTED command %02x",cdb[0]));
		set_sense_data(OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;
	}

	if (mask_port & OMTI_MASK_INTE) {
//      if (omti_state != OMTI_STATE_STATUS) {
//          LOG(("do_command: UNEXPECTED omti_state %02x",omti_state));
//      }
		status_port |= OMTI_STATUS_IREQ;
		if (command_duration == 0)
		{
			set_interrupt(ASSERT_LINE);
		}
		else
		{
			// FIXME: should delay omti_state and status_port as well
			m_timer->adjust(attotime::from_msec(command_duration), 0);
		}
	}
}
void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type)
{
	switch (sense_type) {
	case SENSE_TYPE_MEDIA_CHANGE:
		set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0);
     		break;
		
    	case SENSE_TYPE_MEDIA_NOT_PRESENT:
		set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0);
    		break;
		
	case SENSE_TYPE_MEDIA_LBA_OVER_RANGE:
		set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0);
		break;
		
	case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT:
		set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0);
		break;
		
	case SENSE_TYPE_MEDIA_WRITE_PROTECT:
		set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0);
		break;
		
	case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR:
		set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0);
		break;
		
	case SENSE_TYPE_MEDIA_WRITE_ERR:
		set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0);
		break;
		
	case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD:
		set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, 
				ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1);
		break;
		
	case SENSE_TYPE_FORMAT_IN_PROGRESS:
		set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0);
		break;
		
	case SENSE_TYPE_FORMAT_CMD_FAILED:
		set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0);
		break;
		
#ifdef SUPPORT_MAGIC_GATE
	case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB:
		set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0);
		break;
		
	case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN:
		set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0);
		break;
		
	case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM:
		set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0);
		break;
		
	case SENSE_TYPE_MG_WRITE_ERR:
		set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0);
		break;
#endif

#ifdef SUPPORT_SD_LOCK
	case SENSE_TYPE_MEDIA_READ_FORBIDDEN:
		set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0);
		break;
#endif

    	case SENSE_TYPE_NO_SENSE:
	default:
		set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0);
    		break;
	}
}
Beispiel #5
0
static void do_command(omti8621_state *state,
		const UINT8 cdb[], const UINT16 cdb_length) {

	UINT8 lun = get_lun(cdb);
	disk_data *disk = state->disk[lun];
	int command_duration = 0; // ms

	log_command( state, cdb, cdb_length);

	// default to read status and status is successful completion
	state->omti_state = OMTI_STATE_STATUS;
	state->status_port |= OMTI_STATUS_IO | OMTI_STATUS_CD;
	state->command_status = lun ? OMTI_COMMAND_STATUS_LUN : 0;

	if (state->mask_port & OMTI_MASK_INTE) {
		set_interrupt(state, CLEAR_LINE);
	}

	if (!disk->image->exists()) {
		state->command_status |= OMTI_COMMAND_STATUS_ERROR; // no such drive
	}

	switch (cdb[0]) {
	case OMTI_CMD_TEST_DRIVE_READY: // 0x00
		if (!disk->image->exists())
		{
			set_sense_data(state, OMTI_SENSE_CODE_DRIVE_NOT_READY, cdb);
		}
		break;

	case OMTI_CMD_RECALIBRATE: // 0x01
		break;

	case OMTI_CMD_REQUEST_SENSE: // 0x03
		set_data_transfer(state, state->sense_data, sizeof(state->sense_data));
		break;

	case OMTI_CMD_READ_VERIFY: // 0x05
		check_disk_address(state, cdb);
		break;

	case OMTI_CMD_FORMAT_TRACK: // 0x06
		format_track(state, cdb);
		break;

	case OMTI_CMD_FORMAT_BAD_TRACK: // 0x07
		state->diskaddr_format_bad_track = get_disk_address(state, cdb);
		break;

	case OMTI_CMD_READ: // 0x08
		if (check_disk_address(state, cdb)) {
			// read data from controller
			read_sectors_from_disk(state, get_disk_address(state, cdb), cdb[4], lun);
			set_data_transfer(state, state->sector_buffer,  OMTI_DISK_SECTOR_SIZE*cdb[4]);
		}
		break;

	case OMTI_CMD_WRITE: // 0x0A
		log_data(state);
		if (check_disk_address(state, cdb)) {
			write_sectors_to_disk(state, get_disk_address(state, cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_SEEK: // 0x0B
		check_disk_address(state, cdb);
		break;

	case OMTI_CMD_READ_SECTOR_BUFFER: // 0x0E
		set_data_transfer(state, state->sector_buffer, OMTI_DISK_SECTOR_SIZE*cdb[4]);
		break;

	case OMTI_CMD_WRITE_SECTOR_BUFFER: // 0x0F
		log_data(state);
		break;

	case OMTI_CMD_COPY: // 0x20
		if (check_disk_address(state, cdb) && check_disk_address(state, cdb+4)) {
			// copy sectors
			copy_sectors (state, get_disk_address(state,  cdb+4), get_disk_address(state, cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_READ_ESDI_DEFECT_LIST: // 0x37
		set_esdi_defect_list(state, get_lun(cdb), cdb[1] & 0x1f);
		set_data_transfer(state, disk->esdi_defect_list, sizeof(disk->esdi_defect_list));
		break;

	case OMTI_CMD_ASSIGN_ALTERNATE_TRACK: // 0x11
		log_data(state);
		state->alternate_track_address[0] = get_disk_track(state, cdb);
		state->alternate_track_address[1] = get_disk_track(state, state->alternate_track_buffer-1);;
		break;

	case OMTI_CMD_READ_DATA_TO_BUFFER: // 0x1E
		if (check_disk_address(state, cdb)) {
			// read data from controller
			read_sectors_from_disk (state, get_disk_address(state, cdb), cdb[4], lun);
			// Domain/OS doesn't expect zero access time
			command_duration += 1; // 1 ms is enough, average time would be 30 ms)
		}
		break;

	case OMTI_CMD_WRITE_DATA_FROM_BUFFER: // 0x1F
		log_data(state);
		if (check_disk_address(state, cdb)) {
			write_sectors_to_disk(state, get_disk_address(state, cdb), cdb[4], lun);
		}
		break;

	case  OMTI_CMD_RAM_DIAGNOSTICS: // 0xE0
		break;

	case OMTI_CMD_CONTROLLER_INT_DIAGNOSTIC: // 0xE4
		break;

	case OMTI_CMD_READ_LONG: // 0xE5
		if (check_disk_address(state, cdb)) {
			// read data from controller
			read_sectors_from_disk(state, get_disk_address(state, cdb), cdb[4], lun);
			set_data_transfer(state, state->sector_buffer, OMTI_DISK_SECTOR_SIZE+6);
		}
		break;

	case OMTI_CMD_WRITE_LONG: // 0xE6
		log_data(state);
		if (check_disk_address(state, cdb)) {
			UINT32 diskaddr =  get_disk_address(state, cdb);
			write_sectors_to_disk(state, diskaddr, cdb[4], lun);
			// this will spoil the ECC code
			state->diskaddr_ecc_error = diskaddr;
		}
		break;

	case OMTI_CMD_READ_CONFIGURATION: // 0xEC
		set_configuration_data(state, get_lun(cdb));
		set_data_transfer(state, disk->config_data, sizeof(disk->config_data));
		break;

	case OMTI_CMD_INVALID_COMMAND: // 0xFF
		set_sense_data(state, OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		state->command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;

	default:
		LOG(("do_command: UNEXPECTED command %02x",cdb[0]));
		set_sense_data(state, OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		state->command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;
	}

	if (state->mask_port & OMTI_MASK_INTE) {
//      if (state->omti_state != OMTI_STATE_STATUS) {
//          LOG(("do_command: UNEXPECTED omti_state %02x",state->omti_state));
//      }
		state->status_port |= OMTI_STATUS_IREQ;
		if (command_duration == 0) {
			set_interrupt(state, ASSERT_LINE);
		} else {
			// FIXME: should delay state->omti_state and state->status_port as well
			state->device->machine().scheduler().timer_set(attotime::from_msec(command_duration), FUNC(set_interrupt_caba), 0, state);
		}
	}
}
Beispiel #6
0
void show_serial_number(struct sg_io_hdr *hdr)
{
	unsigned char *buffer = hdr->dxferp;
	int i;
	printf("serial number: ");
	for (i=0x80, 
}
#endif

#define SENSE_LEN 32
#define BLOCK_LEN 1

unsigned char sense_buffer[SENSE_LEN];
unsigned char data_buffer[BLOCK_LEN*256];
void test_execute_Inquiry(char * path, int evpd, int page_code)
{
	struct sg_io_hdr * p_hdr = init_io_hdr();
	set_xfer_data(p_hdr, data_buffer, BLOCK_LEN*256);
	set_sense_data(p_hdr, sense_buffer, SENSE_LEN);
	int status = 0;
	int fd = open(path, O_RDWR);
	if (fd>0) {
		status = execute_Inquiry(fd, page_code, evpd, p_hdr);
		printf("the return status is %d\n", status);
		if (status!=0) {
			show_sense_buffer(p_hdr);
		} else{
			show_vendor(p_hdr);
			show_product(p_hdr);
			show_product_rev(p_hdr);
			show_xfer_data(p_hdr);
		}
	} else {
		printf("failed to open sg file %s\n", path);
	}
	close(fd);
	destroy_io_hdr(p_hdr);
}


void test_cmds(char *path, int evpd, int page_code)
{
	struct sg_io_hdr * p_hdr = init_io_hdr();
	set_xfer_data(p_hdr, data_buffer, BLOCK_LEN*256);
	set_sense_data(p_hdr, sense_buffer, SENSE_LEN);
	int status = 0;
	int fd = open(path, O_RDWR);
	if (fd>0) {
		status = execute_Inquiry(fd, page_code, evpd, p_hdr);
		printf("the return status is %d\n", status);
		//show_sense_buffer(p_hdr);
		show_xfer_data(p_hdr);
	} else {
		printf("failed to open sg file %s\n", path);
	}
	close(fd);
	destroy_io_hdr(p_hdr);
}

void get_rpm(char *path, int evpd, int page_code)
{
	struct sg_io_hdr * p_hdr = init_io_hdr();
	set_xfer_data(p_hdr, data_buffer, BLOCK_LEN*256);
	set_sense_data(p_hdr, sense_buffer, SENSE_LEN);
	int status = 0;
	unsigned char *xfer;
	int pdt, rpm;

	int fd = open(path, O_RDWR);
	if (fd>0) {
		status = execute_Inquiry(fd, page_code, evpd, p_hdr);
		printf("the return status is %d\n", status);
		//show_sense_buffer(p_hdr);
		//show_xfer_data(p_hdr);

		// 参考代码 sg3_utils: sg_vpd.c : decode_b1_vpd()
		xfer = p_hdr->dxferp;
		pdt = (int)xfer[0];
		switch (pdt)
		{
			case 0:
				if (p_hdr->dxfer_len < 64)
				{
					printf("xfer is too short!\n");
				}
				else
				{
					rpm = (xfer[4]<<8) | xfer[5];
					printf("rpm of %s: %d rpm\n", path, rpm);
				}
				break;
			default:
				printf("unknown pdt\n");
				break;
		}
	} else {
		printf("failed to open sg file %s\n", path);
	}
	close(fd);
	destroy_io_hdr(p_hdr);
}

int main(int argc, char * argv[])
{
	//test_execute_Inquiry(argv[1], 0, 0);

	//test_cmds(argv[1], 1, 0x86);
	get_rpm(argv[1], 1, 0xb1); // rpm
	// tested:
	// 0x80,0x83

	return 0;
}