1/* 2 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6/* 7 Part of Open IDE bus manager 8 9 Basic ATA/ATAPI protocol functions 10*/ 11 12 13#include "ide_internal.h" 14#include <scsi_cmds.h> 15 16#include "ide_sim.h" 17#include "ide_cmds.h" 18 19 20// time in ��s an IDE interrupt may get delayed 21// as this is used for waiting in normal code, this applies to hardware delays only 22// it's used for a hardware bug fix as well, see send_command 23#define MAX_IRQ_DELAY 50 24 25// maximum number send tries before giving up 26#define MAX_FAILED_SEND 1 27 28 29/** busy-wait for data request going high */ 30 31bool 32wait_for_drq(ide_device_info *device) 33{ 34 return ide_wait(device, ide_status_drq, 0, true, 10000000); 35} 36 37 38/** busy-wait for data request going low */ 39 40bool 41wait_for_drqdown(ide_device_info *device) 42{ 43 return ide_wait(device, 0, ide_status_drq, true, 1000000); 44} 45 46 47/** busy-wait for device ready */ 48 49bool 50wait_for_drdy(ide_device_info *device) 51{ 52 return ide_wait(device, ide_status_drdy, ide_status_bsy, false, 5000000); 53} 54 55 56/** reset entire IDE bus 57 * all active request apart from <ignore> are resubmitted 58 */ 59 60bool 61reset_bus(ide_device_info *device, ide_qrequest *ignore) 62{ 63 ide_bus_info *bus = device->bus; 64 ide_controller_interface *controller = bus->controller; 65 ide_channel_cookie channel = bus->channel_cookie; 66 67 dprintf("ide: reset_bus() device %p, bus %p\n", device, bus); 68 69 if (device->reconnect_timer_installed) { 70 cancel_timer(&device->reconnect_timer.te); 71 device->reconnect_timer_installed = false; 72 } 73 74 if (device->other_device->reconnect_timer_installed) { 75 cancel_timer(&device->other_device->reconnect_timer.te); 76 device->other_device->reconnect_timer_installed = false; 77 } 78 79 // activate srst signal for 5 ��s 80 // also, deactivate IRQ 81 // (as usual, we will get an IRQ on disabling, but as we leave them 82 // disabled for 2 ms, this false report is ignored) 83 if (controller->write_device_control(channel, 84 ide_devctrl_nien | ide_devctrl_srst | ide_devctrl_bit3) != B_OK) 85 goto err0; 86 87 spin(5); 88 89 if (controller->write_device_control(channel, ide_devctrl_nien | ide_devctrl_bit3) != B_OK) 90 goto err0; 91 92 // let devices wake up 93 snooze(2000); 94 95 // ouch, we have to wait up to 31 seconds! 96 if (!ide_wait(device, 0, ide_status_bsy, true, 31000000)) { 97 // as we don't know which of the devices is broken 98 // we leave them both alive 99 if (controller->write_device_control(channel, ide_devctrl_bit3) != B_OK) 100 goto err0; 101 102 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT); 103 goto err1; 104 } 105 106 if (controller->write_device_control(channel, ide_devctrl_bit3) != B_OK) 107 goto err0; 108 109 finish_all_requests(bus->devices[0], ignore, SCSI_SCSI_BUS_RESET, true); 110 finish_all_requests(bus->devices[1], ignore, SCSI_SCSI_BUS_RESET, true); 111 112 dprintf("ide: reset_bus() device %p, bus %p success\n", device, bus); 113 return true; 114 115err0: 116 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); 117 118err1: 119 finish_all_requests(bus->devices[0], ignore, SCSI_SCSI_BUS_RESET, true); 120 finish_all_requests(bus->devices[1], ignore, SCSI_SCSI_BUS_RESET, true); 121 122 //xpt->call_async( bus->xpt_cookie, -1, -1, AC_BUS_RESET, NULL, 0 ); 123 124 dprintf("ide: reset_bus() device %p, bus %p failed\n", device, bus); 125 return false; 126} 127 128 129/** execute packet device reset. 130 * resets entire bus on fail or if device is not atapi; 131 * all requests but <ignore> are resubmitted 132 */ 133 134bool 135reset_device(ide_device_info *device, ide_qrequest *ignore) 136{ 137 ide_bus_info *bus = device->bus; 138 status_t res; 139 uint8 orig_command; 140 141 dprintf("ide: reset_device() device %p\n", device); 142 143 SHOW_FLOW0(3, ""); 144 145 if (!device->is_atapi) 146 goto err; 147 148 if (device->reconnect_timer_installed) { 149 cancel_timer(&device->reconnect_timer.te); 150 device->reconnect_timer_installed = false; 151 } 152 153 // select device 154 if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, 155 ide_mask_device_head) != B_OK) 156 goto err; 157 158 // safe original command to let caller restart it 159 orig_command = device->tf.write.command; 160 161 // send device reset, independ of current device state 162 // (that's the point of a reset) 163 device->tf.write.command = IDE_CMD_DEVICE_RESET; 164 res = bus->controller->write_command_block_regs(bus->channel_cookie, 165 &device->tf, ide_mask_command); 166 device->tf.write.command = orig_command; 167 168 if (res != B_OK) 169 goto err; 170 171 // don't know how long to wait, but 31 seconds, like soft reset, 172 // should be enough 173 if (!ide_wait(device, 0, ide_status_bsy, true, 31000000)) 174 goto err; 175 176 // alright, resubmit all requests 177 finish_all_requests(device, ignore, SCSI_SCSI_BUS_RESET, true); 178 179 SHOW_FLOW0(3, "done"); 180 dprintf("ide: reset_device() device %p success\n", device); 181 return true; 182 183err: 184 // do the hard way 185 dprintf("ide: reset_device() device %p failed, calling reset_bus\n", device); 186 return reset_bus(device, ignore); 187} 188 189/** new_state must be either accessing, async_waiting or sync_waiting 190 * param_mask must not include command register 191 */ 192 193bool 194send_command(ide_device_info *device, ide_qrequest *qrequest, 195 bool need_drdy, uint32 timeout, ide_bus_state new_state) 196{ 197 ide_bus_info *bus = device->bus; 198 bigtime_t irq_disabled_at = 0; // make compiler happy 199 uint8 num_retries = 0; 200 bool irq_guard; 201 202retry: 203 irq_guard = bus->num_running_reqs > 1; 204 205 SHOW_FLOW(3, "qrequest=%p, request=%p", qrequest, 206 qrequest ? qrequest->request : NULL); 207 208 // if there are pending requests, IRQs must be disabled to 209 // not mix up IRQ reasons 210 // XXX can we avoid that with the IDE_LOCK trick? It would 211 // save some work and the bug workaround! 212 if (irq_guard) { 213 if (bus->controller->write_device_control(bus->channel_cookie, 214 ide_devctrl_nien | ide_devctrl_bit3) != B_OK) 215 goto err; 216 217 irq_disabled_at = system_time(); 218 } 219 220 // select device 221 if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, 222 ide_mask_device_head) != B_OK) 223 goto err; 224 225 bus->active_device = device; 226 227 if (!ide_wait(device, 0, ide_status_bsy | ide_status_drq, false, 50000)) { 228 uint8 status; 229 230 SHOW_FLOW0(1, "device is not ready"); 231 232 status = bus->controller->get_altstatus(bus->channel_cookie); 233 if (status == 0xff) { 234 // there is no device (should happen during detection only) 235 SHOW_FLOW0(1, "there is no device"); 236 237 // device detection recognizes this code as "all hope lost", so 238 // neither replace it nor use it anywhere else 239 device->subsys_status = SCSI_TID_INVALID; 240 return false; 241 } 242 243 // reset device and retry 244 if (reset_device(device, qrequest) && ++num_retries <= MAX_FAILED_SEND) { 245 SHOW_FLOW0(1, "retrying"); 246 goto retry; 247 } 248 249 SHOW_FLOW0(1, "giving up"); 250 251 // reset to often - abort request 252 device->subsys_status = SCSI_SEL_TIMEOUT; 253 return false; 254 } 255 256 if (need_drdy 257 && (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) { 258 SHOW_FLOW0(3, "drdy not set"); 259 device->subsys_status = SCSI_SEQUENCE_FAIL; 260 return false; 261 } 262 263 // write parameters 264 if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, 265 device->tf_param_mask) != B_OK) 266 goto err; 267 268 if (irq_guard) { 269 // IRQ may be fired by service requests and by the process of disabling(!) 270 // them (I heard this is caused by edge triggered PCI IRQs) 271 272 // wait at least 50 ��s to catch all pending irq's 273 // (at my system, up to 30 ��s elapsed) 274 275 // additionally, old drives (at least my IBM-DTTA-351010) loose 276 // sync if they are pushed too hard - on heavy overlapped write 277 // stress this drive tends to forget outstanding requests, 278 // waiting at least 50 ��s seems(!) to solve this 279 while (system_time() - irq_disabled_at < MAX_IRQ_DELAY) 280 spin(1); 281 } 282 283 // if we will start waiting once the command is sent, we have to 284 // lock the bus before sending; this way, IRQs that are fired 285 // shortly before/after sending of command are delayed until the 286 // command is really sent (start_waiting unlocks the bus) and then 287 // the IRQ handler can check savely whether the IRQ really signals 288 // finishing of command or not by testing the busy-signal of the device 289 if (new_state != ide_state_accessing) { 290 IDE_LOCK(bus); 291 } 292 293 if (irq_guard) { 294 // now it's clear why IRQs gets fired, so we can enable them again 295 if (bus->controller->write_device_control(bus->channel_cookie, 296 ide_devctrl_bit3) != B_OK) 297 goto err1; 298 } 299 300 // write command code - this will start the actual command 301 SHOW_FLOW(3, "Writing command 0x%02x", (int)device->tf.write.command); 302 if (bus->controller->write_command_block_regs(bus->channel_cookie, 303 &device->tf, ide_mask_command) != B_OK) 304 goto err1; 305 306 // start waiting now; also un-blocks IRQ handler (see above) 307 if (new_state != ide_state_accessing) 308 start_waiting(bus, timeout, new_state); 309 310 return true; 311 312err1: 313 if (timeout > 0) { 314 bus->state = ide_state_accessing; 315 IDE_UNLOCK(bus); 316 } 317 318err: 319 device->subsys_status = SCSI_HBA_ERR; 320 return false; 321} 322 323 324/** busy-wait for device 325 * mask - bits of status register that must be set 326 * not_mask - bits of status register that must not be set 327 * check_err - abort if error bit is set 328 * timeout - waiting timeout 329 * return: true on success 330 */ 331 332bool 333ide_wait(ide_device_info *device, int mask, int not_mask, 334 bool check_err, bigtime_t timeout) 335{ 336 ide_bus_info *bus = device->bus; 337 bigtime_t start_time = system_time(); 338 339 while (1) { 340 bigtime_t elapsed_time; 341 int status; 342 343 // do spin before test as the device needs 400 ns 344 // to update its status register 345 spin(1); 346 347 status = bus->controller->get_altstatus(bus->channel_cookie); 348 349 if ((status & mask) == mask && (status & not_mask) == 0) 350 return true; 351 352 if (check_err && (status & ide_status_err) != 0) { 353 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); 354 return false; 355 } 356 357 elapsed_time = system_time() - start_time; 358 359 if (elapsed_time > timeout) { 360 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT); 361 return false; 362 } 363 364 // if we've waited more then 5ms, we start passive waiting 365 // to reduce system load 366 if (elapsed_time > 5000) 367 snooze(elapsed_time / 10); 368 } 369} 370 371 372/** tell device to continue queued command 373 * on return, no waiting is active! 374 * tag - will contain tag of command to be continued 375 * return: true - request continued 376 * false - something went wrong; sense set 377 */ 378 379bool 380device_start_service(ide_device_info *device, int *tag) 381{ 382 ide_bus_info *bus = device->bus; 383 384 device->tf.write.command = IDE_CMD_SERVICE; 385 device->tf.queued.mode = ide_mode_lba; 386 387 if (bus->active_device != device) { 388 // don't apply any precautions in terms of IRQ 389 // -> the bus is in accessing state, so IRQs are ignored anyway 390 if (bus->controller->write_command_block_regs(bus->channel_cookie, 391 &device->tf, ide_mask_device_head) != B_OK) 392 // on error, pretend that this device asks for service 393 // -> the disappeared controller will be recognized soon ;) 394 return true; 395 396 bus->active_device = device; 397 398 // give one clock (400 ns) to take notice 399 spin(1); 400 } 401 402 // here we go... 403 if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf, 404 ide_mask_command) != B_OK) 405 goto err; 406 407 // we need to wait for the device as we want to read the tag 408 if (!ide_wait(device, ide_status_drdy, ide_status_bsy, false, 1000000)) 409 return false; 410 411 // read tag 412 if (bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, 413 ide_mask_sector_count) != B_OK) 414 goto err; 415 416 if (device->tf.queued.release) { 417 // bus release is the wrong answer to a service request 418 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); 419 return false; 420 } 421 422 *tag = device->tf.queued.tag; 423 424 return true; 425 426err: 427 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE); 428 return false; 429} 430 431 432/** check device whether it wants to continue queued request */ 433 434bool 435check_service_req(ide_device_info *device) 436{ 437 ide_bus_info *bus = device->bus; 438 int status; 439 440 // fast bailout if there is no request pending 441 if (device->num_running_reqs == 0) 442 return false; 443 444 if (bus->active_device != device) { 445 // don't apply any precautions in terms of IRQ 446 // -> the bus is in accessing state, so IRQs are ignored anyway 447 if (bus->controller->write_command_block_regs(bus->channel_cookie, 448 &device->tf, ide_mask_device_head) != B_OK) 449 // on error, pretend that this device asks for service 450 // -> the disappeared controller will be recognized soon ;) 451 return true; 452 453 bus->active_device = device; 454 455 // give one clock (400 ns) to take notice 456 spin(1); 457 } 458 459 status = bus->controller->get_altstatus(bus->channel_cookie); 460 461 return (status & ide_status_service) != 0; 462} 463 464