diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 2923b97825..10aa36f0e1 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -130,6 +130,8 @@ AddFilesToHaikuImage beos system add-ons kernel bus_managers : $(BEOS_ADD_ONS_BUS_MANAGERS) ; AddFilesToHaikuImage beos system add-ons kernel busses ide : generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata ; +AddFilesToHaikuImage beos system add-ons kernel busses scsi + : ahci ; AddFilesToHaikuImage beos system add-ons kernel busses usb : uhci ohci ehci ; AddFilesToHaikuImage beos system add-ons kernel console : vga_text ; @@ -153,7 +155,6 @@ AddDriversToHaikuImage : console dprintf $(X86_ONLY)keyboard null AddDriversToHaikuImage audio hmulti : $(BEOS_ADD_ONS_DRIVERS_AUDIO) ; AddDriversToHaikuImage midi : $(BEOS_ADD_ONS_DRIVERS_MIDI) ; AddDriversToHaikuImage bus : usb_raw ; -AddDriversToHaikuImage disk : ahci ; AddDriversToHaikuImage disk scsi : scsi_cd scsi_dsk ; AddDriversToHaikuImage disk virtual : nbd ; AddDriversToHaikuImage dvb : cx23882 ; diff --git a/src/add-ons/kernel/busses/scsi/Jamfile b/src/add-ons/kernel/busses/scsi/Jamfile index f14ccdb90f..8d80bbc3bb 100644 --- a/src/add-ons/kernel/busses/scsi/Jamfile +++ b/src/add-ons/kernel/busses/scsi/Jamfile @@ -1,5 +1,6 @@ SubDir HAIKU_TOP src add-ons kernel busses scsi ; +SubInclude HAIKU_TOP src add-ons kernel busses scsi ahci ; SubInclude HAIKU_TOP src add-ons kernel busses scsi 53c8xx ; SubInclude HAIKU_TOP src add-ons kernel busses scsi buslogic ; SubInclude HAIKU_TOP src add-ons kernel busses scsi usb ; diff --git a/src/add-ons/kernel/busses/scsi/ahci/Jamfile b/src/add-ons/kernel/busses/scsi/ahci/Jamfile new file mode 100644 index 0000000000..998df85ecf --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/ahci/Jamfile @@ -0,0 +1,6 @@ +SubDir HAIKU_TOP src add-ons kernel busses scsi ahci ; + +KernelAddon ahci : + ahci.c + ahci_sim.c + ; diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci.c b/src/add-ons/kernel/busses/scsi/ahci/ahci.c new file mode 100644 index 0000000000..1ad616d9e8 --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci.c @@ -0,0 +1,248 @@ +/* + * Copyright 2007, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include "ahci_defs.h" + +#include +#include + +#include + + +#define TRACE(a...) dprintf("\33[35mahci:\33[30m " a) +#define FLOW(a...) dprintf("ahci: " a) + +#define AHCI_ID_GENERATOR "ahci/id" +#define AHCI_ID_ITEM "ahci/id" + +static device_manager_info *sDeviceManager; +static pci_device *sPCIDevice; + + +static status_t +register_sim(device_node_handle parent) +{ + int32 id = sDeviceManager->create_id(AHCI_ID_GENERATOR); + if (id < 0) + return id; + + { + device_attr attrs[] = { + { B_DRIVER_MODULE, B_STRING_TYPE, + { string: AHCI_SIM_MODULE_NAME }}, + { B_DRIVER_FIXED_CHILD, B_STRING_TYPE, + { string: SCSI_FOR_SIM_MODULE_NAME }}, + + { SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, + { string: AHCI_DEVICE_MODULE_NAME }}, + { B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: 255 }}, + { AHCI_ID_ITEM, B_UINT32_TYPE, { ui32: id }}, + { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, + { string: AHCI_ID_GENERATOR }}, + { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: id }}, + + { NULL } + }; + + device_node_handle node; + status_t status = sDeviceManager->register_device(parent, attrs, NULL, + &node); + if (status < B_OK) + sDeviceManager->free_id(AHCI_ID_GENERATOR, id); + + return status; + } +} + + +// #pragma mark - + + +static float +ahci_supports_device(device_node_handle parent, bool *_noConnection) +{ + uint8 baseClass, subClass, classAPI; + uint16 vendorID; + uint16 deviceID; + char *bus; + + TRACE("ahci_supports_device\n"); + + // make sure parent is an PCI IDE mass storage host adapter device node + if (sDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, + false) != B_OK + || sDeviceManager->get_attr_uint8(parent, + PCI_DEVICE_BASE_CLASS_ID_ITEM, &baseClass, false) != B_OK + || sDeviceManager->get_attr_uint8(parent, + PCI_DEVICE_SUB_CLASS_ID_ITEM, &subClass, false) != B_OK + || sDeviceManager->get_attr_uint8(parent, + PCI_DEVICE_API_ID_ITEM, &classAPI, false) != B_OK + || sDeviceManager->get_attr_uint16(parent, + PCI_DEVICE_VENDOR_ID_ITEM, &vendorID, false) != B_OK + || sDeviceManager->get_attr_uint16(parent, + PCI_DEVICE_DEVICE_ID_ITEM, &deviceID, false) != B_OK) + return B_ERROR; + +#if 1 + if (strcmp(bus, "pci") || baseClass != PCI_mass_storage + || subClass != PCI_sata || classAPI != PCI_sata_ahci) { + free(bus); + return 0.0f; + } +#else + if (strcmp(bus, "pci") || baseClass != PCI_mass_storage + || subClass != PCI_ide) { + free(bus); + return 0.0; + } +#endif + + TRACE("controller found! vendor 0x%04x, device 0x%04x\n", + vendorID, deviceID); + +#if 0 + res = pci->find_pci_capability(device, PCI_cap_id_sata, &cap_ofs); + if (res == B_OK) { + uint32 satacr0; + uint32 satacr1; + TRACE("PCI SATA capability found at offset 0x%x\n", cap_ofs); + satacr0 = pci->read_pci_config(device, cap_ofs, 4); + satacr1 = pci->read_pci_config(device, cap_ofs + 4, 4); + TRACE("satacr0 = 0x%08x, satacr1 = 0x%08x\n", satacr0, satacr1); + } +#endif + + free(bus); + return 0.5; +} + + +static status_t +ahci_register_device(device_node_handle parent) +{ + device_node_handle node; + status_t status; + + device_attr attrs[] = { + // info about ourself and our consumer + { B_DRIVER_MODULE, B_STRING_TYPE, { string: AHCI_DEVICE_MODULE_NAME }}, + + // DMA properties + // data must be word-aligned; + { B_BLOCK_DEVICE_DMA_ALIGNMENT, B_UINT32_TYPE, + { ui32: 1 }}, + // one S/G block must not cross 64K boundary + { B_BLOCK_DEVICE_DMA_BOUNDARY, B_UINT32_TYPE, + { ui32: 0xffff }}, + // max size of S/G block is 16 bits with zero being 64K + { B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, B_UINT32_TYPE, + { ui32: 0x10000 }}, + // see definition of MAX_SG_COUNT + { B_BLOCK_DEVICE_MAX_SG_BLOCKS, B_UINT32_TYPE, + { ui32: 32 /* whatever... */ }}, + { NULL } + }; + + TRACE("ahci_register_device\n"); + + // initialize parent (the bus) to get the PCI interface and device + status = sDeviceManager->init_driver(parent, NULL, + (driver_module_info **)&gPCI, (void **)&sPCIDevice); + if (status != B_OK) + return status; + + status = sDeviceManager->register_device(parent, attrs, + NULL, &node); + if (status < B_OK) + return status; + + // TODO: register SIM for every controller we find! + return register_sim(node); +} + + +static status_t +ahci_init_driver(device_node_handle node, void *userCookie, void **_cookie) +{ + TRACE("ahci_init_driver\n"); + return B_OK; +} + + +static status_t +ahci_uninit_driver(void *cookie) +{ + TRACE("ahci_uninit_driver\n"); + return B_OK; +} + + +static void +ahci_device_removed(device_node_handle node, void *cookie) +{ + TRACE("ahci_device_removed\n"); +} + + +static void +ahci_device_cleanup(device_node_handle node) +{ + TRACE("ahci_device_cleanup\n"); +} + + +static void +ahci_get_supported_paths(const char ***_busses, const char ***_devices) +{ + static const char *kBus[] = { "pci", NULL }; + static const char *kDevice[] = { "drivers/dev/disk/sata", NULL }; + + TRACE("ahci_get_supported_paths\n"); + + *_busses = kBus; + *_devices = kDevice; +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + return B_ERROR; + } +} + + +driver_module_info sAHCIDevice = { + { + AHCI_DEVICE_MODULE_NAME, + 0, + std_ops + }, + ahci_supports_device, + ahci_register_device, + ahci_init_driver, + ahci_uninit_driver, + ahci_device_removed, + ahci_device_cleanup, + ahci_get_supported_paths, +}; + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager }, + { SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSI }, + {} +}; + +module_info *modules[] = { + (module_info *)&sAHCIDevice, + (module_info *)&gAHCISimInterface, + NULL +}; diff --git a/src/add-ons/kernel/drivers/disk/ahci/ahci_defs.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h similarity index 81% rename from src/add-ons/kernel/drivers/disk/ahci/ahci_defs.h rename to src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h index 6029e97be0..3c52458b91 100644 --- a/src/add-ons/kernel/drivers/disk/ahci/ahci_defs.h +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h @@ -2,14 +2,17 @@ * Copyright 2007, Marcus Overhagen. All rights reserved. * Distributed under the terms of the MIT License. */ - #ifndef _AHCI_DEFS_H #define _AHCI_DEFS_H -#include +#include +#include -typedef struct -{ +#define AHCI_DEVICE_MODULE_NAME "busses/scsi/ahci/device_v1" +#define AHCI_SIM_MODULE_NAME "busses/scsi/ahci/sim/v1" + + +typedef struct { uint32 clb; // Command List Base Address uint32 clbu; // Command List Base Address Upper 32-Bits uint32 fb; // FIS Base Address @@ -32,8 +35,7 @@ typedef struct } ahci_port; -typedef struct -{ +typedef struct { uint32 cap; // Host Capabilities uint32 ghc; // Global Host Control uint32 is; // Interrupt Status @@ -48,4 +50,8 @@ typedef struct ahci_port port[32]; } ahci_hba; -#endif +extern scsi_sim_interface gAHCISimInterface; +extern pci_device_module_info *gPCI; +extern scsi_for_sim_interface *gSCSI; + +#endif /* _AHCI_DEFS_H */ diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_sim.c b/src/add-ons/kernel/busses/scsi/ahci/ahci_sim.c new file mode 100644 index 0000000000..c3a23c0069 --- /dev/null +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_sim.c @@ -0,0 +1,179 @@ +/* + * Copyright 2007, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include "ahci_defs.h" + +#include + +#define TRACE(a...) dprintf("\33[34mahci:\33[30m " a) +#define FLOW(a...) dprintf("ahci: " a) + + +pci_device_module_info *gPCI; +scsi_for_sim_interface *gSCSI; + + +// #pragma mark - SIM module interface + + +//! execute request +static void +ahci_scsi_io(scsi_sim_cookie cookie, scsi_ccb *request) +{ + TRACE("ahci_scsi_io()\n"); + + request->subsys_status = SCSI_NO_HBA; + gSCSI->finished(request, 1); +} + + +//! abort request +static uchar +ahci_abort_io(scsi_sim_cookie cookie, scsi_ccb *request) +{ + TRACE("ahci_abort_io()\n"); + + return SCSI_REQ_CMP; +} + + +static uchar +ahci_reset_device(scsi_sim_cookie cookie, uchar targetID, uchar targetLUN) +{ + TRACE("ahci_reset_device()\n"); + + return SCSI_REQ_CMP; +} + + +//! terminate request +static uchar +ahci_terminate_io(scsi_sim_cookie cookie, scsi_ccb *request) +{ + TRACE("ahci_terminate_io()\n"); + + return SCSI_NO_HBA; +} + + +//! get information about bus +static uchar +ahci_path_inquiry(scsi_sim_cookie cookie, scsi_path_inquiry *info) +{ + TRACE("ahci_path_inquiry()\n"); + + return SCSI_NO_HBA; +} + + +//! this is called immediately before the SCSI bus manager scans the bus +static uchar +ahci_scan_bus(scsi_sim_cookie cookie) +{ + TRACE("ahci_scan_bus()\n"); + + return SCSI_NO_HBA; +} + + +static uchar +ahci_reset_bus(scsi_sim_cookie cookie) +{ + TRACE("ahci_reset_bus()\n"); + + return SCSI_NO_HBA; +} + + +/*! Get restrictions of one device + (used for non-SCSI transport protocols and bug fixes) +*/ +static void +ahci_get_restrictions(scsi_sim_cookie cookie, uchar targetID, bool *isATAPI, + bool *noAutoSense, uint32 *maxBlocks) +{ + TRACE("ahci_get_restrictions()\n"); + + *isATAPI = false; + *noAutoSense = false; + *maxBlocks = 255; +} + + +static status_t +ahci_ioctl(scsi_sim_cookie cookie, uint8 targetID, uint32 op, void *buffer, + size_t length) +{ + TRACE("ahci_ioctl()\n"); + return B_BAD_VALUE; +} + + +// #pragma mark - + + +static status_t +ahci_sim_init_bus(device_node_handle node, void *user_cookie, void **_cookie) +{ + TRACE("ahci_sim_init_bus\n"); + return B_OK; +} + + +static status_t +ahci_sim_uninit_bus(void *cookie) +{ + TRACE("ahci_sim_uninit_bus\n"); + return B_OK; +} + + +static void +ahci_sim_bus_removed(device_node_handle node, void *cookie) +{ + TRACE("ahci_sim_bus_removed\n"); +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + return B_ERROR; + } +} + + +scsi_sim_interface gAHCISimInterface = { + { + { + AHCI_SIM_MODULE_NAME, + 0, + std_ops + }, + NULL, // supported devices + NULL, // register node + ahci_sim_init_bus, + ahci_sim_uninit_bus, + ahci_sim_bus_removed, + NULL, // device cleanup + NULL, // get supported paths + }, + ahci_scsi_io, + ahci_abort_io, + ahci_reset_device, + ahci_terminate_io, + ahci_path_inquiry, + ahci_scan_bus, + ahci_reset_bus, + ahci_get_restrictions, + ahci_ioctl +}; + diff --git a/src/add-ons/kernel/drivers/disk/Jamfile b/src/add-ons/kernel/drivers/disk/Jamfile index d97f86a2a0..15b51768fe 100644 --- a/src/add-ons/kernel/drivers/disk/Jamfile +++ b/src/add-ons/kernel/drivers/disk/Jamfile @@ -1,6 +1,5 @@ SubDir HAIKU_TOP src add-ons kernel drivers disk ; SubInclude HAIKU_TOP src add-ons kernel drivers disk acpi_loader ; -SubInclude HAIKU_TOP src add-ons kernel drivers disk ahci ; SubInclude HAIKU_TOP src add-ons kernel drivers disk scsi ; SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual ; diff --git a/src/add-ons/kernel/drivers/disk/ahci/Jamfile b/src/add-ons/kernel/drivers/disk/ahci/Jamfile deleted file mode 100644 index c78046227c..0000000000 --- a/src/add-ons/kernel/drivers/disk/ahci/Jamfile +++ /dev/null @@ -1,7 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel drivers disk ahci ; - - -KernelAddon ahci : - ahci.c - ahci_sim.c - ; diff --git a/src/add-ons/kernel/drivers/disk/ahci/ahci.c b/src/add-ons/kernel/drivers/disk/ahci/ahci.c deleted file mode 100644 index e411f26e62..0000000000 --- a/src/add-ons/kernel/drivers/disk/ahci/ahci.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2007, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#include -#include - - -#define TRACE(a...) dprintf("\33[35mahci:\33[30m " a) -#define FLOW(a...) dprintf("ahci: " a) - -static float -ahci_supports_device(device_node_handle parent, bool *_noConnection) -{ - TRACE("ahci_supports_device\n"); - -#if 0 - uint16 vendor_id; - uint16 device_id; - uint8 base_class; - uint8 sub_class; - uint8 class_api; - status_t res; - - if (base_class != PCI_mass_storage || sub_class != PCI_sata || class_api != PCI_sata_ahci) - return 0.0f; - - TRACE("controller found! vendor 0x%04x, device 0x%04x\n", vendor_id, device_id); - - res = pci->find_pci_capability(device, PCI_cap_id_sata, &cap_ofs); - if (res == B_OK) { - uint32 satacr0; - uint32 satacr1; - TRACE("PCI SATA capability found at offset 0x%x\n", cap_ofs); - satacr0 = pci->read_pci_config(device, cap_ofs, 4); - satacr1 = pci->read_pci_config(device, cap_ofs + 4, 4); - TRACE("satacr0 = 0x%08x, satacr1 = 0x%08x\n", satacr0, satacr1); - } -#endif - - return 0.0; -} - - -static status_t -ahci_register_device(device_node_handle parent) -{ - TRACE("ahci_register_device\n"); - return B_OK; -} - - -static status_t -ahci_init_driver(device_node_handle node, void *user_cookie, void **_cookie) -{ - TRACE("ahci_init_driver\n"); - return B_OK; -} - - -static status_t -ahci_uninit_driver(void *cookie) -{ - TRACE("ahci_uninit_driver\n"); - return B_OK; -} - - -static void -ahci_device_removed(device_node_handle node, void *cookie) -{ - TRACE("ahci_device_removed\n"); -} - - -static void -ahci_device_cleanup(device_node_handle node) -{ - TRACE("ahci_device_cleanup\n"); -} - - -static void -ahci_get_supported_paths(const char ***_busses, const char ***_devices) -{ - static const char *kBus[] = { "pci", NULL }; - static const char *kDevice[] = { "drivers/dev/disk/sata", NULL }; - - TRACE("ahci_get_supported_paths\n"); - - *_busses = kBus; - *_devices = kDevice; -} - - -static status_t -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - - default: - return B_ERROR; - } -} - - -driver_module_info ahci_driver = { - { - "ahci/device_v1", - 0, - std_ops - }, - ahci_supports_device, - ahci_register_device, - ahci_init_driver, - ahci_uninit_driver, - ahci_device_removed, - ahci_device_cleanup, - ahci_get_supported_paths, -}; - - -module_info *modules[] = { - (module_info *)&ahci_driver, - NULL -}; diff --git a/src/add-ons/kernel/drivers/disk/ahci/ahci_sim.c b/src/add-ons/kernel/drivers/disk/ahci/ahci_sim.c deleted file mode 100644 index 64cbfdd77a..0000000000 --- a/src/add-ons/kernel/drivers/disk/ahci/ahci_sim.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2007, Marcus Overhagen. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#include -#include - -#define TRACE(a...) dprintf("ahci: " a) -#define FLOW(a...) dprintf("ahci: " a) - - - -/* - -// SIM interface -// SCSI controller drivers must provide this interface -typedef struct scsi_sim_interface { - driver_module_info info; - - // execute request - void (*scsi_io)( scsi_sim_cookie cookie, scsi_ccb *ccb ); - // abort request - uchar (*abort)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort ); - // reset device - uchar (*reset_device)( scsi_sim_cookie cookie, uchar target_id, uchar target_lun ); - // terminate request - uchar (*term_io)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate ); - - // get information about bus - uchar (*path_inquiry)( scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data ); - // scan bus - // this is called immediately before the SCSI bus manager scans the bus - uchar (*scan_bus)( scsi_sim_cookie cookie ); - // reset bus - uchar (*reset_bus)( scsi_sim_cookie cookie ); - - // get restrictions of one device - // (used for non-SCSI transport protocols and bug fixes) - void (*get_restrictions)( - scsi_sim_cookie cookie, - uchar target_id, // target id - bool *is_atapi, // set to true if this is an ATAPI device that - // needs some commands emulated - bool *no_autosense, // set to true if there is no autosense; - // the SCSI bus manager will request sense on - // SCSI_REQ_CMP_ERR/SCSI_DEVICE_CHECK_CONDITION - uint32 *max_blocks ); // maximum number of blocks per transfer if > 0; - // used for buggy devices that cannot handle - // large transfers (read: ATAPI ZIP drives) - - status_t (*ioctl)(scsi_sim_cookie, uint8 targetID, uint32 op, void *buffer, size_t length); -} scsi_sim_interface; - -*/