1 /* 2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. 3 * Copyright 2008, Marcus Overhagen. 4 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. 5 * Copyright 2002-2003, Thomas Kurschel. 6 * 7 * Distributed under the terms of the MIT License. 8 */ 9 10 #include "ATAPrivate.h" 11 12 13 scsi_for_sim_interface *gSCSIModule = NULL; 14 device_manager_info *gDeviceManager = NULL; 15 16 17 static status_t 18 ata_sim_init_bus(device_node *node, void **cookie) 19 { 20 ATAChannel *channel = new(std::nothrow) ATAChannel(node); 21 if (channel == NULL) 22 return B_NO_MEMORY; 23 24 status_t result = channel->InitCheck(); 25 if (result != B_OK) { 26 TRACE_ERROR("failed to set up ata channel object\n"); 27 delete channel; 28 return result; 29 } 30 31 *cookie = channel; 32 return B_OK; 33 } 34 35 36 static void 37 ata_sim_uninit_bus(void *cookie) 38 { 39 ATAChannel *channel = (ATAChannel *)cookie; 40 delete channel; 41 } 42 43 44 static void 45 ata_sim_bus_removed(void *cookie) 46 { 47 ATAChannel *channel = (ATAChannel *)cookie; 48 if (channel->Bus() != NULL) { 49 gSCSIModule->block_bus(channel->Bus()); 50 channel->SetBus(NULL); 51 } 52 } 53 54 55 static void 56 ata_sim_set_scsi_bus(scsi_sim_cookie cookie, scsi_bus bus) 57 { 58 ATAChannel *channel = (ATAChannel *)cookie; 59 channel->SetBus(bus); 60 channel->ScanBus(); 61 } 62 63 64 static void 65 ata_sim_scsi_io(scsi_sim_cookie cookie, scsi_ccb *ccb) 66 { 67 ATAChannel *channel = (ATAChannel *)cookie; 68 if (channel->Bus() == NULL) { 69 ccb->subsys_status = SCSI_NO_HBA; 70 gSCSIModule->finished(ccb, 1); 71 return; 72 } 73 74 if (channel->ExecuteIO(ccb) == B_BUSY) 75 gSCSIModule->requeue(ccb, true); 76 } 77 78 79 static uchar 80 ata_sim_abort(scsi_sim_cookie cookie, scsi_ccb *ccb) 81 { 82 ATAChannel *channel = (ATAChannel *)cookie; 83 if (channel->Bus() == NULL) 84 return SCSI_NO_HBA; 85 86 // aborting individual commands is not possible 87 return SCSI_REQ_CMP; 88 } 89 90 91 static uchar 92 ata_sim_reset_device(scsi_sim_cookie cookie, uchar targetId, uchar targetLun) 93 { 94 ATAChannel *channel = (ATAChannel *)cookie; 95 if (channel->Bus() == NULL) 96 return SCSI_NO_HBA; 97 98 // TODO: implement 99 return SCSI_REQ_INVALID; 100 } 101 102 103 static uchar 104 ata_sim_term_io(scsi_sim_cookie cookie, scsi_ccb *ccb) 105 { 106 ATAChannel *channel = (ATAChannel *)cookie; 107 if (channel->Bus() == NULL) 108 return SCSI_NO_HBA; 109 110 // we don't terminate commands, ignore 111 return SCSI_REQ_CMP; 112 } 113 114 115 static uchar 116 ata_sim_path_inquiry(scsi_sim_cookie cookie, scsi_path_inquiry *info) 117 { 118 ATAChannel *channel = (ATAChannel *)cookie; 119 if (channel->Bus() == NULL) 120 return SCSI_NO_HBA; 121 122 channel->PathInquiry(info); 123 return SCSI_REQ_CMP; 124 } 125 126 127 static uchar 128 ata_sim_rescan_bus(scsi_sim_cookie cookie) 129 { 130 // TODO: implement 131 return SCSI_REQ_CMP; 132 } 133 134 135 static uchar 136 ata_sim_reset_bus(scsi_sim_cookie cookie) 137 { 138 ATAChannel *channel = (ATAChannel *)cookie; 139 if (channel->Bus() == NULL) 140 return SCSI_NO_HBA; 141 142 //channel->Reset(); 143 panic("asking for trouble"); 144 return SCSI_REQ_CMP; 145 } 146 147 148 static void 149 ata_sim_get_restrictions(scsi_sim_cookie cookie, uchar targetID, 150 bool *isATAPI, bool *noAutoSense, uint32 *maxBlocks) 151 { 152 ATAChannel *channel = (ATAChannel *)cookie; 153 channel->GetRestrictions(targetID, isATAPI, noAutoSense, maxBlocks); 154 } 155 156 157 static status_t 158 ata_sim_control(scsi_sim_cookie cookie, uchar targetID, uint32 op, void *buffer, 159 size_t length) 160 { 161 ATAChannel *channel = (ATAChannel *)cookie; 162 return channel->Control(targetID, op, buffer, length); 163 } 164 165 166 status_t 167 ata_channel_added(device_node *parent) 168 { 169 const char *controllerName; 170 if (gDeviceManager->get_attr_string(parent, 171 ATA_CONTROLLER_CONTROLLER_NAME_ITEM, &controllerName, true) != B_OK) { 172 TRACE_ERROR("controller name missing\n"); 173 return B_ERROR; 174 } 175 176 int32 channelID = gDeviceManager->create_id(ATA_CHANNEL_ID_GENERATOR); 177 if (channelID < 0) { 178 TRACE_ERROR("out of channel ids\n"); 179 return B_ERROR; 180 } 181 182 device_attr attributes[] = { 183 { 184 B_DEVICE_FIXED_CHILD, B_STRING_TYPE, 185 { .string = SCSI_FOR_SIM_MODULE_NAME } 186 }, 187 188 { 189 SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, 190 { .string = controllerName } 191 }, 192 193 // maximum number of blocks per transmission: 194 // - ATAPI uses packets, i.e. normal SCSI limits apply 195 // but I'm not sure about controller restrictions 196 // - ATA allows up to 256 blocks for LBA28 and 65535 for LBA48 197 // to fix specific drive bugs use ATAChannel::GetRestrictions() 198 { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { .ui32 = 0xffff } }, 199 { ATA_CHANNEL_ID_ITEM, B_UINT32_TYPE, { .ui32 = (uint32)channelID } }, 200 { NULL } 201 }; 202 203 return gDeviceManager->register_node(parent, ATA_SIM_MODULE_NAME, 204 attributes, NULL, NULL); 205 } 206 207 208 status_t 209 ata_interrupt_handler(void *cookie, uint8 status) 210 { 211 ATAChannel *channel = (ATAChannel *)cookie; 212 return channel->Interrupt(status); 213 } 214 215 216 static status_t 217 std_ops(int32 op, ...) 218 { 219 switch (op) { 220 case B_MODULE_INIT: 221 case B_MODULE_UNINIT: 222 return B_OK; 223 224 default: 225 break; 226 } 227 228 return B_ERROR; 229 } 230 231 232 scsi_sim_interface ata_sim_module = { 233 { 234 { 235 ATA_SIM_MODULE_NAME, 236 0, 237 std_ops 238 }, 239 240 NULL, // supported devices 241 NULL, // register node 242 ata_sim_init_bus, 243 ata_sim_uninit_bus, 244 NULL, // register child devices 245 NULL, // rescan 246 ata_sim_bus_removed, 247 NULL, // suspend 248 NULL, // resume 249 }, 250 251 ata_sim_set_scsi_bus, 252 ata_sim_scsi_io, 253 ata_sim_abort, 254 ata_sim_reset_device, 255 ata_sim_term_io, 256 ata_sim_path_inquiry, 257 ata_sim_rescan_bus, 258 ata_sim_reset_bus, 259 ata_sim_get_restrictions, 260 ata_sim_control 261 }; 262 263 ata_for_controller_interface ata_for_controller_module = { 264 { 265 { 266 ATA_FOR_CONTROLLER_MODULE_NAME, 267 0, 268 &std_ops 269 }, 270 271 NULL, // supported devices 272 ata_channel_added, 273 NULL, 274 NULL, 275 NULL 276 }, 277 278 ata_interrupt_handler 279 }; 280 281 282 module_dependency module_dependencies[] = { 283 { SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSIModule }, 284 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, 285 {} 286 }; 287 288 module_info *modules[] = { 289 (module_info *)&ata_for_controller_module, 290 (module_info *)&ata_sim_module, 291 NULL 292 }; 293