1/* 2 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6/*! Generic PCI bus mastering IDE driver. */ 7 8#include <KernelExport.h> 9#include <stdlib.h> 10#include <string.h> 11 12#include <ide_adapter.h> 13 14#define GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME "busses/ide/generic_ide_pci/driver_v1" 15#define GENERIC_IDE_PCI_CHANNEL_MODULE_NAME "busses/ide/generic_ide_pci/channel/v1" 16 17#define IDE_PCI_CONTROLLER_TYPE_NAME "ide pci controller" 18 19ide_for_controller_interface *ide; 20static ide_adapter_interface *ide_adapter; 21device_manager_info *pnp; 22 23 24static void 25set_channel(void *cookie, ide_channel channel) 26{ 27 ide_adapter->set_channel((ide_adapter_channel_info *)cookie, channel); 28} 29 30 31static status_t 32write_command_block_regs(void *channel_cookie, ide_task_file *tf, ide_reg_mask mask) 33{ 34 return ide_adapter->write_command_block_regs((ide_adapter_channel_info *)channel_cookie, tf, mask); 35} 36 37 38static status_t 39read_command_block_regs(void *channel_cookie, ide_task_file *tf, ide_reg_mask mask) 40{ 41 return ide_adapter->read_command_block_regs((ide_adapter_channel_info *)channel_cookie, tf, mask); 42} 43 44 45static uint8 46get_altstatus(void *channel_cookie) 47{ 48 return ide_adapter->get_altstatus((ide_adapter_channel_info *)channel_cookie); 49} 50 51 52static status_t 53write_device_control(void *channel_cookie, uint8 val) 54{ 55 return ide_adapter->write_device_control((ide_adapter_channel_info *)channel_cookie, val); 56} 57 58 59static status_t 60write_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit) 61{ 62 return ide_adapter->write_pio((ide_adapter_channel_info *)channel_cookie, data, count, force_16bit); 63} 64 65 66static status_t 67read_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit) 68{ 69 return ide_adapter->read_pio((ide_adapter_channel_info *)channel_cookie, data, count, force_16bit); 70} 71 72 73static status_t 74prepare_dma(void *channel_cookie, 75 const physical_entry *sg_list, size_t sg_list_count, 76 bool to_device) 77{ 78 return ide_adapter->prepare_dma((ide_adapter_channel_info *)channel_cookie, sg_list, sg_list_count, to_device); 79} 80 81 82static status_t 83start_dma(void *channel_cookie) 84{ 85 return ide_adapter->start_dma((ide_adapter_channel_info *)channel_cookie); 86} 87 88 89static status_t 90finish_dma(void *channel_cookie) 91{ 92 return ide_adapter->finish_dma((ide_adapter_channel_info *)channel_cookie); 93} 94 95 96static status_t 97init_channel(device_node *node, void **channel_cookie) 98{ 99 return ide_adapter->init_channel(node, 100 (ide_adapter_channel_info **)channel_cookie, 101 sizeof(ide_adapter_channel_info), ide_adapter->inthand); 102} 103 104 105static void 106uninit_channel(void *channel_cookie) 107{ 108 ide_adapter->uninit_channel((ide_adapter_channel_info *)channel_cookie); 109} 110 111 112static void 113channel_removed(void *channel_cookie) 114{ 115 ide_adapter->channel_removed((ide_adapter_channel_info *)channel_cookie); 116} 117 118 119static status_t 120init_controller(device_node *node, ide_adapter_controller_info **cookie) 121{ 122 return ide_adapter->init_controller(node, cookie, 123 sizeof( ide_adapter_controller_info)); 124} 125 126 127static void 128uninit_controller(ide_adapter_controller_info *controller) 129{ 130 ide_adapter->uninit_controller(controller); 131} 132 133 134static void 135controller_removed(ide_adapter_controller_info *controller) 136{ 137 return ide_adapter->controller_removed(controller); 138} 139 140 141static status_t 142probe_controller(device_node *parent) 143{ 144 return ide_adapter->probe_controller(parent, 145 GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME, "generic_ide_pci", 146 "Generic IDE PCI Controller", 147 GENERIC_IDE_PCI_CHANNEL_MODULE_NAME, 148 true, 149 true, // assume that command queuing works 150 1, // assume 16 bit alignment is enough 151 0xffff, // boundary is on 64k according to spec 152 0x10000, // up to 64k per S/G block according to spec 153 true); // by default, compatibility mode is used 154} 155 156 157static float 158supports_device(device_node *parent) 159{ 160 const char *bus; 161 uint16 baseClass, subClass; 162 163 // make sure parent is an PCI IDE mass storage host adapter device node 164 if (pnp->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK 165 || pnp->get_attr_uint16(parent, B_DEVICE_TYPE, &baseClass, false) != B_OK 166 || pnp->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subClass, false) != B_OK) 167 return -1; 168 169 if (strcmp(bus, "pci") || baseClass != PCI_mass_storage) 170 return 0.0f; 171 172 if (subClass == PCI_ide) 173 return 0.3f; 174 175 // vendor 105a: Promise Technology, Inc.; device 4d69: 20269 (Ultra133TX2) 176 // has subClass set to PCI_mass_storage_other, and there are others as well. 177 if (subClass == PCI_mass_storage_other) 178 return 0.3f; 179 180 return 0.0f; 181} 182 183 184module_dependency module_dependencies[] = { 185 { IDE_FOR_CONTROLLER_MODULE_NAME, (module_info **)&ide }, 186 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp }, 187 { IDE_ADAPTER_MODULE_NAME, (module_info **)&ide_adapter }, 188 {} 189}; 190 191 192// exported interface 193static ide_controller_interface channel_interface = { 194 { 195 { 196 GENERIC_IDE_PCI_CHANNEL_MODULE_NAME, 197 0, 198 NULL 199 }, 200 201 NULL, // supports device 202 NULL, // register device 203 init_channel, 204 uninit_channel, 205 NULL, // register child devices 206 NULL, // rescan 207 channel_removed, 208 }, 209 210 &set_channel, 211 212 &write_command_block_regs, 213 &read_command_block_regs, 214 215 &get_altstatus, 216 &write_device_control, 217 218 &write_pio, 219 &read_pio, 220 221 &prepare_dma, 222 &start_dma, 223 &finish_dma, 224}; 225 226 227static driver_module_info controller_interface = { 228 { 229 GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME, 230 0, 231 NULL 232 }, 233 234 supports_device, 235 probe_controller, 236 (status_t (*)(device_node *, void **)) init_controller, 237 (void (*)(void *)) uninit_controller, 238 NULL, // register child devices 239 NULL, // rescan 240 (void (*)(void *)) controller_removed, 241}; 242 243module_info *modules[] = { 244 (module_info *)&controller_interface, 245 (module_info *)&channel_interface, 246 NULL 247}; 248