Esempio n. 1
0
static rtems_status_code
rtems_bsd_sim_attach_worker(rtems_media_state state, const char *src, char **dest, void *arg)
{
	rtems_status_code sc = RTEMS_SUCCESSFUL;
	struct cam_sim *sim = arg;
	char *disk = NULL;

	if (state == RTEMS_MEDIA_STATE_READY) {
		unsigned retries = 0;

		struct scsi_inquiry_data inq_data;
		uint32_t block_count = 0;
		uint32_t block_size = 0;

		disk = rtems_media_create_path("/dev", src, cam_sim_unit(sim));
		if (disk == NULL) {
			BSD_PRINTF("OOPS: create path failed\n");
			goto error;
		}

		sc = rtems_bsd_scsi_inquiry(&sim->ccb, &inq_data);
		if (sc != RTEMS_SUCCESSFUL) {
			BSD_PRINTF("OOPS: inquiry failed\n");
			goto error;
		}
		scsi_print_inquiry(&inq_data);

		for (retries = 0; retries <= 3; ++retries) {
			sc = rtems_bsd_scsi_test_unit_ready(&sim->ccb);
			if (sc == RTEMS_SUCCESSFUL) {
				break;
			}
		}
		if (sc != RTEMS_SUCCESSFUL) {
			BSD_PRINTF("OOPS: test unit ready failed\n");
			goto error;
		}

		sc = rtems_bsd_scsi_read_capacity(&sim->ccb, &block_count, &block_size);
		if (sc != RTEMS_SUCCESSFUL) {
			BSD_PRINTF("OOPS: read capacity failed\n");
			goto error;
		}

		BSD_PRINTF("read capacity: block count %u, block size %u\n", block_count, block_size);

		sc = rtems_blkdev_create(disk, block_size, block_count, rtems_bsd_sim_disk_ioctl, sim);
		if (sc != RTEMS_SUCCESSFUL) {
			goto error;
		}

		/* FIXME */
#if 0
		rtems_disk_device *dd = rtems_disk_obtain(dev);
		dd->block_size *= 64;
		rtems_disk_release(dd);
#endif

		rtems_bsd_sim_disk_initialized(sim, disk);

		*dest = strdup(disk, M_RTEMS_HEAP);
	}

	return RTEMS_SUCCESSFUL;

error:

	free(disk, M_RTEMS_HEAP);

	rtems_bsd_sim_disk_initialized(sim, NULL);

	return RTEMS_IO_ERROR;
}
Esempio n. 2
0
File: scsi.c Progetto: PyroOS/Pyro
SCSI_device_s *scsi_scan_device( SCSI_host_s * psHost, int nChannel, int nDevice, int nLun, int *pnSCSILevel )
{
	unsigned char nSCSIResult[256];
	SCSI_cmd sCmd;
	int nError;
	SCSI_device_s *psDevice = NULL;

	printk( "Scanning device %i:%i:%i...\n", nChannel, nDevice, nLun );

	/* Build SCSI_INQUIRY command */
	memset( &sCmd, 0, sizeof( sCmd ) );

	sCmd.psHost = psHost;
	sCmd.nChannel = nChannel;
	sCmd.nDevice = nDevice;
	sCmd.nLun = nLun;
	sCmd.nDirection = SCSI_DATA_READ;

	sCmd.nCmd[0] = SCSI_INQUIRY;
	if( *pnSCSILevel <= SCSI_2 )
		sCmd.nCmd[1] = ( nLun << 5 ) & 0xe0;
	sCmd.nCmd[4] = 255;
	sCmd.nCmdLen = scsi_get_command_size( SCSI_INQUIRY );

	sCmd.pRequestBuffer = nSCSIResult;
	sCmd.nRequestSize = 256;

	/* Send command */
	nError = psHost->queue_command( &sCmd );

	kerndbg( KERN_DEBUG, "Result: %i\n", sCmd.nResult );

	/* Check result */
	if( nError != 0 || sCmd.nResult != 0 )
	{
		return NULL;
	}

	scsi_print_inquiry( nSCSIResult );

	switch( ( nSCSIResult[0] & 0x1f ) )
	{
		case SCSI_TYPE_DISK:
		{
			kerndbg( KERN_DEBUG, "SCSI_TYPE_DISK\n" );

			psDevice = scsi_add_disk( psHost, nChannel, nDevice, nLun, nSCSIResult );
			break;
		}

		case SCSI_TYPE_ROM:
		{
			kerndbg( KERN_DEBUG, "SCSI_TYPE_ROM\n" );

			psDevice = scsi_add_cdrom( psHost, nChannel, nDevice, nLun, nSCSIResult );
			break;
		}

		default:
		{
			printk( "Unsupported SCSI device (Type 0x%.2x)\n", ( nSCSIResult[0] & 0x1f ) );
			return NULL;
		}
	}

	if( psDevice )
		*pnSCSILevel = psDevice->nSCSILevel;

	return psDevice;
}