Added Thomas Kurschel's scsi_periph module.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7766 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9d506c43b8
commit
b59852c818
14
src/add-ons/kernel/generic/scsi_periph/Jamfile
Normal file
14
src/add-ons/kernel/generic/scsi_periph/Jamfile
Normal file
@ -0,0 +1,14 @@
|
||||
SubDir OBOS_TOP src add-ons kernel generic scsi_periph ;
|
||||
|
||||
UsePrivateHeaders kernel ;
|
||||
|
||||
KernelAddon scsi_periph : kernel generic :
|
||||
block.c
|
||||
device_icons.c
|
||||
device.c
|
||||
error_handling.c
|
||||
handle.c
|
||||
io.c
|
||||
removable.c
|
||||
scsi_periph.c
|
||||
;
|
95
src/add-ons/kernel/generic/scsi_periph/block.c
Normal file
95
src/add-ons/kernel/generic/scsi_periph/block.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Handling of block device (currently, only a capacity check is provided)
|
||||
*/
|
||||
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
status_t
|
||||
periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
scsi_res_read_capacity capacity_res;
|
||||
scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)request->cdb;
|
||||
uint64 capacity;
|
||||
uint32 block_size;
|
||||
status_t res;
|
||||
|
||||
SHOW_FLOW(3, "%p, %p", device, request);
|
||||
|
||||
// driver doesn't support capacity callback - seems to be no block
|
||||
// device driver, so ignore
|
||||
if (device->callbacks->set_capacity == NULL)
|
||||
return B_OK;
|
||||
|
||||
request->flags = SCSI_DIR_IN;
|
||||
|
||||
request->data = (char *)&capacity_res;
|
||||
request->data_len = sizeof(capacity_res);
|
||||
request->cdb_len = sizeof(scsi_cmd_read_capacity);
|
||||
request->timeout = device->std_timeout;
|
||||
request->sort = -1;
|
||||
request->sg_list = NULL;
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->opcode = SCSI_OP_READ_CAPACITY;
|
||||
// we don't set PMI (partial medium indicator) as we want the whole capacity;
|
||||
// in this case, all other parameters must be zero
|
||||
|
||||
res = periph_safe_exec(device, request);
|
||||
|
||||
if (res == B_DEV_MEDIA_CHANGED) {
|
||||
// in this case, the error handler has already called check_capacity
|
||||
// recursively, so we ignore our (invalid) result
|
||||
SHOW_FLOW0( 3, "ignore result because medium change" );
|
||||
return B_DEV_MEDIA_CHANGED;
|
||||
}
|
||||
|
||||
ACQUIRE_BEN(&device->mutex);
|
||||
|
||||
if (res == B_OK && request->data_resid == 0) {
|
||||
capacity = (capacity_res.top_LBA << 24)
|
||||
| (capacity_res.high_LBA << 16)
|
||||
| (capacity_res.mid_LBA << 8)
|
||||
| capacity_res.low_LBA;
|
||||
|
||||
// the command returns the index of the _last_ block,
|
||||
// i.e. the size is one larger
|
||||
++capacity;
|
||||
|
||||
block_size = (capacity_res.top_block_size << 24)
|
||||
| (capacity_res.high_block_size << 16)
|
||||
| (capacity_res.mid_block_size << 8)
|
||||
| capacity_res.low_block_size;
|
||||
} else {
|
||||
capacity = 0;
|
||||
block_size = 0;
|
||||
}
|
||||
|
||||
SHOW_FLOW(3, "capacity = %Ld, block_size = %ld", capacity, block_size);
|
||||
|
||||
device->callbacks->set_capacity(device->periph_device,
|
||||
capacity, block_size);
|
||||
|
||||
/* device->byte2blk_shift = log2( device->block_size );
|
||||
if( device->byte2blk_shift < 0 ) {
|
||||
// this may be too restrictive...
|
||||
device->capacity = -1;
|
||||
return ERR_DEV_GENERAL;
|
||||
}*/
|
||||
|
||||
RELEASE_BEN(&device->mutex);
|
||||
|
||||
SHOW_FLOW(3, "done (%s)", strerror(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
103
src/add-ons/kernel/generic/scsi_periph/device.c
Normal file
103
src/add-ons/kernel/generic/scsi_periph/device.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Basic handling of device.
|
||||
*/
|
||||
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
|
||||
#include <blkman.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define SCSI_PERIPH_STD_TIMEOUT 10
|
||||
|
||||
|
||||
char *
|
||||
periph_compose_device_name(pnp_node_handle node, const char *prefix)
|
||||
{
|
||||
uint8 path_id, target_id, target_lun;
|
||||
|
||||
if (pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &path_id, true) != B_OK
|
||||
|| pnp->get_attr_uint8(node, SCSI_DEVICE_TARGET_ID_ITEM, &target_id, true) != B_OK
|
||||
|| pnp->get_attr_uint8(node, SCSI_DEVICE_TARGET_LUN_ITEM, &target_lun, true) != B_OK)
|
||||
return NULL;
|
||||
|
||||
{
|
||||
char name_buffer[100];
|
||||
sprintf(name_buffer, "%s/%d/%d/%d/raw", prefix, path_id, target_id, target_lun);
|
||||
|
||||
return strdup(name_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_register_device(periph_device_cookie periph_device, scsi_periph_callbacks *callbacks,
|
||||
scsi_device scsi_device, scsi_device_interface *scsi, pnp_node_handle node,
|
||||
bool removable, scsi_periph_device *driver)
|
||||
{
|
||||
scsi_periph_device_info *device;
|
||||
status_t res;
|
||||
|
||||
SHOW_FLOW0( 3, "" );
|
||||
|
||||
device = (scsi_periph_device_info *)malloc(sizeof(*device));
|
||||
if (device == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(device, 0, sizeof(*device));
|
||||
|
||||
if (INIT_BEN(&device->mutex, "SCSI_PERIPH") != B_OK) {
|
||||
res = B_NO_MEMORY;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
device->scsi_device = scsi_device;
|
||||
device->scsi = scsi;
|
||||
device->periph_device = periph_device;
|
||||
device->removal_requested = false;
|
||||
device->callbacks = callbacks;
|
||||
device->node = node;
|
||||
device->removable = removable;
|
||||
device->std_timeout = SCSI_PERIPH_STD_TIMEOUT;
|
||||
|
||||
// set some default options
|
||||
device->next_tag_action = 0;
|
||||
device->rw10_enabled = true;
|
||||
|
||||
// launch sync daemon
|
||||
res = register_kernel_daemon(periph_sync_queue_daemon, device, 60*10);
|
||||
if (res != B_OK)
|
||||
goto err2;
|
||||
|
||||
*driver = device;
|
||||
|
||||
SHOW_FLOW0(3, "done");
|
||||
|
||||
return B_OK;
|
||||
|
||||
err2:
|
||||
DELETE_BEN(&device->mutex);
|
||||
err1:
|
||||
free(device);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_unregister_device(scsi_periph_device_info *device)
|
||||
{
|
||||
unregister_kernel_daemon(periph_sync_queue_daemon, device);
|
||||
free(device);
|
||||
|
||||
return B_OK;
|
||||
}
|
393
src/add-ons/kernel/generic/scsi_periph/device_icons.c
Normal file
393
src/add-ons/kernel/generic/scsi_periph/device_icons.c
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Icons for various types of peripheral devices.
|
||||
*/
|
||||
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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,
|
||||
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, 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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
static struct {
|
||||
const char *large;
|
||||
const char *small;
|
||||
} icons[] = {
|
||||
{ icon_disk, icon_disk_mini },
|
||||
{ icon_removable, icon_removable_mini },
|
||||
{ icon_floppy, icon_floppy_mini },
|
||||
{ icon_cd, icon_cd_mini }
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
periph_get_icon(icon_type type, device_icon *data)
|
||||
{
|
||||
SHOW_FLOW( 3, "%d", type );
|
||||
|
||||
if (type < 0 || type >= sizeof(icons) / sizeof(icons[0]))
|
||||
return B_BAD_INDEX;
|
||||
|
||||
switch (data->icon_size) {
|
||||
case 32:
|
||||
memcpy(data->icon_data, icons[type].large, 32*32);
|
||||
return B_OK;
|
||||
|
||||
case 16:
|
||||
memcpy(data->icon_data, icons[type].small, 16*16);
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
9
src/add-ons/kernel/generic/scsi_periph/device_icons.h
Normal file
9
src/add-ons/kernel/generic/scsi_periph/device_icons.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef __DEVICE_ICONS_H__
|
||||
#define __DEVICE_ICONS_H__
|
||||
|
||||
const char icon_removable[32*32];
|
||||
const char icon_disc[32*32];
|
||||
const char icon_removable_mini[16*16];
|
||||
const char icon_disc_mini[16*16];
|
||||
|
||||
#endif
|
88
src/add-ons/kernel/generic/scsi_periph/dl_list.h
Normal file
88
src/add-ons/kernel/generic/scsi_periph/dl_list.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Macros for double linked lists
|
||||
*/
|
||||
|
||||
#ifndef _DL_LIST_H
|
||||
#define _DL_LIST_H
|
||||
|
||||
#define REMOVE_DL_LIST( item, head, prefix ) \
|
||||
do { \
|
||||
if( item->prefix##prev ) \
|
||||
item->prefix##prev->prefix##next = item->prefix##next; \
|
||||
else \
|
||||
head = item->prefix##next; \
|
||||
\
|
||||
if( item->prefix##next ) \
|
||||
item->prefix##next->prefix##prev = item->prefix##prev; \
|
||||
} while( 0 )
|
||||
|
||||
#define ADD_DL_LIST_HEAD( item, head, prefix ) \
|
||||
do { \
|
||||
item->prefix##next = head; \
|
||||
item->prefix##prev = NULL; \
|
||||
\
|
||||
if( (head) ) \
|
||||
(head)->prefix##prev = item; \
|
||||
\
|
||||
(head) = item; \
|
||||
} while( 0 )
|
||||
|
||||
#define REMOVE_CDL_LIST( item, head, prefix ) \
|
||||
do { \
|
||||
item->prefix##next->prefix##prev = item->prefix##prev; \
|
||||
item->prefix##prev->prefix##next = item->prefix##next; \
|
||||
\
|
||||
if( item == (head) ) { \
|
||||
if( item->prefix##next != item ) \
|
||||
(head) = item->prefix##next; \
|
||||
else \
|
||||
(head) = NULL; \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
#define ADD_CDL_LIST_TAIL( item, type, head, prefix ) \
|
||||
do { \
|
||||
type *old_head = head; \
|
||||
\
|
||||
if( old_head ) { \
|
||||
type *first, *last; \
|
||||
\
|
||||
first = old_head; \
|
||||
last = first->prefix##prev; \
|
||||
\
|
||||
item->prefix##next = first; \
|
||||
item->prefix##prev = last; \
|
||||
first->prefix##prev = item; \
|
||||
last->prefix##next = item; \
|
||||
} else { \
|
||||
head = item; \
|
||||
item->prefix##next = item->prefix##prev = item; \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
#define ADD_CDL_LIST_HEAD( item, type, head, prefix ) \
|
||||
do { \
|
||||
type *old_head = head; \
|
||||
\
|
||||
head = item; \
|
||||
if( old_head ) { \
|
||||
type *first, *last; \
|
||||
\
|
||||
first = old_head; \
|
||||
last = first->prefix##prev; \
|
||||
\
|
||||
item->prefix##next = first; \
|
||||
item->prefix##prev = last; \
|
||||
first->prefix##prev = item; \
|
||||
last->prefix##next = item; \
|
||||
} else { \
|
||||
item->prefix##next = item->prefix##prev = item; \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
#endif
|
326
src/add-ons/kernel/generic/scsi_periph/error_handling.c
Normal file
326
src/add-ons/kernel/generic/scsi_periph/error_handling.c
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Error handling
|
||||
*/
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
|
||||
#include <blkman.h>
|
||||
|
||||
|
||||
/** decode sense data and generate error code */
|
||||
|
||||
static
|
||||
err_res check_sense(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
scsi_sense *sense = (scsi_sense *)request->sense;
|
||||
|
||||
if ((request->subsys_status & SCSI_AUTOSNS_VALID) == 0) {
|
||||
SHOW_ERROR0(2, "No auto-sense (but there should be)");
|
||||
|
||||
// shouldn't happen (cam_status should be CAM_AUTOSENSE_FAIL
|
||||
// as we asked for autosense)
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
}
|
||||
|
||||
if (SCSI_MAX_SENSE_SIZE - request->sense_resid
|
||||
< (int)offsetof(scsi_sense, add_sense_length) + 1) {
|
||||
SHOW_ERROR(2, "sense too short (%d bytes)", SCSI_MAX_SENSE_SIZE - request->sense_resid);
|
||||
|
||||
// that's a bit too short
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
}
|
||||
|
||||
switch (sense->error_code) {
|
||||
case SCSIS_DEFERRED_ERROR:
|
||||
// we are doomed - some previous request turned out to have failed
|
||||
// we neither know which one nor can we resubmit it
|
||||
SHOW_ERROR0(2, "encountered DEFERRED ERROR - bye, bye");
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSIS_CURR_ERROR:
|
||||
// we start with very specific and finish very general error infos
|
||||
switch ((sense->asc << 8) | sense->ascq) {
|
||||
case SCSIS_ASC_AUDIO_PLAYING:
|
||||
SHOW_INFO0(2, "busy because playing audio");
|
||||
|
||||
// we need something like "busy"
|
||||
return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
|
||||
|
||||
case SCSIS_ASC_LUN_NEED_INIT:
|
||||
SHOW_INFO0(2, "LUN needs init");
|
||||
|
||||
// reported by some devices that are idle and spun down
|
||||
// sending START UNIT should awake them
|
||||
return MK_ERROR(err_act_start, B_NO_INIT);
|
||||
|
||||
case SCSIS_ASC_LUN_NEED_MANUAL_HELP:
|
||||
SHOW_ERROR0(2, "LUN needs manual help");
|
||||
|
||||
return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
|
||||
|
||||
case SCSIS_ASC_LUN_FORMATTING:
|
||||
SHOW_INFO0(2, "LUN is formatting");
|
||||
|
||||
// we could wait, but as formatting normally takes quite long,
|
||||
// we give up without any further retries
|
||||
return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
|
||||
|
||||
case SCSIS_ASC_MEDIUM_CHANGED:
|
||||
SHOW_FLOW0(3, "Medium changed");
|
||||
periph_media_changed(device, request);
|
||||
return MK_ERROR(err_act_fail, B_DEV_MEDIA_CHANGED);
|
||||
|
||||
case SCSIS_ASC_WRITE_ERR_AUTOREALLOC:
|
||||
SHOW_ERROR0(2, "Recovered write error - block got reallocated automatically");
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSIS_ASC_ID_RECOV:
|
||||
SHOW_ERROR0(2, "Recovered ID with ECC");
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSIS_ASC_REMOVAL_REQUESTED:
|
||||
SHOW_INFO0(2, "Removal requested");
|
||||
ACQUIRE_BEN(&device->mutex);
|
||||
device->removal_requested = true;
|
||||
RELEASE_BEN(&device->mutex);
|
||||
|
||||
return MK_ERROR(err_act_retry, B_DEV_MEDIA_CHANGE_REQUESTED);
|
||||
|
||||
case SCSIS_ASC_LUN_BECOMING_READY:
|
||||
SHOW_INFO0(2, "Becoming ready");
|
||||
// wait a bit - the device needs some time
|
||||
snooze(100000);
|
||||
return MK_ERROR(err_act_many_retries, B_DEV_NOT_READY);
|
||||
|
||||
case SCSIS_ASC_WAS_RESET:
|
||||
SHOW_INFO0(2, "Unit was reset");
|
||||
// TBD: need a better error code here
|
||||
// as some earlier command led to the reset, we are innocent
|
||||
return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
|
||||
}
|
||||
|
||||
switch (sense->asc) {
|
||||
case SCSIS_ASC_DATA_RECOV_NO_ERR_CORR >> 8:
|
||||
case SCSIS_ASC_DATA_RECOV_WITH_CORR >> 8:
|
||||
// these are the groups of recovered data with or without correction
|
||||
// we should print at least a warning here
|
||||
SHOW_ERROR(0, "Recovered data, asc=0x%2x, ascq=0x%2x",
|
||||
sense->asc, sense->ascq);
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSIS_ASC_WRITE_PROTECTED >> 8:
|
||||
SHOW_ERROR0( 2, "Write protected" );
|
||||
|
||||
// isn't there any proper "write protected" error code?
|
||||
return MK_ERROR(err_act_fail, B_READ_ONLY_DEVICE);
|
||||
|
||||
case SCSIS_ASC_NO_MEDIUM >> 8:
|
||||
SHOW_FLOW0(2, "No medium");
|
||||
return MK_ERROR(err_act_fail, B_DEV_NO_MEDIA);
|
||||
}
|
||||
|
||||
// we issue this info very late, so we don't clutter syslog with
|
||||
// messages about changed or missing media
|
||||
SHOW_ERROR(3, "0x%04x", (sense->asc << 8) | sense->ascq);
|
||||
|
||||
switch (sense->sense_key) {
|
||||
case SCSIS_KEY_NO_SENSE:
|
||||
SHOW_ERROR0(2, "No sense");
|
||||
|
||||
// we thought there was an error, huh?
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSIS_KEY_RECOVERED_ERROR:
|
||||
SHOW_ERROR0(2, "Recovered error");
|
||||
|
||||
// we should probably tell about that; perhaps tomorrow
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSIS_KEY_NOT_READY:
|
||||
return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
|
||||
|
||||
case SCSIS_KEY_MEDIUM_ERROR:
|
||||
SHOW_ERROR0(2, "Medium error");
|
||||
return MK_ERROR( err_act_retry, B_DEV_RECALIBRATE_ERROR);
|
||||
|
||||
case SCSIS_KEY_HARDWARE_ERROR:
|
||||
SHOW_ERROR0(2, "Hardware error");
|
||||
return MK_ERROR(err_act_retry, B_DEV_SEEK_ERROR);
|
||||
|
||||
case SCSIS_KEY_ILLEGAL_REQUEST:
|
||||
SHOW_ERROR0(2, "Illegal request");
|
||||
return MK_ERROR(err_act_invalid_req, B_ERROR);
|
||||
|
||||
case SCSIS_KEY_UNIT_ATTENTION:
|
||||
SHOW_ERROR0(2, "Unit attention");
|
||||
return MK_ERROR( err_act_retry, B_DEV_NOT_READY);
|
||||
|
||||
case SCSIS_KEY_DATA_PROTECT:
|
||||
SHOW_ERROR0(2, "Data protect");
|
||||
|
||||
// we could set "permission denied", but that's probably
|
||||
// irritating to the user
|
||||
return MK_ERROR(err_act_fail, B_NOT_ALLOWED);
|
||||
|
||||
case SCSIS_KEY_BLANK_CHECK:
|
||||
SHOW_ERROR0(2, "Is blank");
|
||||
|
||||
return MK_ERROR(err_act_fail, B_DEV_UNREADABLE);
|
||||
|
||||
case SCSIS_KEY_VENDOR_SPECIFIC:
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
|
||||
case SCSIS_KEY_COPY_ABORTED:
|
||||
// we don't use copy, so this is really wrong
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
|
||||
case SCSIS_KEY_ABORTED_COMMAND:
|
||||
// proper error code?
|
||||
return MK_ERROR(err_act_retry, B_ERROR);
|
||||
|
||||
case SCSIS_KEY_EQUAL:
|
||||
case SCSIS_KEY_MISCOMPARE:
|
||||
// we don't search, so this is really wrong
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
|
||||
case SCSIS_KEY_VOLUME_OVERFLOW:
|
||||
// not the best return code, but this error doesn't apply
|
||||
// to devices we currently support
|
||||
return MK_ERROR(err_act_fail, B_DEV_SEEK_ERROR);
|
||||
|
||||
case SCSIS_KEY_RESERVED:
|
||||
default:
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
}
|
||||
|
||||
default:
|
||||
// shouldn't happen - there are only 2 error codes defined
|
||||
SHOW_ERROR(2, "Invalid sense type (0x%x)", sense->error_code);
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** check scsi status, using sense if available */
|
||||
|
||||
static err_res
|
||||
check_scsi_status(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
SHOW_FLOW(3, "%d", request->device_status & SCSI_STATUS_MASK);
|
||||
|
||||
switch (request->device_status & SCSI_STATUS_MASK) {
|
||||
case SCSI_STATUS_GOOD:
|
||||
// shouldn't happen (cam_status should be CAM_REQ_CMP)
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case SCSI_STATUS_CHECK_CONDITION:
|
||||
return check_sense(device, request);
|
||||
|
||||
case SCSI_STATUS_QUEUE_FULL:
|
||||
// SIM should have automatically requeued request, fall through
|
||||
case SCSI_STATUS_BUSY:
|
||||
// take deep breath and try again
|
||||
snooze(1000000);
|
||||
return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
|
||||
|
||||
case SCSI_STATUS_COMMAND_TERMINATED:
|
||||
return MK_ERROR(err_act_retry, B_INTERRUPTED);
|
||||
|
||||
default:
|
||||
return MK_ERROR(err_act_retry, B_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** check result of request
|
||||
* 1. check SCSI subsystem problems
|
||||
* 2. if request hit device, check SCSI status
|
||||
* 3. if request got executed, check sense
|
||||
*/
|
||||
|
||||
err_res
|
||||
periph_check_error(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
SHOW_FLOW(4, "%d", request->subsys_status & SCSI_SUBSYS_STATUS_MASK);
|
||||
|
||||
switch (request->subsys_status & SCSI_SUBSYS_STATUS_MASK) {
|
||||
// everything is ok
|
||||
case SCSI_REQ_CMP:
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
// no device
|
||||
case SCSI_LUN_INVALID:
|
||||
case SCSI_TID_INVALID:
|
||||
case SCSI_PATH_INVALID:
|
||||
case SCSI_DEV_NOT_THERE:
|
||||
case SCSI_NO_HBA:
|
||||
SHOW_ERROR0(2, "No device");
|
||||
return MK_ERROR(err_act_fail, B_DEV_BAD_DRIVE_NUM);
|
||||
|
||||
// device temporary unavailable
|
||||
case SCSI_SEL_TIMEOUT:
|
||||
case SCSI_BUSY:
|
||||
case SCSI_SCSI_BUSY:
|
||||
case SCSI_HBA_ERR:
|
||||
case SCSI_MSG_REJECT_REC:
|
||||
case SCSI_NO_NEXUS:
|
||||
case SCSI_FUNC_NOTAVAIL:
|
||||
case SCSI_RESRC_UNAVAIL:
|
||||
// take a deep breath and hope device becomes ready
|
||||
snooze(1000000);
|
||||
return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
|
||||
|
||||
// data transmission went wrong
|
||||
case SCSI_DATA_RUN_ERR:
|
||||
case SCSI_UNCOR_PARITY:
|
||||
SHOW_ERROR0(2, "Data transmission failed");
|
||||
// retry immediately
|
||||
return MK_ERROR(err_act_retry, B_DEV_READ_ERROR);
|
||||
|
||||
// request broken
|
||||
case SCSI_REQ_INVALID:
|
||||
SHOW_ERROR0(2, "Invalid request");
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
|
||||
// request aborted
|
||||
case SCSI_REQ_ABORTED:
|
||||
case SCSI_SCSI_BUS_RESET:
|
||||
case SCSI_REQ_TERMIO:
|
||||
case SCSI_UNEXP_BUSFREE:
|
||||
case SCSI_BDR_SENT:
|
||||
case SCSI_CMD_TIMEOUT:
|
||||
case SCSI_IID_INVALID:
|
||||
case SCSI_UNACKED_EVENT:
|
||||
case SCSI_IDE:
|
||||
case SCSI_SEQUENCE_FAIL:
|
||||
// take a small breath and retry
|
||||
snooze(100000);
|
||||
return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
|
||||
|
||||
// device error
|
||||
case SCSI_REQ_CMP_ERR:
|
||||
return check_scsi_status(device, request);
|
||||
|
||||
// device error, but we don't know what happened
|
||||
case SCSI_AUTOSENSE_FAIL:
|
||||
SHOW_ERROR0(2, "Auto-sense failed, don't know what really happened");
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
|
||||
// should not happen, give up
|
||||
case SCSI_BUS_RESET_DENIED:
|
||||
case SCSI_PROVIDE_FAIL:
|
||||
case SCSI_UA_TERMIO:
|
||||
case SCSI_CDB_RECVD:
|
||||
case SCSI_LUN_ALLREADY_ENAB:
|
||||
// supposed to fall through
|
||||
default:
|
||||
return MK_ERROR(err_act_fail, B_ERROR);
|
||||
}
|
||||
}
|
71
src/add-ons/kernel/generic/scsi_periph/handle.c
Normal file
71
src/add-ons/kernel/generic/scsi_periph/handle.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Basic handling of file handles.
|
||||
*/
|
||||
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
|
||||
#include <dl_list.h>
|
||||
#include <malloc.h>
|
||||
|
||||
|
||||
status_t
|
||||
periph_handle_open(scsi_periph_device_info *device, periph_handle_cookie periph_handle,
|
||||
scsi_periph_handle_info **res_handle)
|
||||
{
|
||||
scsi_periph_handle_info *handle;
|
||||
|
||||
// SHOW_FLOW( 3, "device=%p", device );
|
||||
|
||||
handle = (scsi_periph_handle_info *)malloc(sizeof(*handle));
|
||||
if (handle == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
handle->periph_handle = periph_handle;
|
||||
handle->device = device;
|
||||
handle->pending_error = B_OK;
|
||||
|
||||
ACQUIRE_BEN(&device->mutex);
|
||||
ADD_DL_LIST_HEAD(handle, device->handles, );
|
||||
RELEASE_BEN(&device->mutex);
|
||||
|
||||
*res_handle = handle;
|
||||
|
||||
// SHOW_FLOW( 3, "handle=%p", handle );
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_handle_close(scsi_periph_handle_info *handle)
|
||||
{
|
||||
// SHOW_FLOW( 3, "handle=%p", handle );
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_handle_free(scsi_periph_handle_info *handle)
|
||||
{
|
||||
scsi_periph_device_info *device = handle->device;
|
||||
|
||||
// SHOW_FLOW( 3, "handle=%p, device=%p", handle, handle->device );
|
||||
|
||||
ACQUIRE_BEN(&device->mutex);
|
||||
REMOVE_DL_LIST(handle, device->handles, );
|
||||
RELEASE_BEN(&device->mutex);
|
||||
|
||||
free(handle);
|
||||
|
||||
// SHOW_FLOW0( 3, "done" );
|
||||
|
||||
return B_OK;
|
||||
}
|
326
src/add-ons/kernel/generic/scsi_periph/io.c
Normal file
326
src/add-ons/kernel/generic/scsi_periph/io.c
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Disk Driver
|
||||
|
||||
Everything doing the real input/output stuff.
|
||||
*/
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
#include <scsi.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// we don't want to inline this function - it's just not worth it
|
||||
static int periph_read_write(scsi_periph_handle_info *handle, const phys_vecs *vecs,
|
||||
off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
|
||||
int preferred_ccb_size, bool write);
|
||||
|
||||
|
||||
status_t
|
||||
periph_read(scsi_periph_handle_info *handle, const phys_vecs *vecs, off_t pos,
|
||||
size_t num_blocks, uint32 block_size, size_t *bytes_transferred, int preferred_ccb_size)
|
||||
{
|
||||
return periph_read_write(handle, vecs, pos, num_blocks, block_size,
|
||||
bytes_transferred, preferred_ccb_size, false);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_write(scsi_periph_handle_info *handle, const phys_vecs *vecs, off_t pos,
|
||||
size_t num_blocks, uint32 block_size, size_t *bytes_transferred, int preferred_ccb_size)
|
||||
{
|
||||
return periph_read_write(handle, vecs, pos, num_blocks, block_size,
|
||||
bytes_transferred, preferred_ccb_size, true);
|
||||
}
|
||||
|
||||
|
||||
/** universal read/write function */
|
||||
|
||||
static int
|
||||
periph_read_write(scsi_periph_handle_info *handle, const phys_vecs *vecs,
|
||||
off_t pos64, size_t num_blocks, uint32 block_size, size_t *bytes_transferred,
|
||||
int preferred_ccb_size, bool write)
|
||||
{
|
||||
scsi_periph_device_info *device = handle->device;
|
||||
scsi_ccb *request;
|
||||
err_res res;
|
||||
int retries = 0;
|
||||
int err;
|
||||
uint32 pos = pos64;
|
||||
|
||||
// don't test rw10_enabled restrictions - this flag may get changed
|
||||
request = device->scsi->alloc_ccb(device->scsi_device);
|
||||
|
||||
if (request == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
do {
|
||||
size_t num_bytes;
|
||||
bool is_rw10;
|
||||
|
||||
request->flags = write ? SCSI_DIR_OUT : SCSI_DIR_IN;
|
||||
|
||||
// make sure we avoid 10 byte commands if they aren't supported
|
||||
if( !device->rw10_enabled || preferred_ccb_size == 6) {
|
||||
// restricting transfer is OK - the block manager will
|
||||
// take care of transferring the rest
|
||||
if (num_blocks > 0x100)
|
||||
num_blocks = 0x100;
|
||||
|
||||
// no way to break the 21 bit address limit
|
||||
if (pos64 > 0x200000) {
|
||||
err = B_BAD_VALUE;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
// don't allow transfer cross the 24 bit address limit
|
||||
// (I'm not sure whether this is allowed, but this way we
|
||||
// are sure to not ask for trouble)
|
||||
num_blocks = min(num_blocks, 0x100000 - pos);
|
||||
}
|
||||
|
||||
num_bytes = num_blocks * block_size;
|
||||
|
||||
request->data = NULL;
|
||||
request->sg_list = vecs->vec;
|
||||
request->data_len = num_bytes;
|
||||
request->sg_cnt = 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_len = 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->RelAdr = 0;
|
||||
cmd->FUA = 0;
|
||||
cmd->DPO = 0;
|
||||
|
||||
cmd->top_LBA = (pos >> 24) & 0xff;
|
||||
cmd->high_LBA = (pos >> 16) & 0xff;
|
||||
cmd->mid_LBA = (pos >> 8) & 0xff;
|
||||
cmd->low_LBA = pos & 0xff;
|
||||
|
||||
cmd->high_length = (num_blocks >> 8) & 0xff;
|
||||
cmd->low_length = num_blocks & 0xff;
|
||||
|
||||
request->cdb_len = 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)
|
||||
{
|
||||
scsi_res_inquiry *device_inquiry = NULL;
|
||||
size_t inquiry_len;
|
||||
|
||||
if (pnp->get_attr_raw(device->node, SCSI_DEVICE_INQUIRY_ITEM,
|
||||
(void **)&device_inquiry, &inquiry_len, true) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
memcpy(inquiry, device_inquiry, min(inquiry_len, sizeof(scsi_inquiry)));
|
||||
free(device_inquiry);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
prevent_allow(scsi_periph_device_info *device, bool prevent)
|
||||
{
|
||||
scsi_cmd_prevent_allow cmd;
|
||||
|
||||
SHOW_FLOW0(0, "");
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.opcode = SCSI_OP_PREVENT_ALLOW;
|
||||
cmd.prevent = prevent;
|
||||
|
||||
return periph_simple_exec(device, (uint8 *)&cmd, sizeof(cmd), NULL, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/** !!!keep this in sync with scsi_raw driver!!! */
|
||||
|
||||
static status_t
|
||||
raw_command(scsi_periph_device_info *device, raw_device_command *cmd)
|
||||
{
|
||||
scsi_ccb *request;
|
||||
|
||||
SHOW_FLOW0(0, "");
|
||||
|
||||
request = device->scsi->alloc_ccb(device->scsi_device);
|
||||
if (request == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
request->flags = 0;
|
||||
|
||||
if (cmd->flags & B_RAW_DEVICE_DATA_IN)
|
||||
request->flags |= SCSI_DIR_IN;
|
||||
else
|
||||
request->flags |= SCSI_DIR_OUT;
|
||||
|
||||
request->data = cmd->data;
|
||||
request->sg_list = NULL;
|
||||
request->data_len = cmd->data_length;
|
||||
request->sort = -1;
|
||||
request->timeout = cmd->timeout;
|
||||
|
||||
memcpy(request->cdb, cmd->command, SCSI_MAX_CDB_SIZE);
|
||||
request->cdb_len = cmd->command_length;
|
||||
|
||||
device->scsi->sync_io(request);
|
||||
|
||||
// TBD: should we call standard error handler here, or may the
|
||||
// actions done there (like starting the unit) confuse the application?
|
||||
|
||||
cmd->cam_status = request->subsys_status;
|
||||
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, SCSI_MAX_SENSE_SIZE - request->sense_resid));
|
||||
}
|
||||
|
||||
if ((cmd->flags & B_RAW_DEVICE_REPORT_RESIDUAL) != 0) {
|
||||
// this is a bit strange, see Be's sample code where I pinched this from;
|
||||
// normally, residual means "number of unused bytes left"
|
||||
// but here, we have to return "number of used bytes", which is the opposite
|
||||
cmd->data_length = cmd->data_length - request->data_resid;
|
||||
cmd->sense_data_length = SCSI_MAX_SENSE_SIZE - request->sense_resid;
|
||||
}
|
||||
|
||||
device->scsi->free_ccb(request);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_ioctl(scsi_periph_handle_info *handle, int op, void *buf, size_t len)
|
||||
{
|
||||
switch (op) {
|
||||
case B_GET_MEDIA_STATUS: {
|
||||
status_t res;
|
||||
|
||||
if (!handle->device->removable)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
res = periph_get_media_status(handle);
|
||||
SHOW_FLOW(2, "%s", strerror(res));
|
||||
|
||||
*(status_t *)buf = res;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_SCSI_INQUIRY:
|
||||
return inquiry(handle->device, (scsi_inquiry *)buf);
|
||||
|
||||
case B_SCSI_PREVENT_ALLOW:
|
||||
return prevent_allow(handle->device, *(bool *)buf);
|
||||
|
||||
case B_RAW_DEVICE_COMMAND:
|
||||
return raw_command(handle->device, buf);
|
||||
|
||||
default:
|
||||
SHOW_ERROR(4, "Unknown ioctl: %x", op);
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** 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)
|
||||
{
|
||||
scsi_periph_device_info *device = (scsi_periph_device_info *)arg;
|
||||
|
||||
SHOW_FLOW0(3, "Setting ordered flag for next R/W access");
|
||||
atomic_or(&device->next_tag_action, SCSI_ORDERED_QTAG);
|
||||
}
|
232
src/add-ons/kernel/generic/scsi_periph/removable.c
Normal file
232
src/add-ons/kernel/generic/scsi_periph/removable.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Handling of removable media.
|
||||
*/
|
||||
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
|
||||
#include <blkman.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void
|
||||
periph_media_changed(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
uint32 backup_flags;
|
||||
uint8 backup_cdb[SCSI_MAX_CDB_SIZE];
|
||||
uchar backup_cdb_len;
|
||||
int64 backup_sort;
|
||||
bigtime_t backup_timeout;
|
||||
uchar *backup_data;
|
||||
const physical_entry *backup_sg_list;
|
||||
uint16 backup_sg_cnt;
|
||||
uint32 backup_data_len;
|
||||
|
||||
// if there is no hook, the driver doesn't handle removal devices
|
||||
if (!device->removable) {
|
||||
SHOW_ERROR0( 1, "Driver doesn't support medium changes, but there occured one!?" );
|
||||
return;
|
||||
}
|
||||
|
||||
// when medium has changed, tell all handles
|
||||
periph_media_changed_public(device);
|
||||
|
||||
// the peripheral driver may need a fresh ccb; sadly, we cannot allocate one
|
||||
// as this may lead to a deadlock if all ccb are in use already; thus, we
|
||||
// have to backup all relevant data of current ccb and use it instead of a
|
||||
// new one - not pretty but working (and performance is not an issue in this
|
||||
// path)
|
||||
backup_flags = request->flags;
|
||||
memcpy(backup_cdb, request->cdb, SCSI_MAX_CDB_SIZE);
|
||||
backup_cdb_len = request->cdb_len;
|
||||
backup_sort = request->sort;
|
||||
backup_timeout = request->timeout;
|
||||
backup_data = request->data;
|
||||
backup_sg_list = request->sg_list;
|
||||
backup_sg_cnt = request->sg_cnt;
|
||||
backup_data_len = request->data_len;
|
||||
|
||||
if (device->callbacks->media_changed != NULL)
|
||||
device->callbacks->media_changed(device->periph_device, request);
|
||||
|
||||
request->flags = backup_flags;
|
||||
memcpy(request->cdb, backup_cdb, SCSI_MAX_CDB_SIZE);
|
||||
request->cdb_len = backup_cdb_len;
|
||||
request->sort = backup_sort;
|
||||
request->timeout = backup_timeout;
|
||||
request->data = backup_data;
|
||||
request->sg_list = backup_sg_list;
|
||||
request->sg_cnt = backup_sg_cnt;
|
||||
request->data_len = backup_data_len;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
periph_media_changed_public(scsi_periph_device_info *device)
|
||||
{
|
||||
scsi_periph_handle_info *handle;
|
||||
|
||||
ACQUIRE_BEN(&device->mutex);
|
||||
|
||||
// when medium has changed, tell all handles
|
||||
// (this must be atomic for each handle!)
|
||||
for (handle = device->handles; handle; handle = handle->next)
|
||||
handle->pending_error = B_DEV_MEDIA_CHANGED;
|
||||
|
||||
RELEASE_BEN(&device->mutex);
|
||||
}
|
||||
|
||||
|
||||
/** send TUR */
|
||||
|
||||
static err_res
|
||||
send_tur(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
scsi_cmd_tur *cmd = (scsi_cmd_tur *)request->cdb;
|
||||
|
||||
request->flags = SCSI_DIR_NONE | SCSI_ORDERED_QTAG;
|
||||
|
||||
request->data = NULL;
|
||||
request->sg_list = NULL;
|
||||
request->data_len = 0;
|
||||
request->timeout = device->std_timeout;
|
||||
request->sort = -1;
|
||||
request->sg_list = NULL;
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->opcode = SCSI_OP_TUR;
|
||||
|
||||
request->cdb_len = sizeof(*cmd);
|
||||
|
||||
device->scsi->sync_io(request);
|
||||
|
||||
return periph_check_error(device, request);
|
||||
}
|
||||
|
||||
|
||||
/** wait until device is ready */
|
||||
|
||||
static err_res
|
||||
wait_for_ready(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
int retries = 0;
|
||||
|
||||
while (true) {
|
||||
err_res res;
|
||||
|
||||
// we send TURs until the device is OK or all hope is lost
|
||||
res = send_tur(device, request);
|
||||
|
||||
switch (res.action) {
|
||||
case err_act_ok:
|
||||
return MK_ERROR(err_act_ok, B_OK);
|
||||
|
||||
case err_act_retry:
|
||||
if (++retries >= 3)
|
||||
return MK_ERROR(err_act_fail, res.error_code);
|
||||
break;
|
||||
|
||||
case err_act_many_retries:
|
||||
if (++retries >= 30)
|
||||
return MK_ERROR(err_act_fail, res.error_code);
|
||||
break;
|
||||
|
||||
default:
|
||||
SHOW_FLOW( 3, "action: %x, error: %x", (int)res.action, (int)res.error_code);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_get_media_status(scsi_periph_handle_info *handle)
|
||||
{
|
||||
scsi_periph_device_info *device = handle->device;
|
||||
scsi_ccb *request;
|
||||
err_res res;
|
||||
status_t err;
|
||||
|
||||
ACQUIRE_BEN(&device->mutex);
|
||||
|
||||
// removal requests are returned to exactly one handle
|
||||
// (no real problem, as noone check medias status "by mistake")
|
||||
if (device->removal_requested) {
|
||||
device->removal_requested = false;
|
||||
err = B_DEV_MEDIA_CHANGE_REQUESTED;
|
||||
goto err;
|
||||
}
|
||||
|
||||
// if there is a pending error (read: media has changed), return once per handle
|
||||
err = handle->pending_error;
|
||||
if (err != B_OK) {
|
||||
handle->pending_error = B_OK;
|
||||
goto err;
|
||||
}
|
||||
|
||||
SHOW_FLOW0( 3, "" );
|
||||
|
||||
RELEASE_BEN(&device->mutex);
|
||||
|
||||
// finally, ask the device itself
|
||||
|
||||
request = device->scsi->alloc_ccb(device->scsi_device);
|
||||
if (request == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
res = wait_for_ready(device, request);
|
||||
|
||||
device->scsi->free_ccb(request);
|
||||
|
||||
SHOW_FLOW(3, "error_code: %x", (int)res.error_code);
|
||||
|
||||
return res.error_code;
|
||||
|
||||
err:
|
||||
RELEASE_BEN(&device->mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/** send START/STOP command to device
|
||||
* start - true for start, false for stop
|
||||
* with_LoEj - if true, then lock drive on start and eject on stop
|
||||
*/
|
||||
|
||||
err_res
|
||||
periph_send_start_stop(scsi_periph_device_info *device, scsi_ccb *request,
|
||||
bool start, bool with_LoEj)
|
||||
{
|
||||
scsi_cmd_ssu *cmd = (scsi_cmd_ssu *)request->cdb;
|
||||
|
||||
// this must be ordered, so all previous commands are really finished
|
||||
request->flags = SCSI_DIR_NONE | SCSI_ORDERED_QTAG;
|
||||
|
||||
request->data = NULL;
|
||||
request->sg_list = NULL;
|
||||
request->data_len = 0;
|
||||
request->timeout = device->std_timeout;
|
||||
request->sort = -1;
|
||||
request->sg_list = NULL;
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->opcode = SCSI_OP_START_STOP;
|
||||
// we don't want to poll; we give a long timeout instead
|
||||
// (well - the default timeout _is_ large)
|
||||
cmd->immed = 0;
|
||||
cmd->start = start;
|
||||
cmd->LoEj = with_LoEj;
|
||||
|
||||
request->cdb_len = sizeof(*cmd);
|
||||
|
||||
device->scsi->sync_io(request);
|
||||
|
||||
return periph_check_error(device, request);
|
||||
}
|
174
src/add-ons/kernel/generic/scsi_periph/scsi_periph.c
Normal file
174
src/add-ons/kernel/generic/scsi_periph/scsi_periph.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Part of Open SCSI Peripheral Driver
|
||||
|
||||
Main file.
|
||||
*/
|
||||
|
||||
#include "scsi_periph_int.h"
|
||||
|
||||
#include <module.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
device_manager_info *pnp;
|
||||
|
||||
|
||||
status_t
|
||||
periph_simple_exec(scsi_periph_device_info *device, void *cdb, uchar cdb_len,
|
||||
void *data, size_t data_len, int ccb_flags)
|
||||
{
|
||||
scsi_ccb *ccb;
|
||||
status_t res;
|
||||
|
||||
SHOW_FLOW0( 0, "" );
|
||||
|
||||
ccb = device->scsi->alloc_ccb(device->scsi_device);
|
||||
if (ccb == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
ccb->flags = ccb_flags;
|
||||
|
||||
memcpy(ccb->cdb, cdb, cdb_len);
|
||||
ccb->cdb_len = cdb_len;
|
||||
|
||||
ccb->sort = -1;
|
||||
ccb->timeout = device->std_timeout;
|
||||
|
||||
ccb->data = data;
|
||||
ccb->sg_list = NULL;
|
||||
ccb->data_len = data_len;
|
||||
|
||||
res = periph_safe_exec(device, ccb);
|
||||
|
||||
device->scsi->free_ccb(ccb);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request)
|
||||
{
|
||||
err_res res;
|
||||
int retries = 0;
|
||||
|
||||
do {
|
||||
device->scsi->sync_io(request);
|
||||
|
||||
// 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"
|
||||
// (we cannot allocate a new cdb as there may be no more cdb and
|
||||
// waiting for one to become empty may lead to deadlock if everyone
|
||||
// does that)
|
||||
uint32 backup_flags;
|
||||
uint8 backup_cdb[SCSI_MAX_CDB_SIZE];
|
||||
uchar backup_cdb_len;
|
||||
int64 backup_sort;
|
||||
bigtime_t backup_timeout;
|
||||
uchar *backup_data;
|
||||
const physical_entry *backup_sg_list;
|
||||
uint16 backup_sg_cnt;
|
||||
uint32 backup_data_len;
|
||||
|
||||
backup_flags = request->flags;
|
||||
memcpy(backup_cdb, request->cdb, SCSI_MAX_CDB_SIZE);
|
||||
backup_cdb_len = request->cdb_len;
|
||||
backup_sort = request->sort;
|
||||
backup_timeout = request->timeout;
|
||||
backup_data = request->data;
|
||||
backup_sg_list = request->sg_list;
|
||||
backup_sg_cnt = request->sg_cnt;
|
||||
backup_data_len = request->data_len;
|
||||
|
||||
SHOW_INFO0( 2, "Sending start to init LUN" );
|
||||
|
||||
res = periph_send_start_stop(device, request, 1, device->removable);
|
||||
|
||||
request->flags = backup_flags;
|
||||
memcpy(request->cdb, backup_cdb, SCSI_MAX_CDB_SIZE);
|
||||
request->cdb_len = backup_cdb_len;
|
||||
request->sort = backup_sort;
|
||||
request->timeout = backup_timeout;
|
||||
request->data = backup_data;
|
||||
request->sg_list = backup_sg_list;
|
||||
request->sg_cnt = backup_sg_cnt;
|
||||
request->data_len = backup_data_len;
|
||||
|
||||
if (res.action == err_act_ok)
|
||||
res.action = err_act_retry;
|
||||
}
|
||||
} while ((res.action == err_act_retry && retries++ < 3)
|
||||
|| (res.action == err_act_many_retries && retries++ < 30));
|
||||
|
||||
return res.error_code;
|
||||
}
|
||||
|
||||
|
||||
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[] = {
|
||||
{ DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
scsi_periph_interface scsi_periph_module = {
|
||||
{
|
||||
SCSI_PERIPH_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
|
||||
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_ioctl,
|
||||
periph_check_capacity,
|
||||
|
||||
periph_media_changed_public,
|
||||
periph_check_error,
|
||||
periph_send_start_stop,
|
||||
periph_get_media_status,
|
||||
|
||||
periph_compose_device_name,
|
||||
periph_get_icon
|
||||
};
|
||||
|
||||
|
||||
#if !_BUILDING_kernel && !BOOT
|
||||
_EXPORT
|
||||
scsi_periph_interface *modules[] = {
|
||||
&scsi_periph_module,
|
||||
NULL
|
||||
};
|
||||
#endif
|
110
src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h
Normal file
110
src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
** Copyright 2002, Thomas Kurschel. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
#ifndef __SCSI_PERIPH_INT_H__
|
||||
#define __SCSI_PERIPH_INT_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <bus/scsi/scsi_periph.h>
|
||||
#include <blkman.h>
|
||||
#include <device_manager.h>
|
||||
#include "wrapper.h"
|
||||
|
||||
|
||||
typedef struct scsi_periph_device_info {
|
||||
struct scsi_periph_handle_info *handles;
|
||||
|
||||
scsi_device scsi_device;
|
||||
scsi_device_interface *scsi;
|
||||
periph_device_cookie periph_device;
|
||||
pnp_node_handle node;
|
||||
|
||||
bool removal_requested;
|
||||
|
||||
bool removable; // true, if device is removable
|
||||
|
||||
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
|
||||
|
||||
benaphore mutex;
|
||||
int std_timeout;
|
||||
|
||||
scsi_periph_callbacks *callbacks;
|
||||
} scsi_periph_device_info;
|
||||
|
||||
typedef struct scsi_periph_handle_info {
|
||||
scsi_periph_device_info *device;
|
||||
struct scsi_periph_handle_info *next, *prev;
|
||||
|
||||
int pending_error; // error to be reported on all accesses
|
||||
// (used to block access after medium change until
|
||||
// B_GET_MEDIA_STATUS is called)
|
||||
periph_handle_cookie periph_handle;
|
||||
} scsi_periph_handle_info;
|
||||
|
||||
extern device_manager_info *pnp;
|
||||
|
||||
|
||||
// removable.c
|
||||
|
||||
void periph_media_changed(scsi_periph_device_info *device, scsi_ccb *ccb);
|
||||
void periph_media_changed_public(scsi_periph_device_info *device);
|
||||
status_t periph_get_media_status(scsi_periph_handle_info *handle);
|
||||
err_res periph_send_start_stop(scsi_periph_device_info *device, scsi_ccb *request,
|
||||
bool start, bool with_LoEj);
|
||||
|
||||
|
||||
// error_handling.c
|
||||
|
||||
err_res periph_check_error(scsi_periph_device_info *device, scsi_ccb *request);
|
||||
|
||||
|
||||
// handle.c
|
||||
|
||||
status_t periph_handle_open(scsi_periph_device_info *device, periph_handle_cookie periph_handle,
|
||||
scsi_periph_handle_info **res_handle);
|
||||
status_t periph_handle_close(scsi_periph_handle_info *handle);
|
||||
status_t periph_handle_free(scsi_periph_handle_info *handle);
|
||||
|
||||
|
||||
// block.c
|
||||
|
||||
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,
|
||||
pnp_node_handle node, bool removable, scsi_periph_device *driver);
|
||||
status_t periph_unregister_device(scsi_periph_device_info *driver);
|
||||
char *periph_compose_device_name(pnp_node_handle 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_ioctl(scsi_periph_handle_info *handle, int op,
|
||||
void *buf, size_t len);
|
||||
void periph_sync_queue_daemon(void *arg, int iteration);
|
||||
|
||||
|
||||
// scsi_periph.c
|
||||
|
||||
status_t periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request);
|
||||
status_t periph_simple_exec(scsi_periph_device_info *device, void *cdb,
|
||||
uchar cdb_len, void *data, size_t data_len, int ccb_flags);
|
||||
|
||||
|
||||
// device_icons.c
|
||||
|
||||
status_t periph_get_icon(icon_type type, device_icon *data);
|
||||
|
||||
#endif
|
89
src/add-ons/kernel/generic/scsi_periph/wrapper.h
Normal file
89
src/add-ons/kernel/generic/scsi_periph/wrapper.h
Normal file
@ -0,0 +1,89 @@
|
||||
#ifndef _WRAPPER_H
|
||||
#define _WRAPPER_H
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <lock.h>
|
||||
|
||||
|
||||
// benaphores
|
||||
|
||||
#define INIT_BEN(x, prefix) benaphore_init(x, prefix)
|
||||
#define DELETE_BEN(x) benaphore_destroy(x)
|
||||
#define ACQUIRE_BEN(x) benaphore_lock(x)
|
||||
#define RELEASE_BEN(x) benaphore_unlock(x)
|
||||
|
||||
// debug output
|
||||
|
||||
#ifdef DEBUG_WAIT_ON_MSG
|
||||
# define DEBUG_WAIT snooze( DEBUG_WAIT_ON_MSG );
|
||||
#else
|
||||
# define DEBUG_WAIT
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_WAIT_ON_ERROR
|
||||
# define DEBUG_WAIT_ERROR snooze( DEBUG_WAIT_ON_ERROR );
|
||||
#else
|
||||
# define DEBUG_WAIT_ERROR
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_MAX_LEVEL_FLOW
|
||||
# define DEBUG_MAX_LEVEL_FLOW 4
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_MAX_LEVEL_INFO
|
||||
# define DEBUG_MAX_LEVEL_INFO 4
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_MAX_LEVEL_ERROR
|
||||
# define DEBUG_MAX_LEVEL_ERROR 4
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_MSG_PREFIX
|
||||
# define DEBUG_MSG_PREFIX ""
|
||||
#endif
|
||||
|
||||
#ifndef debug_level_flow
|
||||
# define debug_level_flow 3
|
||||
#endif
|
||||
|
||||
#ifndef debug_level_info
|
||||
# define debug_level_info 2
|
||||
#endif
|
||||
|
||||
#ifndef debug_level_error
|
||||
# define debug_level_error 1
|
||||
#endif
|
||||
|
||||
#define FUNC_NAME DEBUG_MSG_PREFIX __FUNCTION__ ": "
|
||||
|
||||
#define SHOW_FLOW(seriousness, format, param...) \
|
||||
do { if( seriousness <= debug_level_flow && seriousness <= DEBUG_MAX_LEVEL_FLOW ) { \
|
||||
dprintf( "%s"##format"\n", FUNC_NAME, param ); DEBUG_WAIT \
|
||||
}} while( 0 )
|
||||
|
||||
#define SHOW_FLOW0(seriousness, format) \
|
||||
do { if( seriousness <= debug_level_flow && seriousness <= DEBUG_MAX_LEVEL_FLOW ) { \
|
||||
dprintf( "%s"##format"\n", FUNC_NAME); DEBUG_WAIT \
|
||||
}} while( 0 )
|
||||
|
||||
#define SHOW_INFO(seriousness, format, param...) \
|
||||
do { if( seriousness <= debug_level_info && seriousness <= DEBUG_MAX_LEVEL_INFO ) { \
|
||||
dprintf( "%s"##format"\n", FUNC_NAME, param ); DEBUG_WAIT \
|
||||
}} while( 0 )
|
||||
|
||||
#define SHOW_INFO0(seriousness, format) \
|
||||
do { if( seriousness <= debug_level_info && seriousness <= DEBUG_MAX_LEVEL_INFO ) { \
|
||||
dprintf( "%s"##format"\n", FUNC_NAME); DEBUG_WAIT \
|
||||
}} while( 0 )
|
||||
|
||||
#define SHOW_ERROR(seriousness, format, param...) \
|
||||
do { if( seriousness <= debug_level_error && seriousness <= DEBUG_MAX_LEVEL_ERROR ) { \
|
||||
dprintf( "%s"##format"\n", FUNC_NAME, param ); DEBUG_WAIT_ERROR \
|
||||
}} while( 0 )
|
||||
|
||||
#define SHOW_ERROR0(seriousness, format) \
|
||||
do { if( seriousness <= debug_level_error && seriousness <= DEBUG_MAX_LEVEL_ERROR ) { \
|
||||
dprintf( "%s"##format"\n", FUNC_NAME); DEBUG_WAIT_ERROR \
|
||||
}} while( 0 )
|
||||
|
||||
#endif /* _BENAPHORE_H */
|
Loading…
Reference in New Issue
Block a user