1/* 2 * Copyright 2004-2007, Haiku, Inc. All RightsReserved. 3 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8/* 9 Part of Open IDE bus manager 10 11 ATAPI command protocol 12*/ 13 14#include "ide_internal.h" 15 16#include <scsi_cmds.h> 17 18#include "ide_cmds.h" 19#include "ide_sim.h" 20 21#include <string.h> 22 23 24// used for MODE SENSE/SELECT 6 emulation; maximum size is 255 + header, 25// so this is a safe bet 26#define IDE_ATAPI_BUFFER_SIZE 512 27 28 29/*! 30 Set sense according to error reported by device 31 return: true - device reported error 32*/ 33static bool 34check_packet_error(ide_device_info *device, ide_qrequest *qrequest) 35{ 36 ide_bus_info *bus = device->bus; 37 int status; 38 39 status = bus->controller->get_altstatus(bus->channel_cookie); 40 41 if ((status & (ide_status_err | ide_status_df)) != 0) { 42 int error; 43 44 SHOW_FLOW(3, "packet error, status=%02x", status); 45 46 if (bus->controller->read_command_block_regs(bus->channel_cookie, 47 &device->tf, ide_mask_error) != B_OK) { 48 device->subsys_status = SCSI_HBA_ERR; 49 return true; 50 } 51 52 // the upper 4 bits contain sense key 53 // we don't want to clutter syslog with "not ready" and UA messages, 54 // so use FLOW messages for them 55 error = device->tf.read.error; 56 if ((error >> 4) == SCSIS_KEY_NOT_READY 57 || (error >> 4) == SCSIS_KEY_UNIT_ATTENTION) 58 SHOW_FLOW(3, "error=%x", error); 59 else 60 SHOW_ERROR(3, "error=%x", error); 61 62 // ATAPI says that: 63 // "ABRT shall be set to one if the requested command has been command 64 // aborted because the command code or a command parameter is invalid. 65 // ABRT may be set to one if the device is not able to complete the 66 // action requested by the command." 67 // Effectively, it can be set if "something goes wrong", including 68 // if the medium got changed. Therefore, we currently ignore the bit 69 // and rely on auto-sense information 70 /* 71 if ((error & ide_error_abrt) != 0) { 72 // if command got aborted, there's no point in reading sense 73 set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE); 74 return false; 75 } 76 */ 77 78 // tell SCSI layer that sense must be requested 79 // (we don't take care of auto-sense ourselve) 80 device->subsys_status = SCSI_REQ_CMP_ERR; 81 qrequest->request->device_status = SCSI_STATUS_CHECK_CONDITION; 82 // reset pending emulated sense - its overwritten by a real one 83 device->combined_sense = 0; 84 return true; 85 } 86 87 return false; 88} 89 90 91/*! IRQ handler of packet transfer (executed as DPC) */ 92void 93packet_dpc(ide_qrequest *qrequest) 94{ 95 ide_device_info *device = qrequest->device; 96 ide_bus_info *bus = device->bus; 97 int status; 98 uint32 timeout = qrequest->request->timeout > 0 ? 99 qrequest->request->timeout : IDE_STD_TIMEOUT; 100 101 SHOW_FLOW0(3, ""); 102 103 bus->controller->read_command_block_regs(bus->channel_cookie, 104 &device->tf, ide_mask_error | ide_mask_ireason); 105 106 status = bus->controller->get_altstatus(bus->channel_cookie); 107 108 if (qrequest->packet_irq) { 109 // device requests packet 110 qrequest->packet_irq = false; 111 112 if (!device->tf.packet_res.cmd_or_data 113 || device->tf.packet_res.input_or_output 114 || (status & ide_status_drq) == 0) { 115 device->subsys_status = SCSI_SEQUENCE_FAIL; 116 goto err; 117 } 118 119 start_waiting_nolock(device->bus, timeout, ide_state_async_waiting); 120 121 // send packet 122 if (bus->controller->write_pio(bus->channel_cookie, 123 (uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16), 124 true) != B_OK) { 125 SHOW_ERROR0( 1, "Error sending command packet" ); 126 127 device->subsys_status = SCSI_HBA_ERR; 128 goto err_cancel_timer; 129 } 130 131 return; 132 } 133 134 if (qrequest->uses_dma) { 135 // DMA transmission finished 136 bool dma_err, dev_err; 137 138 // don't check drq - if there is some data left, we cannot handle 139 // it anyway 140 // XXX does the device throw remaining data away on DMA overflow? 141 SHOW_FLOW0(3, "DMA done"); 142 143 dma_err = !finish_dma(device); 144 dev_err = check_packet_error(device, qrequest); 145 146 // what to do if both the DMA controller and the device reports an error? 147 // let's assume that the DMA controller got problems because there was a 148 // device error, so we ignore the dma error and use the device error instead 149 if (dev_err) { 150 finish_checksense(qrequest); 151 return; 152 } 153 154 // device is happy, let's see what the controller says 155 if (!dma_err) { 156 // if DMA works, reset error counter so we don't disable 157 // DMA only because it didn't work once in a while 158 device->DMA_failures = 0; 159 // this is a lie, but there is no way to find out 160 // how much has been transmitted 161 qrequest->request->data_resid = 0; 162 finish_checksense(qrequest); 163 } else { 164 // DMA transmission went wrong 165 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); 166 167 if (++device->DMA_failures >= MAX_DMA_FAILURES) { 168 SHOW_ERROR0(1, "Disabling DMA because of too many errors"); 169 170 device->DMA_enabled = false; 171 } 172 173 finish_checksense(qrequest); 174 } 175 176 return; 177 } 178 179 // PIO mode 180 if ((status & ide_status_drq) != 0) { 181 // device wants to transmit data 182 int length; 183 status_t err; 184 185 SHOW_FLOW0(3, "data transmission"); 186 187 if (device->tf.packet_res.cmd_or_data) { 188 device->subsys_status = SCSI_SEQUENCE_FAIL; 189 goto err; 190 } 191 192 // check whether transmission direction matches 193 if ((device->tf.packet_res.input_or_output ^ qrequest->is_write) == 0) { 194 SHOW_ERROR0(2, "data transmission in wrong way!?"); 195 196 // TODO: hm, either the device is broken or the caller has specified 197 // the wrong direction - what is the proper handling? 198 set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); 199 200 // reset device to make it alive 201 // TODO: the device will abort next command with a reset condition 202 // perhaps we should hide that by reading sense? 203 SHOW_FLOW0(3, "Reset"); 204 reset_device(device, qrequest); 205 206 finish_checksense(qrequest); 207 return; 208 } 209 210 // ask device how much data it wants to transmit 211 bus->controller->read_command_block_regs(bus->channel_cookie, 212 &device->tf, ide_mask_byte_count); 213 214 length = device->tf.packet_res.byte_count_0_7 215 | ((int)device->tf.packet_res.byte_count_8_15 << 8); 216 217 SHOW_FLOW(3, "device transmittes %d bytes", length); 218 219 // start waiting before starting transmission, else we 220 // could start waiting too late; 221 // don't mind getting overtaken by IRQ handler - as it will 222 // issue a DPC for the thread context we are in, we are save 223 start_waiting_nolock(device->bus, timeout, ide_state_async_waiting); 224 225 if (device->tf.packet_res.input_or_output) 226 err = read_PIO_block(qrequest, length); 227 else 228 err = write_PIO_block(qrequest, length); 229 230 // only report "real" errors; 231 // discarding data (ERR_TOO_BIG) can happen but is OK 232 if (err == B_ERROR) { 233 SHOW_ERROR0(2, "Error during PIO transmission"); 234 235 device->subsys_status = SCSI_HBA_ERR; 236 goto err_cancel_timer; 237 } 238 239 SHOW_FLOW0(3, "7"); 240 return; 241 } else { 242 // device has done job and doesn't want to transmit data anymore 243 // -> finish request 244 SHOW_FLOW0(3, "no data"); 245 246 check_packet_error(device, qrequest); 247 248 SHOW_FLOW(3, "finished: %d of %d left", 249 (int)qrequest->request->data_resid, 250 (int)qrequest->request->data_length); 251 252 finish_checksense(qrequest); 253 return; 254 } 255 256 return; 257 258err_cancel_timer: 259 cancel_irq_timeout(device->bus); 260err: 261 finish_checksense(qrequest); 262} 263 264 265/*! Create taskfile for ATAPI packet */ 266static bool 267create_packet_taskfile(ide_device_info *device, ide_qrequest *qrequest, 268 bool write) 269{ 270 scsi_ccb *request = qrequest->request; 271 272 SHOW_FLOW(3, "DMA enabled=%d, uses_dma=%d, scsi_cmd=%x", 273 device->DMA_enabled, qrequest->uses_dma, device->packet[0]); 274 275 device->tf_param_mask = ide_mask_features | ide_mask_byte_count; 276 277 device->tf.packet.dma = qrequest->uses_dma; 278 device->tf.packet.ovl = 0; 279 device->tf.packet.byte_count_0_7 = request->data_length & 0xff; 280 device->tf.packet.byte_count_8_15 = request->data_length >> 8; 281 device->tf.packet.command = IDE_CMD_PACKET; 282 283 return true; 284} 285 286 287/*! Send ATAPI packet */ 288void 289send_packet(ide_device_info *device, ide_qrequest *qrequest, bool write) 290{ 291 ide_bus_info *bus = device->bus; 292 bool packet_irq = device->atapi.packet_irq; 293 uint8 scsi_cmd = device->packet[0]; 294 295 SHOW_FLOW( 3, "qrequest=%p, command=%x", qrequest, scsi_cmd ); 296 297 /*{ 298 unsigned int i; 299 300 for( i = 0; i < sizeof( device->packet ); ++i ) 301 dprintf( "%x ", device->packet[i] ); 302 }*/ 303 304 SHOW_FLOW(3, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x (len=%d)", 305 device->packet[0], device->packet[1], device->packet[2], 306 device->packet[3], device->packet[4], device->packet[5], 307 device->packet[6], device->packet[7], device->packet[8], 308 device->packet[9], device->packet[10], device->packet[11], 309 qrequest->request->cdb_length); 310 311 //snooze( 1000000 ); 312 313 qrequest->is_write = write; 314 // if needed, mark first IRQ as being packet request IRQ 315 qrequest->packet_irq = packet_irq; 316 317 // only READ/WRITE commands can use DMA 318 // (the device may support it always, but IDE controllers don't 319 // report how much data is transmitted, and this information is 320 // crucial for the SCSI protocol) 321 // special offer: let READ_CD commands use DMA too 322 qrequest->uses_dma = device->DMA_enabled 323 && (scsi_cmd == SCSI_OP_READ_6 || scsi_cmd == SCSI_OP_WRITE_6 324 || scsi_cmd == SCSI_OP_READ_10 || scsi_cmd == SCSI_OP_WRITE_10 325 || scsi_cmd == SCSI_OP_READ_12 || scsi_cmd == SCSI_OP_WRITE_12 326 || scsi_cmd == SCSI_OP_READ_CD); 327 328 // try preparing DMA, if that fails, fall back to PIO 329 if (qrequest->uses_dma) { 330 SHOW_FLOW0(3, "0"); 331 if (!prepare_dma( device, qrequest)) 332 qrequest->uses_dma = false; 333 334 SHOW_FLOW(3, "0->%d", qrequest->uses_dma); 335 } 336 337 SHOW_FLOW0(3, "1"); 338 339 if (!qrequest->uses_dma) 340 prep_PIO_transfer(device, qrequest); 341 342 SHOW_FLOW0(3, "2"); 343 344 if (!create_packet_taskfile(device, qrequest, write)) 345 goto err_setup; 346 347 SHOW_FLOW0(3, "3"); 348 349 if (!send_command(device, qrequest, false, 350 device->atapi.packet_irq_timeout, 351 device->atapi.packet_irq ? ide_state_async_waiting : ide_state_accessing)) 352 goto err_setup; 353 354 SHOW_FLOW0(3, "4"); 355 356 if (packet_irq) { 357 // device asks for packet via IRQ; 358 // timeout and stuff is already set by send_command 359 return; 360 } 361 362 SHOW_FLOW0(3, "5"); 363 364 // wait for device to get ready for packet transmission 365 if (!ide_wait(device, ide_status_drq, ide_status_bsy, false, 100000)) 366 goto err_setup; 367 368 SHOW_FLOW0(3, "6"); 369 370 // make sure device really asks for command packet 371 bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf, 372 ide_mask_ireason); 373 374 if (!device->tf.packet_res.cmd_or_data 375 || device->tf.packet_res.input_or_output) { 376 device->subsys_status = SCSI_SEQUENCE_FAIL; 377 goto err_setup; 378 } 379 380 SHOW_FLOW0(3, "7"); 381 382 // some old drives need a delay before submitting the packet 383 spin(10); 384 385 // locking is evil here: as soon as the packet is transmitted, the device 386 // may raise an IRQ (which actually happens if the device reports an Check 387 // Condition error). Thus, we have to lock out the IRQ handler _before_ we 388 // start packet transmission, which forbids all kind of interrupts for some 389 // time; to reduce this period, blocking is done just before last dword is 390 // sent (avoid sending 16 bits as controller may transmit 32 bit chunks) 391 392 // write packet 393 if (bus->controller->write_pio(bus->channel_cookie, 394 (uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16) - 2, 395 true) != B_OK) { 396 goto err_packet; 397 } 398 399 IDE_LOCK(bus); 400 401 if (bus->controller->write_pio(bus->channel_cookie, 402 (uint16 *)device->packet + sizeof(device->packet) / sizeof(uint16) - 2, 403 2, true) != B_OK) { 404 goto err_packet2; 405 } 406 407 if (qrequest->uses_dma) { 408 SHOW_FLOW0( 3, "ready for DMA" ); 409 410 // S/G table must already be setup - we hold the bus lock, so 411 // we really have to hurry up 412 start_dma_wait(device, qrequest); 413 } else { 414 uint32 timeout = qrequest->request->timeout > 0 ? 415 qrequest->request->timeout : IDE_STD_TIMEOUT; 416 417 start_waiting(bus, timeout, ide_state_async_waiting); 418 } 419 420 SHOW_FLOW0(3, "8"); 421 return; 422 423err_packet2: 424 IDE_UNLOCK(bus); 425 426err_packet: 427 device->subsys_status = SCSI_HBA_ERR; 428 429err_setup: 430 if (qrequest->uses_dma) 431 abort_dma(device, qrequest); 432 433 finish_checksense(qrequest); 434} 435 436 437/*! Execute SCSI I/O for atapi devices */ 438void 439atapi_exec_io(ide_device_info *device, ide_qrequest *qrequest) 440{ 441 scsi_ccb *request = qrequest->request; 442 443 SHOW_FLOW(3, "command=%x", qrequest->request->cdb[0]); 444 445 // ATAPI command packets are 12 bytes long; 446 // if the command is shorter, remaining bytes must be padded with zeros 447 memset(device->packet, 0, sizeof(device->packet)); 448 memcpy(device->packet, request->cdb, request->cdb_length); 449 450 if (request->cdb[0] == SCSI_OP_REQUEST_SENSE && device->combined_sense) { 451 // we have a pending emulated sense - return it on REQUEST SENSE 452 ide_request_sense(device, qrequest); 453 finish_checksense(qrequest); 454 } else { 455 // reset all error codes for new request 456 start_request(device, qrequest); 457 458 // now we have an IDE packet 459 send_packet(device, qrequest, 460 (request->flags & SCSI_DIR_MASK) == SCSI_DIR_OUT); 461 } 462} 463 464 465/*! Prepare device info for ATAPI device */ 466bool 467prep_atapi(ide_device_info *device) 468{ 469 ide_device_infoblock *infoblock = &device->infoblock; 470 471 SHOW_FLOW0(3, ""); 472 473 device->is_atapi = true; 474 device->exec_io = atapi_exec_io; 475 476 if (infoblock->_0.atapi.ATAPI != 2) 477 return false; 478 479 switch(infoblock->_0.atapi.drq_speed) { 480 case 0: 481 case 2: 482 device->atapi.packet_irq = false; 483 break; 484 case 1: 485 device->atapi.packet_irq = true; 486 device->atapi.packet_irq_timeout = IDE_STD_TIMEOUT; 487 break; 488 default: 489 return false; 490 } 491 492 SHOW_FLOW(3, "drq speed: %d", infoblock->_0.atapi.drq_speed); 493 494 /*if( infoblock->_0.atapi.packet_size != 0 ) 495 return false;*/ 496 497 device->device_type = infoblock->_0.atapi.type; 498 device->last_lun = infoblock->last_lun; 499 500 SHOW_FLOW(3, "device_type=%d, last_lun=%d", 501 device->device_type, device->last_lun); 502 503 // don't use task file to select LUN but command packet 504 // (SCSI bus manager sets LUN there automatically) 505 device->tf.packet.lun = 0; 506 507 if (!initialize_qreq_array(device, 1) 508 || !configure_dma(device)) 509 return false; 510 511 // currently, we don't support queuing, but I haven't found any 512 // ATAPI device that supports queuing anyway, so this is no loss 513 device->CQ_enabled = device->CQ_supported = false; 514 515 return true; 516} 517