* First baby steps in letting our drivers use the new I/O request/scheduler

architecture: for now, we do this on the lowest layer only, therefore all
  requests are handled synchronously (ie. in the scheduler's thread).
* Instead of using the block_io module, scsi_disk (and scsi_cd) are now
  exporting a device on their own, and use an I/O scheduler with an appropriate
  DMA resource.
* There are still lots of TODOs, and it can easily panic - don't update if
  you intend to demo Haiku.
* scsi_periph now only has an io() function that get an io_operation, instead
  of the previous read/write functions, moved preferred CCB size from those
  functions into the device registration.
* Changed all scsi_periph files to C++.
* scsi_cd ported, too, but untested.
* Removed block_io from image - it will be removed completely soon.
* Temporarily commented an ASSERT() in the ATA bus manager (in case you use
  it); it's sometimes triggered by the code now, and I haven't yet looked into
  the issue -- doesn't seem to harm, at least.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26828 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-08-05 21:11:51 +00:00
parent 34faa5f214
commit 24593e2c79
19 changed files with 814 additions and 751 deletions

View File

@ -160,7 +160,7 @@ AddFilesToHaikuImage beos system add-ons kernel debugger
AddFilesToHaikuImage beos system add-ons kernel file_systems
: $(BEOS_ADD_ONS_FILE_SYSTEMS) ;
AddFilesToHaikuImage beos system add-ons kernel generic
: block_io dpc ide_adapter locked_pool mpu401 scsi_periph ;
: dpc ide_adapter locked_pool mpu401 scsi_periph ;
AddFilesToHaikuImage beos system add-ons kernel partitioning_systems
: intel session ;
AddFilesToHaikuImage beos system add-ons kernel interrupt_controllers
@ -372,7 +372,7 @@ AddFilesToHaikuImage beos system : zbeos ;
AddBootModuleSymlinksToHaikuImage
pci $(X86_ONLY)isa config_manager ide scsi usb
$(PPC_ONLY)openpic
block_io ide_adapter locked_pool scsi_periph
ide_adapter locked_pool scsi_periph
ahci generic_ide_pci it8211 legacy_sata silicon_image_3112 $(X86_ONLY)ide_isa
<usb>uhci <usb>ohci <usb>ehci
scsi_cd scsi_disk usb_disk

View File

@ -134,6 +134,7 @@ typedef struct scsi_ccb {
uint16 sg_count; // number of S/G entries
uint32 data_length; // length of data
int32 data_resid; // data transfer residual length: 2's comp
void *io_operation;
uchar sense[SCSI_MAX_SENSE_SIZE]; // autosense data
uchar sense_resid; // autosense resid length: 2's comp

View File

@ -7,8 +7,7 @@
#ifndef _SCSI_PERIPH_H
#define _SCSI_PERIPH_H
/*
Use this module to minimize work required to write a SCSI
/*! Use this module to minimize work required to write a SCSI
peripheral driver.
It takes care of:
@ -64,21 +63,21 @@ typedef struct periph_device_info *periph_device_cookie;
// cookie issued by driver per file handle
typedef struct periph_handle_info *periph_handle_cookie;
typedef struct IOOperation io_operation;
// callbacks to be provided by peripheral driver
typedef struct scsi_periph_callbacks {
// *** block devices ***
// informs of new size of medium
// (set to NULL if not a block device)
void (*set_capacity)( periph_device_cookie periph_device, uint64 capacity,
uint32 block_size );
void (*set_capacity)(periph_device_cookie cookie, uint64 capacity,
uint32 blockSize);
// *** removable devices
// called when media got changed (can be NULL if medium is not changable)
// (you don't need to call periph->media_changed, but it's doesn't if you do)
// ccb - request at your disposal
void (*media_changed)( periph_device_cookie periph_device,
scsi_ccb *request );
void (*media_changed)(periph_device_cookie cookie, scsi_ccb *request);
} scsi_periph_callbacks;
@ -87,73 +86,61 @@ typedef struct scsi_periph_interface {
module_info info;
// *** init/cleanup ***
status_t (*register_device)(
periph_device_cookie periph_device,
scsi_periph_callbacks *callbacks,
scsi_device scsi_device,
scsi_device_interface *scsi,
device_node *node,
bool removable,
scsi_periph_device *driver );
status_t (*unregister_device)( scsi_periph_device driver );
// preferred_ccb_size - preferred command size; if zero, the shortest is used
status_t (*register_device)(periph_device_cookie cookie,
scsi_periph_callbacks *callbacks, scsi_device scsiDevice,
scsi_device_interface *scsi, device_node *node, bool removable,
int preferredCcbSize, scsi_periph_device *driver);
status_t (*unregister_device)(scsi_periph_device driver);
// *** basic command execution ***
// exec command, retrying on problems
status_t (*safe_exec)(
scsi_periph_device periph_device,
scsi_ccb *request );
status_t (*safe_exec)(scsi_periph_device periphCookie, scsi_ccb *request);
// exec simple command
status_t (*simple_exec)( scsi_periph_device device,
void *cdb, uchar cdb_len, void *data, size_t data_len,
int ccb_flags );
status_t (*simple_exec)(scsi_periph_device device, void *cdb,
uint8 cdbLength, void *data, size_t dataLength, int ccbFlags);
// *** file handling ***
// to be called when a new file is opened
status_t (*handle_open)( scsi_periph_device device,
periph_handle_cookie periph_handle, scsi_periph_handle *res_handle );
status_t (*handle_open)(scsi_periph_device device,
periph_handle_cookie periph_handle, scsi_periph_handle *_handle);
// to be called when a file is closed
status_t (*handle_close)( scsi_periph_handle handle );
status_t (*handle_close)(scsi_periph_handle handle);
// to be called when a file is freed
status_t (*handle_free)( scsi_periph_handle handle );
status_t (*handle_free)(scsi_periph_handle handle);
// *** default implementation for block devices ***
// block read
// preferred_ccb_size - preferred command size; if zero, the shortest is used
status_t (*read)( scsi_periph_handle handle, const phys_vecs *vecs,
off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size );
// block write
// (see block_read)
status_t (*write)( scsi_periph_handle handle, const phys_vecs *vecs,
off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size );
status_t (*io)(scsi_periph_device device, io_operation *operation,
size_t *_bytesTransferred);
// block ioctls
status_t (*ioctl)( scsi_periph_handle handle, int op, void *buf, size_t len );
status_t (*ioctl)(scsi_periph_handle handle, int op, void *buffer,
size_t length);
// check medium capacity (calls set_capacity callback on success)
// request - ccb for this device; is used to talk to device
status_t (*check_capacity)( scsi_periph_device device, scsi_ccb *request );
status_t (*check_capacity)(scsi_periph_device device, scsi_ccb *request);
// *** removable media ***
// to be called when a medium change is detected to block subsequent commands
void (*media_changed)( scsi_periph_device device );
void (*media_changed)(scsi_periph_device device);
// convert result of *request to err_res
err_res (*check_error)( scsi_periph_device device, scsi_ccb *request );
err_res (*check_error)(scsi_periph_device device, scsi_ccb *request);
// send start or stop command to device
// with_LoEj = true - include loading/ejecting,
// false - only do allow/deny
err_res (*send_start_stop)( scsi_periph_device device, scsi_ccb *request,
bool start, bool with_LoEj );
// withLoadEject = true - include loading/ejecting,
// false - only do allow/deny
err_res (*send_start_stop)(scsi_periph_device device, scsi_ccb *request,
bool start, bool withLoadEject);
// checks media status and waits for device to become ready
// returns: B_OK, B_DEV_MEDIA_CHANGE_REQUESTED, B_NO_MEMORY or
// pending error reported by handle_get_error
status_t (*get_media_status)( scsi_periph_handle handle );
status_t (*get_media_status)(scsi_periph_handle handle);
// compose device name consisting of prefix and path/target/LUN
// (result must be freed by caller)
char *(*compose_device_name)(device_node *device_node, const char *prefix);
// fill data with icon (for B_GET_ICON ioctl)
status_t (*get_icon)( icon_type type, device_icon *data );
status_t (*get_icon)(icon_type type, device_icon *data);
// synchronizes (flush) the device cache
err_res(*synchronize_cache)(scsi_periph_device device, scsi_ccb *request);
@ -162,4 +149,3 @@ typedef struct scsi_periph_interface {
#define SCSI_PERIPH_MODULE_NAME "generic/scsi_periph/v1"
#endif /* _SCSI_PERIPH_H */

View File

@ -14,7 +14,7 @@ ata_request_init(ata_request *request, struct ide_device_info *device)
}
/* Start the request, but don't clear sense to allow
/* Start the request, but don't clear sense to allow
* retrieving the previous sense data.
*/
void ata_request_start(ata_request **_request, struct ide_device_info *device, struct scsi_ccb *ccb)
@ -31,7 +31,7 @@ void ata_request_start(ata_request **_request, struct ide_device_info *device, s
device->bus->state = ata_state_busy;
device->bus->active_device = device;
request = device->requestFree;
device->requestActive = request;
device->requestFree = NULL;
@ -77,7 +77,7 @@ ata_request_clear_sense(ata_request *request)
void
ata_request_set_status(ata_request *request, uint8 status)
{
ASSERT(status != SCSI_REQ_CMP);
// ASSERT(status != SCSI_REQ_CMP);
if (request && request->ccb)
request->ccb->subsys_status = status;
}
@ -106,10 +106,10 @@ ata_request_finish(ata_request *request, bool resubmit)
request, ccb->subsys_status, request->senseKey);
// when the request completed and has set sense
// data, report this to the scsci stack by setting
// data, report this to the scsi stack by setting
// CHECK CONDITION status
if (ccb->subsys_status == SCSI_REQ_CMP && request->senseKey != 0) {
TRACE("ata_request_finish - setting check condition\n");
request->ccb->subsys_status = SCSI_REQ_CMP_ERR;

View File

@ -8,7 +8,7 @@
CCB manager
As allocation of ccb can be on the paging path we must use a
As allocation of ccb can be on the paging path we must use a
locked pool.
*/
@ -19,7 +19,7 @@
// ccb are relatively large, so don't make it too small to not waste memory
#define CCB_CHUNK_SIZE 16*1024
// maximum number of CCBs - probably, we want to make that editable
// maximum number of CCBs - probably, we want to make that editable
// it must be at least 1 for normal use and 1 for stand-by autosense request
#define CCB_NUM_MAX 128
@ -40,6 +40,7 @@ scsi_alloc_ccb(scsi_device_info *device)
// reset some very important fields
// TODO: should we better omit that to find bugs easier?
ccb->sg_list = NULL;
ccb->io_operation = NULL;
ccb->sort = -1;
SHOW_FLOW(3, "path=%d", ccb->path_id);

View File

@ -1,6 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers disk scsi scsi_disk ;
UsePrivateHeaders drivers kernel ;
SubDirHdrs $(HAIKU_TOP) src system kernel device_manager ;
KernelAddon scsi_disk :
scsi_disk.cpp

View File

@ -29,13 +29,12 @@
#endif
static scsi_periph_interface *sSCSIPeripheral;
static device_manager_info *sDeviceManager;
static block_io_for_driver_interface *sBlockIO;
static scsi_periph_interface* sSCSIPeripheral;
static device_manager_info* sDeviceManager;
static status_t
update_capacity(das_device_info *device)
update_capacity(das_driver_info *device)
{
TRACE("update_capacity()\n");
@ -53,20 +52,20 @@ update_capacity(das_device_info *device)
static status_t
get_geometry(das_handle_info *handle, device_geometry *geometry)
get_geometry(das_handle* handle, device_geometry* geometry)
{
das_device_info *device = handle->device;
das_driver_info* info = handle->info;
status_t status = update_capacity(device);
status_t status = update_capacity(info);
if (status < B_OK)
return status;
geometry->bytes_per_sector = device->block_size;
geometry->bytes_per_sector = info->block_size;
geometry->sectors_per_track = 1;
geometry->cylinder_count = device->capacity;
geometry->cylinder_count = info->capacity;
geometry->head_count = 1;
geometry->device_type = B_DISK;
geometry->removable = device->removable;
geometry->removable = info->removable;
// TBD: for all but CD-ROMs, read mode sense - medium type
// (bit 7 of block device specific parameter for Optical Memory Block Device)
@ -86,7 +85,7 @@ get_geometry(das_handle_info *handle, device_geometry *geometry)
static status_t
load_eject(das_device_info *device, bool load)
load_eject(das_driver_info *device, bool load)
{
TRACE("load_eject()\n");
@ -104,7 +103,7 @@ load_eject(das_device_info *device, bool load)
static status_t
synchronize_cache(das_device_info *device)
synchronize_cache(das_driver_info *device)
{
TRACE("synchronize_cache()\n");
@ -135,36 +134,65 @@ log2(uint32 x)
}
// #pragma mark - block_io API
static void
das_set_device(das_device_info *info, block_io_device device)
static status_t
do_io(void* cookie, IOOperation* operation)
{
info->block_io_device = device;
das_driver_info* info = (das_driver_info*)cookie;
// TODO: this can go away as soon as we pushed the IOOperation to the upper
// layers - we can then set scsi_periph::io() as callback for the scheduler
size_t bytesTransferred;
status_t status = sSCSIPeripheral->io(info->scsi_periph_device, operation,
&bytesTransferred);
info->io_scheduler->OperationCompleted(operation, status, bytesTransferred);
return status;
}
// #pragma mark - device module API
static status_t
das_init_device(void* _info, void** _cookie)
{
das_driver_info* info = (das_driver_info*)_info;
// and get (initial) capacity
scsi_ccb *request = info->scsi->alloc_ccb(info->scsi_device);
if (request == NULL)
return;
return B_NO_MEMORY;
sSCSIPeripheral->check_capacity(info->scsi_periph_device, request);
info->scsi->free_ccb(request);
*_cookie = info;
return B_OK;
}
static void
das_uninit_device(void* _cookie)
{
das_driver_info* info = (das_driver_info*)_cookie;
delete info->io_scheduler;
delete info->dma_resource;
}
static status_t
das_open(das_device_info *device, das_handle_info **_cookie)
das_open(void* _info, const char* path, int openMode, void** _cookie)
{
TRACE("open()\n");
das_driver_info* info = (das_driver_info*)_info;
das_handle_info *handle = (das_handle_info *)malloc(sizeof(*handle));
das_handle* handle = (das_handle*)malloc(sizeof(das_handle));
if (handle == NULL)
return B_NO_MEMORY;
handle->device = device;
handle->info = info;
status_t status = sSCSIPeripheral->handle_open(device->scsi_periph_device,
status_t status = sSCSIPeripheral->handle_open(info->scsi_periph_device,
(periph_handle_cookie)handle, &handle->scsi_periph_handle);
if (status < B_OK) {
free(handle);
@ -177,8 +205,9 @@ das_open(das_device_info *device, das_handle_info **_cookie)
static status_t
das_close(das_handle_info *handle)
das_close(void* cookie)
{
das_handle* handle = (das_handle*)cookie;
TRACE("close()\n");
sSCSIPeripheral->handle_close(handle->scsi_periph_handle);
@ -187,8 +216,9 @@ das_close(das_handle_info *handle)
static status_t
das_free(das_handle_info *handle)
das_free(void* cookie)
{
das_handle* handle = (das_handle*)cookie;
TRACE("free()\n");
sSCSIPeripheral->handle_free(handle->scsi_periph_handle);
@ -198,38 +228,80 @@ das_free(das_handle_info *handle)
static status_t
das_read(das_handle_info *handle, const phys_vecs *vecs, off_t pos,
size_t num_blocks, uint32 block_size, size_t *bytes_transferred)
das_read(void* cookie, off_t pos, void* buffer, size_t* _length)
{
return sSCSIPeripheral->read(handle->scsi_periph_handle, vecs, pos,
num_blocks, block_size, bytes_transferred, 10);
das_handle* handle = (das_handle*)cookie;
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, buffer, length, false, 0);
if (status != B_OK)
return status;
status = handle->info->io_scheduler->ScheduleRequest(&request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
if (status == B_OK)
*_length = length;
else
dprintf("das_read(): request.Wait() returned: %s\n", strerror(status));
return status;
}
static status_t
das_write(das_handle_info *handle, const phys_vecs *vecs, off_t pos,
size_t num_blocks, uint32 block_size, size_t *bytes_transferred)
das_write(void* cookie, off_t pos, const void* buffer, size_t* _length)
{
return sSCSIPeripheral->write(handle->scsi_periph_handle, vecs, pos,
num_blocks, block_size, bytes_transferred, 10);
das_handle* handle = (das_handle*)cookie;
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (void*)buffer, length, true, 0);
if (status != B_OK)
return status;
status = handle->info->io_scheduler->ScheduleRequest(&request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
if (status == B_OK)
*_length = length;
else
dprintf("das_write(): request.Wait() returned: %s\n", strerror(status));
return status;
}
static status_t
das_ioctl(das_handle_info *handle, int op, void *buffer, size_t length)
das_io(void *cookie, io_request *request)
{
das_device_info *device = handle->device;
das_handle* handle = (das_handle*)cookie;
return handle->info->io_scheduler->ScheduleRequest(request);
}
static status_t
das_ioctl(void* cookie, uint32 op, void* buffer, size_t length)
{
das_handle* handle = (das_handle*)cookie;
das_driver_info* info = handle->info;
TRACE("ioctl(op = %d)\n", op);
switch (op) {
case B_GET_DEVICE_SIZE:
{
status_t status = update_capacity(device);
status_t status = update_capacity(info);
if (status != B_OK)
return status;
size_t size = device->capacity * device->block_size;
size_t size = info->capacity * info->block_size;
return user_memcpy(buffer, &size, sizeof(size_t));
}
@ -242,23 +314,23 @@ das_ioctl(das_handle_info *handle, int op, void *buffer, size_t length)
status_t status = get_geometry(handle, &geometry);
if (status != B_OK)
return status;
return user_memcpy(buffer, &geometry, sizeof(device_geometry));
}
case B_GET_ICON:
return sSCSIPeripheral->get_icon(device->removable
return sSCSIPeripheral->get_icon(info->removable
? icon_type_floppy : icon_type_disk, (device_icon *)buffer);
case B_EJECT_DEVICE:
case B_SCSI_EJECT:
return load_eject(device, false);
return load_eject(info, false);
case B_LOAD_MEDIA:
return load_eject(device, true);
return load_eject(info, true);
case B_FLUSH_DRIVE_CACHE:
return synchronize_cache(device);
return synchronize_cache(info);
default:
return sSCSIPeripheral->ioctl(handle->scsi_periph_handle, op,
@ -271,7 +343,7 @@ das_ioctl(das_handle_info *handle, int op, void *buffer, size_t length)
static void
das_set_capacity(das_device_info *device, uint64 capacity, uint32 blockSize)
das_set_capacity(das_driver_info* info, uint64 capacity, uint32 blockSize)
{
TRACE("das_set_capacity(device = %p, capacity = %Ld, blockSize = %ld)\n",
device, capacity, blockSize);
@ -282,19 +354,40 @@ das_set_capacity(das_device_info *device, uint64 capacity, uint32 blockSize)
if ((1UL << blockShift) != blockSize)
blockShift = 0;
device->capacity = capacity;
device->block_size = blockSize;
info->capacity = capacity;
sBlockIO->set_media_params(device->block_io_device, blockSize,
blockShift, capacity);
if (info->block_size != blockSize) {
if (info->block_size != 0) {
dprintf("old %ld, new %ld\n", info->block_size, blockSize);
panic("updating DMAResource not yet implemented...");
}
// TODO: we need to replace the DMAResource in our IOScheduler
status_t status = info->dma_resource->Init(info->node, blockSize);
if (status != B_OK)
panic("initializing DMAResource failed: %s", strerror(status));
info->io_scheduler = new(std::nothrow) IOScheduler(info->dma_resource);
if (info->io_scheduler == NULL)
panic("allocating IOScheduler failed.");
// TODO: use whole device name here
status = info->io_scheduler->Init("scsi");
if (status != B_OK)
panic("initializing IOScheduler failed: %s", strerror(status));
info->io_scheduler->SetCallback(do_io, info);
}
info->block_size = blockSize;
}
static void
das_media_changed(das_device_info *device, scsi_ccb *request)
das_media_changed(das_driver_info *device, scsi_ccb *request)
{
// do a capacity check
// TBD: is this a good idea (e.g. if this is an empty CD)?
// TODO: is this a good idea (e.g. if this is an empty CD)?
sSCSIPeripheral->check_capacity(device->scsi_periph_device, request);
}
@ -363,53 +456,54 @@ das_register_device(device_node *node)
{"removable", B_UINT8_TYPE, {ui8: deviceInquiry->removable_medium}},
// impose own max block restriction
{B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, {ui32: maxBlocks}},
// in general, any disk can be a BIOS drive (even ZIP-disks)
{B_BLOCK_DEVICE_IS_BIOS_DRIVE, B_UINT8_TYPE, {ui8: 1}},
{ NULL }
};
return sDeviceManager->register_node(node, SCSI_DISK_MODULE_NAME, attrs,
NULL, NULL);
return sDeviceManager->register_node(node, SCSI_DISK_DRIVER_MODULE_NAME,
attrs, NULL, NULL);
}
static status_t
das_init_driver(device_node *node, void **cookie)
{
das_device_info *device;
status_t status;
uint8 removable;
TRACE("das_init_driver");
status = sDeviceManager->get_attr_uint8(node, "removable",
uint8 removable;
status_t status = sDeviceManager->get_attr_uint8(node, "removable",
&removable, false);
if (status != B_OK)
return status;
device = (das_device_info *)malloc(sizeof(*device));
if (device == NULL)
das_driver_info* info = (das_driver_info*)malloc(sizeof(das_driver_info));
if (info == NULL)
return B_NO_MEMORY;
memset(device, 0, sizeof(*device));
memset(info, 0, sizeof(*info));
device->node = node;
device->removable = removable;
info->dma_resource = new(std::nothrow) DMAResource;
if (info->dma_resource == NULL) {
free(info);
return B_NO_MEMORY;
}
device_node *parent = sDeviceManager->get_parent_node(node);
sDeviceManager->get_driver(parent, (driver_module_info **)&device->scsi,
(void **)&device->scsi_device);
info->node = node;
info->removable = removable;
device_node* parent = sDeviceManager->get_parent_node(node);
sDeviceManager->get_driver(parent, (driver_module_info **)&info->scsi,
(void **)&info->scsi_device);
sDeviceManager->put_node(parent);
status = sSCSIPeripheral->register_device((periph_device_cookie)device,
&callbacks, device->scsi_device, device->scsi, device->node,
device->removable, &device->scsi_periph_device);
status = sSCSIPeripheral->register_device((periph_device_cookie)info,
&callbacks, info->scsi_device, info->scsi, info->node,
info->removable, 10, &info->scsi_periph_device);
if (status != B_OK) {
free(device);
free(info);
return status;
}
*cookie = device;
*cookie = info;
return B_OK;
}
@ -417,26 +511,26 @@ das_init_driver(device_node *node, void **cookie)
static void
das_uninit_driver(void *_cookie)
{
das_device_info *device = (das_device_info *)_cookie;
das_driver_info* info = (das_driver_info*)_cookie;
sSCSIPeripheral->unregister_device(device->scsi_periph_device);
free(device);
sSCSIPeripheral->unregister_device(info->scsi_periph_device);
free(info);
}
static status_t
das_register_child_devices(void *_cookie)
das_register_child_devices(void* _cookie)
{
das_device_info *device = (das_device_info *)_cookie;
das_driver_info* info = (das_driver_info*)_cookie;
status_t status;
char *name;
name = sSCSIPeripheral->compose_device_name(device->node, "disk/scsi");
char* name = sSCSIPeripheral->compose_device_name(info->node,
"disk/scsi");
if (name == NULL)
return B_ERROR;
status = sDeviceManager->publish_device(device->node, name,
B_BLOCK_IO_DEVICE_MODULE_NAME);
status = sDeviceManager->publish_device(info->node, name,
SCSI_DISK_DEVICE_MODULE_NAME);
free(name);
return status;
@ -444,43 +538,52 @@ das_register_child_devices(void *_cookie)
module_dependency module_dependencies[] = {
{SCSI_PERIPH_MODULE_NAME, (module_info **)&sSCSIPeripheral},
{B_BLOCK_IO_FOR_DRIVER_MODULE_NAME, (module_info **)&sBlockIO},
{B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager},
{SCSI_PERIPH_MODULE_NAME, (module_info**)&sSCSIPeripheral},
{B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager},
{}
};
block_device_interface sSCSIDiskModule = {
struct device_module_info sSCSIDiskDevice = {
{
{
SCSI_DISK_MODULE_NAME,
0,
NULL
},
das_supports_device,
das_register_device,
das_init_driver,
das_uninit_driver,
das_register_child_devices,
NULL, // rescan
NULL, // removed
SCSI_DISK_DEVICE_MODULE_NAME,
0,
NULL
},
(void (*)(block_device_cookie *, block_io_device)) &das_set_device,
(status_t (*)(block_device_cookie *, block_device_handle_cookie **))&das_open,
(status_t (*)(block_device_handle_cookie *)) &das_close,
(status_t (*)(block_device_handle_cookie *)) &das_free,
das_init_device,
das_uninit_device,
NULL, //das_remove,
(status_t (*)(block_device_handle_cookie *, const phys_vecs *,
off_t, size_t, uint32, size_t *)) &das_read,
(status_t (*)(block_device_handle_cookie *, const phys_vecs *,
off_t, size_t, uint32, size_t *)) &das_write,
das_open,
das_close,
das_free,
das_read,
das_write,
das_io,
das_ioctl,
(status_t (*)(block_device_handle_cookie *, int, void *, size_t))&das_ioctl,
NULL, // select
NULL, // deselect
};
module_info *modules[] = {
(module_info *)&sSCSIDiskModule,
struct driver_module_info sSCSIDiskDriver = {
{
SCSI_DISK_DRIVER_MODULE_NAME,
0,
NULL
},
das_supports_device,
das_register_device,
das_init_driver,
das_uninit_driver,
das_register_child_devices,
NULL, // rescan
NULL, // removed
};
module_info* modules[] = {
(module_info*)&sSCSIDiskDriver,
(module_info*)&sSCSIDiskDevice,
NULL
};

View File

@ -12,27 +12,32 @@
#include <scsi.h>
#include <scsi_periph.h>
#define SCSI_DISK_MODULE_NAME "drivers/disk/scsi/scsi_dsk/driver_v1"
#include "dma_resources.h"
#include "io_requests.h"
#include "IOScheduler.h"
// must start as block_device_cookie
typedef struct das_device_info {
device_node *node;
::scsi_periph_device scsi_periph_device;
::scsi_device scsi_device;
scsi_device_interface *scsi;
::block_io_device block_io_device;
#define SCSI_DISK_DRIVER_MODULE_NAME "drivers/disk/scsi/scsi_disk/driver_v1"
#define SCSI_DISK_DEVICE_MODULE_NAME "drivers/disk/scsi/scsi_disk/device_v1"
uint64 capacity;
uint32 block_size;
bool removable; // true, if device is removable
} das_device_info;
struct das_driver_info {
device_node* node;
::scsi_periph_device scsi_periph_device;
::scsi_device scsi_device;
scsi_device_interface* scsi;
IOScheduler* io_scheduler;
DMAResource* dma_resource;
typedef struct das_handle_info {
::scsi_periph_handle scsi_periph_handle;
das_device_info *device;
} das_handle_info;
uint64 capacity;
uint32 block_size;
bool removable;
};
struct das_handle {
::scsi_periph_handle scsi_periph_handle;
das_driver_info* info;
};
#endif /* _SCSI_DISK_H */

View File

@ -1,6 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel generic scsi_periph ;
UsePrivateHeaders drivers kernel ;
SubDirHdrs $(HAIKU_TOP) src system kernel device_manager ;
# disable debug output, if debugging is disabled
if $(DEBUG) = 0 {
@ -8,13 +9,13 @@ if $(DEBUG) = 0 {
}
KernelAddon scsi_periph :
block.c
device_icons.c
device.c
error_handling.c
handle.c
io.c
removable.c
scsi_periph.c
sync.c
block.cpp
device_icons.cpp
device.cpp
error_handling.cpp
handle.cpp
io.cpp
removable.cpp
scsi_periph.cpp
sync.cpp
;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004-2007, Haiku, Inc. All RightsReserved.
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
@ -24,13 +24,13 @@ periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
SHOW_FLOW(3, "%p, %p", device, request);
// driver doesn't support capacity callback - seems to be no block
// device driver, so ignore
// device driver, so ignore
if (device->callbacks->set_capacity == NULL)
return B_OK;
request->flags = SCSI_DIR_IN;
request->data = (char *)&capacityResult;
request->data = (uint8*)&capacityResult;
request->data_length = sizeof(capacityResult);
request->cdb_length = sizeof(scsi_cmd_read_capacity);
request->timeout = device->std_timeout;
@ -68,7 +68,9 @@ periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
SHOW_FLOW(3, "capacity = %Ld, block_size = %ld", capacity, blockSize);
device->callbacks->set_capacity(device->periph_device,
device->block_size = blockSize;
device->callbacks->set_capacity(device->periph_device,
capacity, blockSize);
/* device->byte2blk_shift = log2( device->block_size );

View File

@ -1,13 +1,11 @@
/*
* Copyright 2004-2006, Haiku, Inc. All RightsReserved.
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
/*
Basic handling of device.
*/
//! Basic handling of device.
#include "scsi_periph_int.h"
@ -27,15 +25,15 @@ periph_compose_device_name(device_node *node, const char *prefix)
char name[128];
uint32 channel;
if (pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &pathID, true) != B_OK
|| pnp->get_attr_uint8(node, SCSI_DEVICE_TARGET_ID_ITEM, &targetID, true) != B_OK
|| pnp->get_attr_uint8(node, SCSI_DEVICE_TARGET_LUN_ITEM, &targetLUN, true) != B_OK)
if (gDeviceManager->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &pathID, true) != B_OK
|| gDeviceManager->get_attr_uint8(node, SCSI_DEVICE_TARGET_ID_ITEM, &targetID, true) != B_OK
|| gDeviceManager->get_attr_uint8(node, SCSI_DEVICE_TARGET_LUN_ITEM, &targetLUN, true) != B_OK)
return NULL;
// IDE devices have a different naming scheme
if (pnp->get_attr_uint32(node, "ide/channel_id", &channel, true) == B_OK
&& pnp->get_attr_uint8(node, SCSI_DEVICE_TYPE_ITEM, &type, true) == B_OK) {
if (gDeviceManager->get_attr_uint32(node, "ide/channel_id", &channel, true) == B_OK
&& gDeviceManager->get_attr_uint8(node, SCSI_DEVICE_TYPE_ITEM, &type, true) == B_OK) {
// this is actually an IDE device, so we ignore the prefix
// a bus device for those
@ -56,7 +54,7 @@ periph_compose_device_name(device_node *node, const char *prefix)
status_t
periph_register_device(periph_device_cookie periph_device, scsi_periph_callbacks *callbacks,
scsi_device scsi_device, scsi_device_interface *scsi, device_node *node,
bool removable, scsi_periph_device *driver)
bool removable, int preferredCcbSize, scsi_periph_device *driver)
{
scsi_periph_device_info *device;
status_t res;
@ -85,6 +83,7 @@ periph_register_device(periph_device_cookie periph_device, scsi_periph_callbacks
// set some default options
device->next_tag_action = 0;
device->preferred_ccb_size = preferredCcbSize;
device->rw10_enabled = true;
// launch sync daemon

View File

@ -15,346 +15,346 @@
const char icon_disk[32*32] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0x00, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0x00, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f,
0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f,
0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff,
0x00, 0x15, 0x15, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
0x00, 0x15, 0x15, 0x39, 0x35, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a,
0x1a, 0x3f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0x00, 0x15, 0x15, 0x35, 0x35, 0x2b, 0x2b, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a,
0x3f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f,
0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1a,
0x15, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0x00, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff,
0x00, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f,
0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f,
0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff,
0x00, 0x15, 0x15, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
0x1a, 0x1a, 0x3f, 0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
0x00, 0x15, 0x15, 0x39, 0x35, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a,
0x1a, 0x3f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0x00, 0x15, 0x15, 0x35, 0x35, 0x2b, 0x2b, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a,
0x3f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f,
0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x1a,
0x15, 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1a,
0x15, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_disk_mini[16*16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x00, 0xff,
0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x0f, 0x00, 0xff,
0x00, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x0f, 0x0f, 0x00, 0xff,
0x00, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f,
0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x3f, 0x0e, 0x0f, 0x0f, 0x00, 0x0f, 0x0f,
0x00, 0x15, 0x35, 0x2b, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x0e, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0xff,
0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x00, 0xff,
0xff, 0x00, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x0f, 0x00, 0xff,
0x00, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x0f, 0x0f, 0x00, 0xff,
0x00, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x3f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f,
0x00, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x1a, 0x1a, 0x3f, 0x0e, 0x0f, 0x0f, 0x00, 0x0f, 0x0f,
0x00, 0x15, 0x35, 0x2b, 0x15, 0x15, 0x15, 0x3f, 0x3f, 0x0e, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0xff,
0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_removable[32*32] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x13, 0x00,
0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x13, 0x00, 0x13,
0x13, 0x13, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x10, 0x00, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0x10, 0x15, 0x00, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x10, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0x15, 0x15, 0x00, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x15, 0x00, 0x23, 0x23, 0x23, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x15, 0x15, 0x00, 0x00, 0x23, 0x23, 0x23, 0x23,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x00, 0x1f, 0x13, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x15, 0x15, 0x15, 0x1f, 0x1f, 0x00, 0x00, 0x23, 0x23,
0x23, 0x23, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x00, 0x1f, 0x13, 0x13, 0x3f, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x1f, 0x00, 0x00,
0x23, 0x23, 0x23, 0x23, 0x15, 0x15, 0x15, 0x15, 0x00, 0x1f, 0x13, 0x13, 0x3f, 0x0a, 0x00, 0x10,
0xff, 0xff, 0x00, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x1f,
0x00, 0x00, 0x23, 0x23, 0x23, 0x23, 0x23, 0x00, 0x1f, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x00, 0x10,
0xff, 0x00, 0x13, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x1f, 0x1f, 0x00, 0x00, 0x23, 0x23, 0x00, 0x1f, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10,
0x00, 0x13, 0x13, 0x13, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x00, 0x0a, 0x15, 0x15, 0x15,
0x15, 0x15, 0x1f, 0x1f, 0x00, 0x00, 0x1f, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff,
0x00, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x13, 0x10, 0x15, 0x15, 0x00, 0x00, 0x3f, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff,
0x00, 0x10, 0x10, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x10, 0x00, 0x00, 0x3f, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff,
0x00, 0x10, 0x10, 0x10, 0x10, 0x3f, 0x3f, 0x13, 0x13, 0x10, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x10, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x3f, 0x3f, 0x13, 0x13, 0x10, 0x10, 0x10, 0x15, 0x15,
0x10, 0x10, 0x10, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x10, 0x10,
0x13, 0x13, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x0a, 0x3f, 0x3f, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x3f, 0x3f, 0x13,
0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x3f,
0x3f, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10,
0x10, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x10, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x13, 0x00,
0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x13, 0x00, 0x13,
0x13, 0x13, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x10, 0x00, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0x10, 0x15, 0x00, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x10, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0x15, 0x15, 0x00, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x15, 0x00, 0x23, 0x23, 0x23, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x15, 0x15, 0x00, 0x00, 0x23, 0x23, 0x23, 0x23,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x00, 0x1f, 0x13, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x10, 0x15, 0x15, 0x15, 0x1f, 0x1f, 0x00, 0x00, 0x23, 0x23,
0x23, 0x23, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x00, 0x1f, 0x13, 0x13, 0x3f, 0x00, 0xff,
0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x1f, 0x00, 0x00,
0x23, 0x23, 0x23, 0x23, 0x15, 0x15, 0x15, 0x15, 0x00, 0x1f, 0x13, 0x13, 0x3f, 0x0a, 0x00, 0x10,
0xff, 0xff, 0x00, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x1f,
0x00, 0x00, 0x23, 0x23, 0x23, 0x23, 0x23, 0x00, 0x1f, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x00, 0x10,
0xff, 0x00, 0x13, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x1f, 0x1f, 0x00, 0x00, 0x23, 0x23, 0x00, 0x1f, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10,
0x00, 0x13, 0x13, 0x13, 0x13, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x00, 0x0a, 0x15, 0x15, 0x15,
0x15, 0x15, 0x1f, 0x1f, 0x00, 0x00, 0x1f, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff,
0x00, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x13, 0x10, 0x15, 0x15, 0x00, 0x00, 0x3f, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff,
0x00, 0x10, 0x10, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x10, 0x00, 0x00, 0x3f, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff,
0x00, 0x10, 0x10, 0x10, 0x10, 0x3f, 0x3f, 0x13, 0x13, 0x10, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x10, 0x10, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x3f, 0x3f, 0x13, 0x13, 0x10, 0x10, 0x10, 0x15, 0x15,
0x10, 0x10, 0x10, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x10, 0x10,
0x13, 0x13, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x0a, 0x3f, 0x3f, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x3f, 0x3f, 0x13,
0x13, 0x13, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x3f,
0x3f, 0x3f, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10,
0x10, 0x0a, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x10, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_removable_mini[16*16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00, 0x15, 0x15, 0x15, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x13, 0x10, 0x00, 0x23, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x00, 0x00, 0x00,
0xff, 0x00, 0x13, 0x10, 0x15, 0x15, 0x00, 0x00, 0x23, 0x15, 0x15, 0x15, 0x00, 0x15, 0x0a, 0x00,
0x00, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x23, 0x00, 0x13, 0x0a, 0x0a, 0x00,
0x00, 0x3f, 0x13, 0x10, 0x15, 0x00, 0x3f, 0x15, 0x15, 0x15, 0x00, 0x15, 0x0a, 0x0a, 0x00, 0x10,
0x00, 0x10, 0x3f, 0x3f, 0x00, 0x3f, 0x15, 0x15, 0x15, 0x10, 0x15, 0x0a, 0x0a, 0x00, 0x10, 0xff,
0x00, 0x00, 0x10, 0x10, 0x3f, 0x3f, 0x10, 0x10, 0x10, 0x15, 0x0a, 0x0a, 0x00, 0x0e, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x10, 0x0a, 0x3f, 0x3f, 0x15, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x13, 0x13, 0x00, 0x15, 0x15, 0x15, 0x10, 0x13, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0x13, 0x10, 0x00, 0x23, 0x15, 0x15, 0x15, 0x15, 0x15, 0x10, 0x00, 0x00, 0x00,
0xff, 0x00, 0x13, 0x10, 0x15, 0x15, 0x00, 0x00, 0x23, 0x15, 0x15, 0x15, 0x00, 0x15, 0x0a, 0x00,
0x00, 0x13, 0x10, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x23, 0x00, 0x13, 0x0a, 0x0a, 0x00,
0x00, 0x3f, 0x13, 0x10, 0x15, 0x00, 0x3f, 0x15, 0x15, 0x15, 0x00, 0x15, 0x0a, 0x0a, 0x00, 0x10,
0x00, 0x10, 0x3f, 0x3f, 0x00, 0x3f, 0x15, 0x15, 0x15, 0x10, 0x15, 0x0a, 0x0a, 0x00, 0x10, 0xff,
0x00, 0x00, 0x10, 0x10, 0x3f, 0x3f, 0x10, 0x10, 0x10, 0x15, 0x0a, 0x0a, 0x00, 0x0e, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x10, 0x0a, 0x3f, 0x3f, 0x15, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_floppy[32*32] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x0e,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0x0f,
0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x00,
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x2d, 0x2e,
0x2d, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x2d,
0x2e, 0x2d, 0xd2, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0xd2, 0xd2, 0xd2, 0xd2, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0xd2, 0xd2, 0xd2, 0xd2, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xd2, 0xd2, 0x00, 0x17, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0e, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x17, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x00, 0x0f, 0x0f, 0x0e, 0xff,
0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x18, 0x17, 0x00, 0x00, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x00, 0x0f, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x18, 0x17, 0x00, 0x00,
0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x15, 0x00, 0x00, 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, 0x18, 0x17,
0x00, 0x00, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x15, 0x00, 0x18, 0x17, 0x00, 0x00, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a,
0x18, 0x17, 0x00, 0x17, 0x0b, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x0f, 0x0e, 0xff, 0xff, 0xff, 0xff,
0x00, 0x3f, 0x3f, 0x0a, 0x15, 0x00, 0x18, 0x17, 0x04, 0x0b, 0x17, 0x00, 0x00, 0x0b, 0x0b, 0x0a,
0x0b, 0x0b, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x15, 0x15, 0x3f, 0x00, 0x17, 0x17, 0x05, 0x00, 0x04, 0x17, 0x18, 0x17, 0x00, 0x00, 0x0b,
0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x15, 0x00, 0x3f, 0x3f, 0x00, 0x04, 0x17, 0x18, 0x17, 0x17, 0x18, 0x17, 0x00,
0x0b, 0x0a, 0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x3f, 0x17, 0x17, 0x18, 0x17, 0x17, 0x00, 0x18,
0x0a, 0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x3f, 0x17, 0x17, 0x00, 0x18, 0x0a,
0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x00, 0x17, 0x0b, 0x0a,
0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x00, 0x3f, 0x3f, 0x0a,
0x04, 0x05, 0x00, 0x0f, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x04,
0x05, 0x00, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x04,
0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x0e,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0x0f,
0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x00,
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x2d, 0x2e,
0x2d, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x2d,
0x2e, 0x2d, 0xd2, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0xd2, 0xd2, 0xd2, 0xd2, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0xd2, 0xd2, 0xd2, 0xd2, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x04, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xd2, 0xd2, 0x00, 0x17, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0e, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x17, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x00, 0x0f, 0x0f, 0x0e, 0xff,
0xff, 0xff, 0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x18, 0x17, 0x00, 0x00, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x00, 0x0f, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x18, 0x17, 0x00, 0x00,
0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x15, 0x00, 0x00, 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, 0x18, 0x17,
0x00, 0x00, 0x3f, 0x00, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0x00, 0x0a, 0x0b, 0x0a, 0x0b, 0x15, 0x00, 0x18, 0x17, 0x00, 0x00, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a,
0x18, 0x17, 0x00, 0x17, 0x0b, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x0f, 0x0e, 0xff, 0xff, 0xff, 0xff,
0x00, 0x3f, 0x3f, 0x0a, 0x15, 0x00, 0x18, 0x17, 0x04, 0x0b, 0x17, 0x00, 0x00, 0x0b, 0x0b, 0x0a,
0x0b, 0x0b, 0x17, 0x0b, 0x0a, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x15, 0x15, 0x3f, 0x00, 0x17, 0x17, 0x05, 0x00, 0x04, 0x17, 0x18, 0x17, 0x00, 0x00, 0x0b,
0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x15, 0x00, 0x3f, 0x3f, 0x00, 0x04, 0x17, 0x18, 0x17, 0x17, 0x18, 0x17, 0x00,
0x0b, 0x0a, 0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x3f, 0x17, 0x17, 0x18, 0x17, 0x17, 0x00, 0x18,
0x0a, 0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x3f, 0x17, 0x17, 0x00, 0x18, 0x0a,
0x0b, 0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x00, 0x17, 0x0b, 0x0a,
0x0b, 0x04, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x00, 0x3f, 0x3f, 0x0a,
0x04, 0x05, 0x00, 0x0f, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x15, 0x04,
0x05, 0x00, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x04,
0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_floppy_mini[16*16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x3f, 0x2d, 0x2e, 0x2d, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x0a, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0xd2, 0xd2, 0xd2, 0x00, 0x00, 0x0e, 0x0f,
0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x0a, 0x00, 0x0f, 0x0f,
0x00, 0x0b, 0x0a, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, 0x3f, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x0f,
0x00, 0x3f, 0x00, 0x17, 0x17, 0x00, 0x00, 0x0b, 0x0b, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x0f, 0xff,
0x00, 0x15, 0x00, 0x3f, 0x3f, 0x17, 0x17, 0x00, 0x0b, 0x0b, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x3f, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x00, 0x0a, 0x05, 0x00, 0x0f, 0x0e, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x3f, 0x2d, 0x2e, 0x2d, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x0a, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0xd2, 0xd2, 0xd2, 0x00, 0x00, 0x0e, 0x0f,
0xff, 0x00, 0x0a, 0x0b, 0x0a, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x0a, 0x00, 0x0f, 0x0f,
0x00, 0x0b, 0x0a, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, 0x3f, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x0f,
0x00, 0x3f, 0x00, 0x17, 0x17, 0x00, 0x00, 0x0b, 0x0b, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x0f, 0xff,
0x00, 0x15, 0x00, 0x3f, 0x3f, 0x17, 0x17, 0x00, 0x0b, 0x0b, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x00, 0x15, 0x15, 0x3f, 0x3f, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x15, 0x00, 0x0a, 0x05, 0x00, 0x0f, 0x0e, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_cd[32*32] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x19, 0x1a, 0x19, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1d, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x19, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x1a,
0x1a, 0x1a, 0x19, 0x3f, 0x3f, 0x19, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1d, 0x1e, 0x3f, 0x3f, 0x3f, 0x3f, 0x19, 0x1a, 0x19, 0x1a, 0x1a, 0x1a,
0x1a, 0x19, 0x1a, 0x3f, 0x19, 0x1a, 0x19, 0x3f, 0x1e, 0x1e, 0x00, 0x0e, 0x0e, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1d, 0x1a, 0x19, 0x1a, 0x3f, 0x3f, 0x3f, 0x3f, 0x19, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x3f, 0x3f, 0x19, 0x3f, 0x3f, 0x1a, 0x19, 0x1a, 0x1d, 0x00, 0x0f, 0x0e, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1d, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x3f, 0x14, 0x14, 0x1e, 0x1e, 0x1e, 0x1d,
0x1e, 0x1e, 0x14, 0x14, 0x3f, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x1e, 0x00, 0x0e, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x19, 0x1a, 0x19, 0x1a, 0x14, 0x1e, 0x1d, 0x09, 0x00, 0x00,
0x08, 0x1e, 0x3f, 0x14, 0x19, 0x1a, 0x19, 0x1a, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x44, 0x44, 0xd8, 0x14, 0x1e, 0x1e, 0x00, 0x0f, 0x0f, 0x0f,
0x0f, 0x08, 0x1e, 0x1e, 0x14, 0xd8, 0x44, 0x44, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x44, 0x44, 0xd8, 0x14, 0x1e, 0x1d, 0x00, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x1e, 0x1d, 0x14, 0xd8, 0x44, 0x44, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0e, 0x0f, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x19, 0x1a, 0x19, 0x1a, 0x14, 0x1e, 0x1d, 0x09, 0x00, 0x00,
0x08, 0x1e, 0x1e, 0x14, 0x19, 0x19, 0x1a, 0x19, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x14, 0x14, 0x1e, 0x1e, 0x1e, 0x1d,
0x1e, 0x1e, 0x14, 0x14, 0x3f, 0x19, 0x19, 0x19, 0x1a, 0x19, 0x1a, 0x00, 0x0f, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x1d, 0x1d, 0x1a, 0x19, 0x1a, 0x1a, 0x3f, 0x19, 0x3f, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x19, 0x3f, 0x3f, 0x3f, 0x3f, 0x19, 0x19, 0x3f, 0x1d, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1d, 0x1e, 0x1a, 0x3f, 0x3f, 0x1a, 0x19, 0x3f, 0x3f, 0x1a, 0x19, 0x19,
0x19, 0x19, 0x1a, 0x19, 0x3f, 0x3f, 0x3f, 0x3f, 0x1d, 0x1e, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0x1d, 0x1a, 0x19, 0x3f, 0x3f, 0x19, 0x1a, 0x19, 0x19,
0x19, 0x19, 0x1a, 0x19, 0x1a, 0x3f, 0x3f, 0x3f, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x19, 0x1a, 0x19, 0x19, 0x19,
0x19, 0x19, 0x1a, 0x1d, 0x1e, 0x1e, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x19, 0x1a, 0x19, 0x1a, 0x1a,
0x1a, 0x1a, 0x1a, 0x1d, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x19, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x1a,
0x1a, 0x1a, 0x19, 0x3f, 0x3f, 0x19, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1d, 0x1e, 0x3f, 0x3f, 0x3f, 0x3f, 0x19, 0x1a, 0x19, 0x1a, 0x1a, 0x1a,
0x1a, 0x19, 0x1a, 0x3f, 0x19, 0x1a, 0x19, 0x3f, 0x1e, 0x1e, 0x00, 0x0e, 0x0e, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1d, 0x1a, 0x19, 0x1a, 0x3f, 0x3f, 0x3f, 0x3f, 0x19, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x3f, 0x3f, 0x19, 0x3f, 0x3f, 0x1a, 0x19, 0x1a, 0x1d, 0x00, 0x0f, 0x0e, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1d, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x3f, 0x14, 0x14, 0x1e, 0x1e, 0x1e, 0x1d,
0x1e, 0x1e, 0x14, 0x14, 0x3f, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x1e, 0x00, 0x0e, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x19, 0x1a, 0x19, 0x1a, 0x14, 0x1e, 0x1d, 0x09, 0x00, 0x00,
0x08, 0x1e, 0x3f, 0x14, 0x19, 0x1a, 0x19, 0x1a, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x44, 0x44, 0xd8, 0x14, 0x1e, 0x1e, 0x00, 0x0f, 0x0f, 0x0f,
0x0f, 0x08, 0x1e, 0x1e, 0x14, 0xd8, 0x44, 0x44, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x44, 0x44, 0xd8, 0x14, 0x1e, 0x1d, 0x00, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x1e, 0x1d, 0x14, 0xd8, 0x44, 0x44, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0e, 0x0f, 0xff,
0xff, 0x00, 0x60, 0x60, 0x41, 0x41, 0x19, 0x1a, 0x19, 0x1a, 0x14, 0x1e, 0x1d, 0x09, 0x00, 0x00,
0x08, 0x1e, 0x1e, 0x14, 0x19, 0x19, 0x1a, 0x19, 0x41, 0x41, 0x60, 0x60, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x19, 0x1a, 0x14, 0x14, 0x1e, 0x1e, 0x1e, 0x1d,
0x1e, 0x1e, 0x14, 0x14, 0x3f, 0x19, 0x19, 0x19, 0x1a, 0x19, 0x1a, 0x00, 0x0f, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0x00, 0x1d, 0x1d, 0x1a, 0x19, 0x1a, 0x1a, 0x3f, 0x19, 0x3f, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x19, 0x3f, 0x3f, 0x3f, 0x3f, 0x19, 0x19, 0x3f, 0x1d, 0x00, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x1d, 0x1e, 0x1a, 0x3f, 0x3f, 0x1a, 0x19, 0x3f, 0x3f, 0x1a, 0x19, 0x19,
0x19, 0x19, 0x1a, 0x19, 0x3f, 0x3f, 0x3f, 0x3f, 0x1d, 0x1e, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0x1d, 0x1a, 0x19, 0x3f, 0x3f, 0x19, 0x1a, 0x19, 0x19,
0x19, 0x19, 0x1a, 0x19, 0x1a, 0x3f, 0x3f, 0x3f, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x19, 0x1a, 0x19, 0x19, 0x19,
0x19, 0x19, 0x1a, 0x1d, 0x1e, 0x1e, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
const char icon_cd_mini[16*16] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1d, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x1d, 0x1e, 0x1a, 0x1a, 0x18, 0x18, 0x18, 0x19, 0x19, 0x1e, 0x1e, 0x00, 0x0f, 0xff,
0x00, 0x60, 0x41, 0x1a, 0x3f, 0x14, 0x1d, 0x00, 0x1d, 0x14, 0x3f, 0x19, 0x41, 0x60, 0x00, 0x0f,
0x00, 0x60, 0x41, 0x44, 0xd8, 0x1e, 0x00, 0xff, 0x00, 0x1e, 0xd8, 0x44, 0x41, 0x60, 0x00, 0x0f,
0x00, 0x60, 0x41, 0x44, 0x18, 0x14, 0x1e, 0x00, 0x1e, 0x14, 0x1d, 0x44, 0x41, 0x60, 0x00, 0x0f,
0x00, 0x1d, 0x1a, 0x19, 0x19, 0x3f, 0x18, 0x18, 0x18, 0x3f, 0x1d, 0x1a, 0x19, 0x1d, 0x00, 0x0f,
0xff, 0x00, 0x1d, 0x1e, 0x3f, 0x19, 0x19, 0x18, 0x18, 0x18, 0x3f, 0x1d, 0x1d, 0x00, 0x0f, 0x0f,
0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1d, 0x00, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1d, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0x00, 0x1d, 0x1e, 0x1a, 0x1a, 0x18, 0x18, 0x18, 0x19, 0x19, 0x1e, 0x1e, 0x00, 0x0f, 0xff,
0x00, 0x60, 0x41, 0x1a, 0x3f, 0x14, 0x1d, 0x00, 0x1d, 0x14, 0x3f, 0x19, 0x41, 0x60, 0x00, 0x0f,
0x00, 0x60, 0x41, 0x44, 0xd8, 0x1e, 0x00, 0xff, 0x00, 0x1e, 0xd8, 0x44, 0x41, 0x60, 0x00, 0x0f,
0x00, 0x60, 0x41, 0x44, 0x18, 0x14, 0x1e, 0x00, 0x1e, 0x14, 0x1d, 0x44, 0x41, 0x60, 0x00, 0x0f,
0x00, 0x1d, 0x1a, 0x19, 0x19, 0x3f, 0x18, 0x18, 0x18, 0x3f, 0x1d, 0x1a, 0x19, 0x1d, 0x00, 0x0f,
0xff, 0x00, 0x1d, 0x1e, 0x3f, 0x19, 0x19, 0x18, 0x18, 0x18, 0x3f, 0x1d, 0x1d, 0x00, 0x0f, 0x0f,
0xff, 0xff, 0x00, 0x00, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1d, 0x00, 0x00, 0x0f, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
@ -374,7 +374,7 @@ periph_get_icon(icon_type type, device_icon *data)
{
SHOW_FLOW( 3, "%d", type );
if (type < 0 || type >= sizeof(icons) / sizeof(icons[0]))
if (type < 0 || type >= int(sizeof(icons) / sizeof(icons[0])))
return B_BAD_INDEX;
switch (data->icon_size) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004-2007, Haiku, Inc. All RightsReserved.
* Copyright 2004-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
@ -15,184 +15,17 @@
#include <stdlib.h>
// we don't want to inline this function - it's just not worth it
static int periph_read_write(scsi_periph_handle_info *handle, const phys_vecs *vecs,
off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size, bool write);
status_t
periph_read(scsi_periph_handle_info *handle, const phys_vecs *vecs, off_t pos,
size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size)
{
return periph_read_write(handle, vecs, pos, num_blocks, block_size,
bytes_transferred, preferred_ccb_size, false);
}
status_t
periph_write(scsi_periph_handle_info *handle, const phys_vecs *vecs, off_t pos,
size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size)
{
return periph_read_write(handle, vecs, pos, num_blocks, block_size,
bytes_transferred, preferred_ccb_size, true);
}
/*! Universal read/write function */
static int
periph_read_write(scsi_periph_handle_info *handle, const phys_vecs *vecs,
off_t pos64, size_t num_blocks, uint32 block_size,
size_t *bytes_transferred, int preferred_ccb_size, bool write)
{
scsi_periph_device_info *device = handle->device;
scsi_ccb *request;
err_res res;
int retries = 0;
int err;
uint32 pos = pos64;
// don't test rw10_enabled restrictions - this flag may get changed
request = device->scsi->alloc_ccb(device->scsi_device);
if (request == NULL)
return B_NO_MEMORY;
do {
size_t num_bytes;
bool is_rw10;
request->flags = write ? SCSI_DIR_OUT : SCSI_DIR_IN;
// make sure we avoid 10 byte commands if they aren't supported
if( !device->rw10_enabled || preferred_ccb_size == 6) {
// restricting transfer is OK - the block manager will
// take care of transferring the rest
if (num_blocks > 0x100)
num_blocks = 0x100;
// no way to break the 21 bit address limit
if (pos64 > 0x200000) {
err = B_BAD_VALUE;
goto abort;
}
// don't allow transfer cross the 24 bit address limit
// (I'm not sure whether this is allowed, but this way we
// are sure to not ask for trouble)
if (pos < 0x100000)
num_blocks = min(num_blocks, 0x100000 - pos);
}
num_bytes = num_blocks * block_size;
request->data = NULL;
request->sg_list = vecs->vec;
request->data_length = num_bytes;
request->sg_count = vecs->num;
request->sort = pos;
request->timeout = device->std_timeout;
// see whether daemon instructed us to post an ordered command;
// reset flag after read
SHOW_FLOW( 3, "flag=%x, next_tag=%x, ordered: %s",
(int)request->flags, (int)device->next_tag_action,
(request->flags & SCSI_ORDERED_QTAG) != 0 ? "yes" : "no" );
// use shortest commands whenever possible
if (pos + num_blocks < 0x200000 && num_blocks <= 0x100) {
scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb;
is_rw10 = false;
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = write ? SCSI_OP_WRITE_6 : SCSI_OP_READ_6;
cmd->high_lba = (pos >> 16) & 0x1f;
cmd->mid_lba = (pos >> 8) & 0xff;
cmd->low_lba = pos & 0xff;
cmd->length = num_blocks;
request->cdb_length = sizeof(*cmd);
} else {
scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;
is_rw10 = true;
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = write ? SCSI_OP_WRITE_10 : SCSI_OP_READ_10;
cmd->relative_address = 0;
cmd->force_unit_access = 0;
cmd->disable_page_out = 0;
cmd->lba = B_HOST_TO_BENDIAN_INT32(pos);
cmd->length = B_HOST_TO_BENDIAN_INT16(num_blocks);
request->cdb_length = sizeof(*cmd);
}
// last chance to detect errors that occured during concurrent accesses
err = handle->pending_error;
if (err)
goto abort;
device->scsi->async_io(request);
acquire_sem(request->completion_sem);
// ask generic peripheral layer what to do now
res = periph_check_error(device, request);
switch (res.action) {
case err_act_ok:
*bytes_transferred = num_bytes - request->data_resid;
break;
case err_act_start:
res = periph_send_start_stop(device, request, 1, device->removable);
if (res.action == err_act_ok)
res.action = err_act_retry;
break;
case err_act_invalid_req:
// if this was a 10 byte command, the device probably doesn't
// support them, so disable them and retry
if (is_rw10) {
atomic_and(&device->rw10_enabled, 0);
res.action = err_act_retry;
} else
res.action = err_act_fail;
break;
}
} while((res.action == err_act_retry && retries++ < 3)
|| (res.action == err_act_many_retries && retries++ < 30));
device->scsi->free_ccb(request);
// peripheral layer only created "read" error, so we have to
// map them to "write" errors if this was a write request
if (res.error_code == B_DEV_READ_ERROR && write)
return B_DEV_WRITE_ERROR;
return res.error_code;
abort:
device->scsi->free_ccb(request);
return err;
}
static status_t
inquiry(scsi_periph_device_info *device, scsi_inquiry *inquiry)
{
const scsi_res_inquiry *device_inquiry = NULL;
size_t inquiry_len;
size_t inquiryLength;
if (pnp->get_attr_raw(device->node, SCSI_DEVICE_INQUIRY_ITEM,
(const void **)&device_inquiry, &inquiry_len, true) != B_OK)
if (gDeviceManager->get_attr_raw(device->node, SCSI_DEVICE_INQUIRY_ITEM,
(const void **)&device_inquiry, &inquiryLength, true) != B_OK)
return B_ERROR;
memcpy(inquiry, device_inquiry, min(inquiry_len, sizeof(scsi_inquiry)));
memcpy(inquiry, device_inquiry, min_c(inquiryLength, sizeof(scsi_inquiry)));
return B_OK;
}
@ -234,7 +67,7 @@ raw_command(scsi_periph_device_info *device, raw_device_command *cmd)
else
request->flags |= SCSI_DIR_NONE;
request->data = cmd->data;
request->data = (uint8*)cmd->data;
request->sg_list = NULL;
request->data_length = cmd->data_length;
request->sort = -1;
@ -252,8 +85,8 @@ raw_command(scsi_periph_device_info *device, raw_device_command *cmd)
cmd->scsi_status = request->device_status;
if ((request->subsys_status & SCSI_AUTOSNS_VALID) != 0 && cmd->sense_data) {
memcpy(cmd->sense_data, request->sense,
min(cmd->sense_data_length, (size_t)SCSI_MAX_SENSE_SIZE - request->sense_resid));
memcpy(cmd->sense_data, request->sense, min_c(cmd->sense_data_length,
(size_t)SCSI_MAX_SENSE_SIZE - request->sense_resid));
}
if ((cmd->flags & B_RAW_DEVICE_REPORT_RESIDUAL) != 0) {
@ -271,7 +104,8 @@ raw_command(scsi_periph_device_info *device, raw_device_command *cmd)
status_t
periph_ioctl(scsi_periph_handle_info *handle, int op, void *buffer, size_t length)
periph_ioctl(scsi_periph_handle_info *handle, int op, void *buffer,
size_t length)
{
switch (op) {
case B_GET_MEDIA_STATUS: {
@ -293,7 +127,7 @@ periph_ioctl(scsi_periph_handle_info *handle, int op, void *buffer, size_t lengt
return prevent_allow(handle->device, *(bool *)buffer);
case B_RAW_DEVICE_COMMAND:
return raw_command(handle->device, buffer);
return raw_command(handle->device, (raw_device_command*)buffer);
default:
if (handle->device->scsi->ioctl != NULL) {
@ -307,13 +141,12 @@ periph_ioctl(scsi_periph_handle_info *handle, int op, void *buffer, size_t lengt
}
/** kernel daemon
* once in a minute, it sets a flag so that the next command is executed
* ordered; this way, we avoid starvation of SCSI commands inside the
* SCSI queuing system - the ordered command waits for all previous
* commands and thus no command can starve longer then a minute
*/
/*! kernel daemon
once in a minute, it sets a flag so that the next command is executed
ordered; this way, we avoid starvation of SCSI commands inside the
SCSI queuing system - the ordered command waits for all previous
commands and thus no command can starve longer then a minute
*/
void
periph_sync_queue_daemon(void *arg, int iteration)
{
@ -322,3 +155,151 @@ periph_sync_queue_daemon(void *arg, int iteration)
SHOW_FLOW0(3, "Setting ordered flag for next R/W access");
atomic_or(&device->next_tag_action, SCSI_ORDERED_QTAG);
}
/*! Universal read/write function */
status_t
periph_io(scsi_periph_device_info *device, io_operation *operation,
size_t* _bytesTransferred)
{
uint32 blockSize = device->block_size;
size_t numBlocks = operation->Length() / blockSize;
uint32 pos = operation->Offset() / blockSize;
scsi_ccb *request;
err_res res;
int retries = 0;
int err;
// don't test rw10_enabled restrictions - this flag may get changed
request = device->scsi->alloc_ccb(device->scsi_device);
if (request == NULL)
return B_NO_MEMORY;
do {
size_t numBytes;
bool is_rw10;
request->flags = operation->IsWrite() ? SCSI_DIR_OUT : SCSI_DIR_IN;
// make sure we avoid 10 byte commands if they aren't supported
if( !device->rw10_enabled || device->preferred_ccb_size == 6) {
// restricting transfer is OK - the block manager will
// take care of transferring the rest
if (numBlocks > 0x100)
numBlocks = 0x100;
// no way to break the 21 bit address limit
if (pos > 0x200000) {
err = B_BAD_VALUE;
goto abort;
}
// don't allow transfer cross the 24 bit address limit
// (I'm not sure whether this is allowed, but this way we
// are sure to not ask for trouble)
if (pos < 0x100000)
numBlocks = min_c(numBlocks, 0x100000 - pos);
}
numBytes = numBlocks * blockSize;
if (numBytes != operation->Length())
panic("I/O operation would need to be cut.");
request->data = NULL;
request->sg_list = (physical_entry*)operation->Vecs();
request->data_length = numBytes;
request->sg_count = operation->VecCount();
request->io_operation = operation;
request->sort = pos;
request->timeout = device->std_timeout;
// see whether daemon instructed us to post an ordered command;
// reset flag after read
SHOW_FLOW( 3, "flag=%x, next_tag=%x, ordered: %s",
(int)request->flags, (int)device->next_tag_action,
(request->flags & SCSI_ORDERED_QTAG) != 0 ? "yes" : "no" );
// use shortest commands whenever possible
if (pos + numBlocks < 0x200000 && numBlocks <= 0x100) {
scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb;
is_rw10 = false;
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = operation->IsWrite()
? SCSI_OP_WRITE_6 : SCSI_OP_READ_6;
cmd->high_lba = (pos >> 16) & 0x1f;
cmd->mid_lba = (pos >> 8) & 0xff;
cmd->low_lba = pos & 0xff;
cmd->length = numBlocks;
request->cdb_length = sizeof(*cmd);
} else {
scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;
is_rw10 = true;
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = operation->IsWrite()
? SCSI_OP_WRITE_10 : SCSI_OP_READ_10;
cmd->relative_address = 0;
cmd->force_unit_access = 0;
cmd->disable_page_out = 0;
cmd->lba = B_HOST_TO_BENDIAN_INT32(pos);
cmd->length = B_HOST_TO_BENDIAN_INT16(numBlocks);
request->cdb_length = sizeof(*cmd);
}
// last chance to detect errors that occured during concurrent accesses
err = 0; // TODO: handle->pending_error;
if (err)
goto abort;
device->scsi->async_io(request);
acquire_sem(request->completion_sem);
// ask generic peripheral layer what to do now
res = periph_check_error(device, request);
switch (res.action) {
case err_act_ok:
*_bytesTransferred = numBytes - request->data_resid;
break;
case err_act_start:
res = periph_send_start_stop(device, request, 1,
device->removable);
if (res.action == err_act_ok)
res.action = err_act_retry;
break;
case err_act_invalid_req:
// if this was a 10 byte command, the device probably doesn't
// support them, so disable them and retry
if (is_rw10) {
atomic_and(&device->rw10_enabled, 0);
res.action = err_act_retry;
} else
res.action = err_act_fail;
break;
}
} while((res.action == err_act_retry && retries++ < 3)
|| (res.action == err_act_many_retries && retries++ < 30));
device->scsi->free_ccb(request);
// peripheral layer only created "read" error, so we have to
// map them to "write" errors if this was a write request
if (res.error_code == B_DEV_READ_ERROR && write)
return B_DEV_WRITE_ERROR;
return res.error_code;
abort:
device->scsi->free_ccb(request);
return err;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004-2007, Haiku, Inc. All RightsReserved.
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
@ -15,19 +15,16 @@
#include <string.h>
device_manager_info *pnp;
device_manager_info* gDeviceManager;
status_t
periph_simple_exec(scsi_periph_device_info *device, void *cdb, uchar cdbLength,
void *data, size_t dataLength, int ccb_flags)
periph_simple_exec(scsi_periph_device_info* device, void* cdb, uchar cdbLength,
void* data, size_t dataLength, int ccb_flags)
{
scsi_ccb *ccb;
status_t res;
SHOW_FLOW0( 0, "" );
ccb = device->scsi->alloc_ccb(device->scsi_device);
scsi_ccb* ccb = device->scsi->alloc_ccb(device->scsi_device);
if (ccb == NULL)
return B_NO_MEMORY;
@ -39,15 +36,15 @@ periph_simple_exec(scsi_periph_device_info *device, void *cdb, uchar cdbLength,
ccb->sort = -1;
ccb->timeout = device->std_timeout;
ccb->data = data;
ccb->data = (uint8*)data;
ccb->sg_list = NULL;
ccb->data_length = dataLength;
res = periph_safe_exec(device, ccb);
status_t status = periph_safe_exec(device, ccb);
device->scsi->free_ccb(ccb);
return res;
return status;
}
@ -60,7 +57,7 @@ periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request)
do {
device->scsi->sync_io(request);
// ask generic peripheral layer what to do now
// ask generic peripheral layer what to do now
res = periph_check_error(device, request);
if (res.action == err_act_start) {
// backup request, as we need it temporarily for sending "start"
@ -111,45 +108,30 @@ periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request)
}
static status_t
std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
default:
return B_ERROR;
}
}
module_dependency module_dependencies[] = {
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp },
{B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager},
{}
};
scsi_periph_interface scsi_periph_module = {
static scsi_periph_interface sSCSIPeripheralModule = {
{
SCSI_PERIPH_MODULE_NAME,
0,
std_ops
NULL
},
periph_register_device,
periph_unregister_device,
periph_safe_exec,
periph_simple_exec,
periph_handle_open,
periph_handle_close,
periph_handle_free,
periph_read,
periph_write,
periph_io,
periph_ioctl,
periph_check_capacity,
@ -157,14 +139,14 @@ scsi_periph_interface scsi_periph_module = {
periph_check_error,
periph_send_start_stop,
periph_get_media_status,
periph_compose_device_name,
periph_get_icon,
periph_synchronize_cache
};
scsi_periph_interface *modules[] = {
&scsi_periph_module,
&sSCSIPeripheralModule,
NULL
};

View File

@ -1,4 +1,5 @@
/*
* Copyright 2004-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2002, Thomas Kurschel. All rights reserved.
* Distributed under the terms of the MIT License.
*/
@ -6,19 +7,20 @@
#define __SCSI_PERIPH_INT_H__
#include <stddef.h>
#include <scsi_periph.h>
#include <block_io.h>
#include <device_manager.h>
#include <stddef.h>
#include "io_requests.h"
#include "wrapper.h"
typedef struct scsi_periph_device_info {
struct scsi_periph_handle_info *handles;
scsi_device scsi_device;
::scsi_device scsi_device;
scsi_device_interface *scsi;
periph_device_cookie periph_device;
device_node *node;
@ -27,10 +29,12 @@ typedef struct scsi_periph_device_info {
bool removable; // true, if device is removable
uint32 block_size;
int32 preferred_ccb_size;
int32 rw10_enabled; // 10 byte r/w commands supported; access must be atomic
int32 next_tag_action; // queuing flag for next r/w command; access must be atomic
mutex mutex;
struct mutex mutex;
int std_timeout;
scsi_periph_callbacks *callbacks;
@ -46,7 +50,7 @@ typedef struct scsi_periph_handle_info {
periph_handle_cookie periph_handle;
} scsi_periph_handle_info;
extern device_manager_info *pnp;
extern device_manager_info *gDeviceManager;
// removable.c
@ -79,20 +83,17 @@ status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
// device.c
status_t periph_register_device(periph_device_cookie periph_device,
scsi_periph_callbacks *callbacks, scsi_device scsi_device, scsi_device_interface *scsi,
device_node *node, bool removable, scsi_periph_device *driver);
scsi_periph_callbacks *callbacks, scsi_device scsi_device,
scsi_device_interface *scsi, device_node *node, bool removable,
int preferredCcbSize, scsi_periph_device *driver);
status_t periph_unregister_device(scsi_periph_device_info *driver);
char *periph_compose_device_name(device_node *device_node, const char *prefix);
// io.c
status_t periph_read(scsi_periph_handle_info *handle, const phys_vecs *vecs,
off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size);
status_t periph_write(scsi_periph_handle_info *handle, const phys_vecs *vecs,
off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
int preferred_ccb_size);
status_t periph_io(scsi_periph_device_info* device, io_operation* operation,
size_t *_bytesTransferred);
status_t periph_ioctl(scsi_periph_handle_info *handle, int op,
void *buf, size_t len);
void periph_sync_queue_daemon(void *arg, int iteration);