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; }
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; }