Work In Progress (do not try yet!) driver for usb floppy drive.

This is loosely based on usb_disk, but uses a different protocol for sending the commands.
Refactoring is unfinished, so don't look at the style too muh, it will e fixed and cleaned up later.

Basic communication with the drive works (sending commands). Command themselves still mostly untested.
Command Blocks sent to the drive are most likely wrong and may erase your floppies or do any other weird things!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38379 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adrien Destugues
2010-08-26 20:28:54 +00:00
parent db4015a5f8
commit bbdb55154d
5 changed files with 1495 additions and 0 deletions
@@ -1,3 +1,4 @@
SubDir HAIKU_TOP src add-ons kernel drivers disk usb ;
SubInclude HAIKU_TOP src add-ons kernel drivers disk usb usb_disk ;
SubInclude HAIKU_TOP src add-ons kernel drivers disk usb usb_floppy ;
@@ -0,0 +1,8 @@
SubDir HAIKU_TOP src add-ons kernel drivers disk usb usb_floppy ;
SubDirSysHdrs $(HAIKU_TOP) src add-ons kernel bus_managers usb ;
UsePrivateHeaders kernel ;
KernelAddon usb_floppy :
usb_disk.cpp
;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
/*
* Copyright 2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#ifndef _USB_DISK_H_
#define _USB_DISK_H_
#include <lock.h>
#include <USB3.h>
#define REQUEST_MASS_STORAGE_RESET 0xff
#define REQUEST_GET_MAX_LUN 0xfe
#define MAX_LOGICAL_UNIT_NUMBER 15
#define ATAPI_COMMAND_LENGTH 12
#define CBW_SIGNATURE 0x43425355
#define CBW_DATA_OUTPUT 0x00
#define CBW_DATA_INPUT 0x80
#define CSW_SIGNATURE 0x53425355
#define CSW_STATUS_COMMAND_PASSED 0x00
#define CSW_STATUS_COMMAND_FAILED 0x01
#define CSW_STATUS_PHASE_ERROR 0x02
#define SYNC_SUPPORT_RELOAD 5
typedef struct device_lun_s device_lun;
// holds common information about an attached device (pointed to by luns)
typedef struct disk_device_s {
usb_device device;
uint32 device_number;
bool removed;
uint32 open_count;
mutex lock;
void * link;
// device state
usb_pipe bulk_in;
usb_pipe bulk_out;
usb_pipe interrupt;
uint8 interface;
uint32 current_tag;
uint8 sync_support;
bool tur_supported;
bool is_atapi;
// used to store callback information
sem_id notify;
status_t status;
size_t actual_length;
// logical units of this device
uint8 lun_count;
device_lun **luns;
} disk_device;
// represents a logical unit on the pointed to device - this gets published
struct device_lun_s {
disk_device *device;
char name[32];
uint8 logical_unit_number;
bool should_sync;
// device information through read capacity/inquiry
bool media_present;
bool media_changed;
uint32 block_count;
uint32 block_size;
uint8 device_type;
bool removable;
bool write_protected;
};
typedef struct command_block_wrapper_s {
uint32 signature;
uint32 tag;
uint32 data_transfer_length;
uint8 flags;
uint8 lun;
uint8 command_block_length;
uint8 command_block[16];
} _PACKED command_block_wrapper;
typedef struct command_status_wrapper_s {
uint8 status;
uint8 misc;
} _PACKED command_status_wrapper;
#endif // _USB_DISK_H_
@@ -0,0 +1,91 @@
/*
* Copyright 2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#ifndef _USB_DISK_SCSI_H_
#define _USB_DISK_SCSI_H_
typedef enum {
SCSI_TEST_UNIT_READY_6 = 0x00,
SCSI_REQUEST_SENSE_6 = 0x03,
SCSI_INQUIRY_6 = 0x12,
SCSI_MODE_SENSE_6 = 0x1a,
SCSI_START_STOP_UNIT_6 = 0x1b,
SCSI_READ_CAPACITY_10 = 0x25,
SCSI_READ_10 = 0x28,
SCSI_WRITE_10 = 0x2a,
SCSI_SYNCHRONIZE_CACHE_10 = 0x35,
} scsi_operations;
// parameters = returned data
typedef struct scsi_request_sense_6_parameter_s {
uint8 error_code : 7;
uint8 valid : 1;
uint8 segment_number;
uint8 sense_key : 4;
uint8 unused_1 : 4;
uint32 information;
uint8 additional_sense_length;
uint32 command_specific_information;
uint8 additional_sense_code;
uint8 additional_sense_code_qualifier;
uint8 field_replacable_unit_code;
uint8 sense_key_specific[3];
} _PACKED scsi_request_sense_6_parameter;
typedef struct scsi_inquiry_6_parameter_s {
uint8 peripherial_device_type : 5;
uint8 peripherial_qualifier : 3;
uint8 reserved_1 : 7;
uint8 removable_medium : 1;
uint8 version;
uint8 response_data_format : 4;
uint8 unused_1 : 4;
uint8 additional_length;
uint8 unused_2[3];
char vendor_identification[8];
char product_identification[16];
char product_revision_level[4];
} _PACKED scsi_inquiry_6_parameter;
typedef struct scsi_mode_sense_6_parameter_s {
uint8 data_length;
uint8 medium_type;
uint8 device_specific;
uint8 block_descriptor_length;
uint8 densitiy;
uint8 num_blocks[3];
uint8 reserved;
uint8 block_length[3];
} _PACKED scsi_mode_sense_6_parameter;
typedef struct scsi_read_capacity_10_parameter_s {
uint32 last_logical_block_address;
uint32 logical_block_length;
} _PACKED scsi_read_capacity_10_parameter;
// request sense keys/codes
typedef enum {
SCSI_SENSE_KEY_NO_SENSE = 0x00,
SCSI_SENSE_KEY_RECOVERED_ERROR = 0x01,
SCSI_SENSE_KEY_NOT_READY = 0x02,
SCSI_SENSE_KEY_MEDIUM_ERROR = 0x03,
SCSI_SENSE_KEY_HARDWARE_ERROR = 0x04,
SCSI_SENSE_KEY_ILLEGAL_REQUEST = 0x05,
SCSI_SENSE_KEY_UNIT_ATTENTION = 0x06,
SCSI_SENSE_KEY_DATA_PROTECT = 0x07,
SCSI_SENSE_KEY_ABORTED_COMMAND = 0x0b,
} scsi_sense_key;
// request sense additional sense codes
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3a
// mode sense page code/parameter
#define SCSI_MODE_PAGE_DEVICE_CONFIGURATION 0x10
#define SCSI_DEVICE_SPECIFIC_WRITE_PROTECT 0x80
#endif // _USB_DISK_SCSI_H_