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