From 24593e2c79f5f228fd9e1edd3e705d5aa286dcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 5 Aug 2008 21:11:51 +0000 Subject: [PATCH] * 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 --- build/jam/HaikuImage | 4 +- headers/os/drivers/bus/SCSI.h | 1 + headers/private/drivers/scsi_periph.h | 78 +-- .../kernel/bus_managers/ata/ata_request.c | 10 +- src/add-ons/kernel/bus_managers/scsi/ccb.c | 5 +- .../drivers/disk/scsi/scsi_disk/Jamfile | 1 + .../drivers/disk/scsi/scsi_disk/scsi_disk.cpp | 321 ++++++--- .../drivers/disk/scsi/scsi_disk/scsi_disk.h | 39 +- .../kernel/generic/scsi_periph/Jamfile | 19 +- .../scsi_periph/{block.c => block.cpp} | 10 +- .../scsi_periph/{device.c => device.cpp} | 19 +- .../{device_icons.c => device_icons.cpp} | 626 +++++++++--------- .../{error_handling.c => error_handling.cpp} | 0 .../scsi_periph/{handle.c => handle.cpp} | 0 .../generic/scsi_periph/{io.c => io.cpp} | 349 +++++----- .../{removable.c => removable.cpp} | 0 .../{scsi_periph.c => scsi_periph.cpp} | 56 +- .../generic/scsi_periph/scsi_periph_int.h | 27 +- .../generic/scsi_periph/{sync.c => sync.cpp} | 0 19 files changed, 814 insertions(+), 751 deletions(-) rename src/add-ons/kernel/generic/scsi_periph/{block.c => block.cpp} (90%) rename src/add-ons/kernel/generic/scsi_periph/{device.c => device.cpp} (76%) rename src/add-ons/kernel/generic/scsi_periph/{device_icons.c => device_icons.cpp} (67%) rename src/add-ons/kernel/generic/scsi_periph/{error_handling.c => error_handling.cpp} (100%) rename src/add-ons/kernel/generic/scsi_periph/{handle.c => handle.cpp} (100%) rename src/add-ons/kernel/generic/scsi_periph/{io.c => io.cpp} (68%) rename src/add-ons/kernel/generic/scsi_periph/{removable.c => removable.cpp} (100%) rename src/add-ons/kernel/generic/scsi_periph/{scsi_periph.c => scsi_periph.cpp} (79%) rename src/add-ons/kernel/generic/scsi_periph/{sync.c => sync.cpp} (100%) diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 57866e83b0..9860e44d98 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -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 uhci ohci ehci scsi_cd scsi_disk usb_disk diff --git a/headers/os/drivers/bus/SCSI.h b/headers/os/drivers/bus/SCSI.h index 4ac3022e07..fe088c2f82 100644 --- a/headers/os/drivers/bus/SCSI.h +++ b/headers/os/drivers/bus/SCSI.h @@ -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 diff --git a/headers/private/drivers/scsi_periph.h b/headers/private/drivers/scsi_periph.h index 12d4fb16e6..23dd56a812 100644 --- a/headers/private/drivers/scsi_periph.h +++ b/headers/private/drivers/scsi_periph.h @@ -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 */ - diff --git a/src/add-ons/kernel/bus_managers/ata/ata_request.c b/src/add-ons/kernel/bus_managers/ata/ata_request.c index 81007b64f6..8929534965 100644 --- a/src/add-ons/kernel/bus_managers/ata/ata_request.c +++ b/src/add-ons/kernel/bus_managers/ata/ata_request.c @@ -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; diff --git a/src/add-ons/kernel/bus_managers/scsi/ccb.c b/src/add-ons/kernel/bus_managers/scsi/ccb.c index 3694b53180..1b4f5eb86c 100644 --- a/src/add-ons/kernel/bus_managers/scsi/ccb.c +++ b/src/add-ons/kernel/bus_managers/scsi/ccb.c @@ -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); diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/Jamfile b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/Jamfile index cfe4a4e8e3..b612fa4935 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/Jamfile +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/Jamfile @@ -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 diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp index 4b58c0cb32..060f0cc39b 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp @@ -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 }; diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h index 5db059b94d..6be48694fc 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h @@ -12,27 +12,32 @@ #include #include - -#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 */ diff --git a/src/add-ons/kernel/generic/scsi_periph/Jamfile b/src/add-ons/kernel/generic/scsi_periph/Jamfile index d4702326c5..e4e71c2c95 100644 --- a/src/add-ons/kernel/generic/scsi_periph/Jamfile +++ b/src/add-ons/kernel/generic/scsi_periph/Jamfile @@ -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 ; diff --git a/src/add-ons/kernel/generic/scsi_periph/block.c b/src/add-ons/kernel/generic/scsi_periph/block.cpp similarity index 90% rename from src/add-ons/kernel/generic/scsi_periph/block.c rename to src/add-ons/kernel/generic/scsi_periph/block.cpp index 8b9e7645e4..8940fc960d 100644 --- a/src/add-ons/kernel/generic/scsi_periph/block.c +++ b/src/add-ons/kernel/generic/scsi_periph/block.cpp @@ -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 ); diff --git a/src/add-ons/kernel/generic/scsi_periph/device.c b/src/add-ons/kernel/generic/scsi_periph/device.cpp similarity index 76% rename from src/add-ons/kernel/generic/scsi_periph/device.c rename to src/add-ons/kernel/generic/scsi_periph/device.cpp index 743cda3d47..d620ee3023 100644 --- a/src/add-ons/kernel/generic/scsi_periph/device.c +++ b/src/add-ons/kernel/generic/scsi_periph/device.cpp @@ -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 diff --git a/src/add-ons/kernel/generic/scsi_periph/device_icons.c b/src/add-ons/kernel/generic/scsi_periph/device_icons.cpp similarity index 67% rename from src/add-ons/kernel/generic/scsi_periph/device_icons.c rename to src/add-ons/kernel/generic/scsi_periph/device_icons.cpp index 13493b2132..c94110e3c0 100644 --- a/src/add-ons/kernel/generic/scsi_periph/device_icons.c +++ b/src/add-ons/kernel/generic/scsi_periph/device_icons.cpp @@ -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) { diff --git a/src/add-ons/kernel/generic/scsi_periph/error_handling.c b/src/add-ons/kernel/generic/scsi_periph/error_handling.cpp similarity index 100% rename from src/add-ons/kernel/generic/scsi_periph/error_handling.c rename to src/add-ons/kernel/generic/scsi_periph/error_handling.cpp diff --git a/src/add-ons/kernel/generic/scsi_periph/handle.c b/src/add-ons/kernel/generic/scsi_periph/handle.cpp similarity index 100% rename from src/add-ons/kernel/generic/scsi_periph/handle.c rename to src/add-ons/kernel/generic/scsi_periph/handle.cpp diff --git a/src/add-ons/kernel/generic/scsi_periph/io.c b/src/add-ons/kernel/generic/scsi_periph/io.cpp similarity index 68% rename from src/add-ons/kernel/generic/scsi_periph/io.c rename to src/add-ons/kernel/generic/scsi_periph/io.cpp index c2bb9aaddf..049433d0eb 100644 --- a/src/add-ons/kernel/generic/scsi_periph/io.c +++ b/src/add-ons/kernel/generic/scsi_periph/io.cpp @@ -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 -// 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; +} + diff --git a/src/add-ons/kernel/generic/scsi_periph/removable.c b/src/add-ons/kernel/generic/scsi_periph/removable.cpp similarity index 100% rename from src/add-ons/kernel/generic/scsi_periph/removable.c rename to src/add-ons/kernel/generic/scsi_periph/removable.cpp diff --git a/src/add-ons/kernel/generic/scsi_periph/scsi_periph.c b/src/add-ons/kernel/generic/scsi_periph/scsi_periph.cpp similarity index 79% rename from src/add-ons/kernel/generic/scsi_periph/scsi_periph.c rename to src/add-ons/kernel/generic/scsi_periph/scsi_periph.cpp index b3fe4d384d..ea0350871d 100644 --- a/src/add-ons/kernel/generic/scsi_periph/scsi_periph.c +++ b/src/add-ons/kernel/generic/scsi_periph/scsi_periph.cpp @@ -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 -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 }; diff --git a/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h b/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h index 23a26c93ca..0057c3cef5 100644 --- a/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h +++ b/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h @@ -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 + #include #include #include -#include - +#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); diff --git a/src/add-ons/kernel/generic/scsi_periph/sync.c b/src/add-ons/kernel/generic/scsi_periph/sync.cpp similarity index 100% rename from src/add-ons/kernel/generic/scsi_periph/sync.c rename to src/add-ons/kernel/generic/scsi_periph/sync.cpp