scsi.lst
来自「HIGH_SPEED_USB_To_ATA(IDE)Firmware相关代码(E」· LST 代码 · 共 1,388 行 · 第 1/5 页
LST
1,388 行
258 1 //char count;
259 1
260 1 if (!scsi)
261 1 return(result);
262 1
263 1 #if DEVICE_TYPE_IS_SCSI
264 1 useUdma = 0;
265 1 result = sendSCSICommand((char xdata *) testUnitReady);
266 1 if (result != USBS_PASSED)
267 1 {
268 2 result = sendSCSICommand((char xdata *) requestSense);
269 2 if (result != USBS_PASSED)
270 2 {
271 3 }
272 2
273 2 //result = waitForIntrq();
274 2
275 2 readPIO16toXdata(ATAPI_DATA_REG, halfKBuffer, SENSE_LEN, LISTEN_TO_DRIVE_LEN);
276 2 return(halfKBuffer[12]);
277 2 }
278 1 #endif
279 1 }
280
281
282 // Read the Inquiry info into our internal data structures.
283 // NOT prompted by the host.
284 #define INQUIRY_LEN 0x2c
285 const char code inquiryCommand[12] = { 0x12, 0x00, 0x00, 0x00, INQUIRY_LEN, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00};
286 void SCSIInquiryToATAPI()
287 {
288 1 #if DEVICE_TYPE_IS_SCSI
289 1
290 1 bit result;
291 1
292 1 useUdma = 0;
293 1 result = sendSCSICommand((char xdata *) inquiryCommand);
294 1 if (result != USBS_PASSED)
295 1 {
296 2 failedIn(); //This is an internal command, just leave if it fails.
297 2 return;
298 2 }
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 6
299 1
300 1 result = waitForIntrq();
301 1
302 1 readPIO16toXdata(ATAPI_DATA_REG, halfKBuffer, INQUIRY_LEN, LISTEN_TO_DRIVE_LEN);
303 1
304 1
305 1 if (halfKBuffer[SCSI_INQUIRY_DEVICE_CLASS] == 5)
306 1 {
307 2 intrfcSubClass = USB_MS_CD_ROM_SUBCLASS;
308 2 }
309 1 #endif
310 1 }
311
312
313 WORD getDriveDataLen()
314 {
315 1 WORD driveDataLen;
316 1
317 1
318 1 driveDataLen = readPIO8(ATAPI_BYTE_COUNT_MSB) << 8;
319 1 driveDataLen += readPIO8(ATAPI_BYTE_COUNT_LSB);
320 1 return(driveDataLen);
321 1 }
322
323
324
325 ///////////////////////////////////////////////////////////////////////////////
326 #if DEVICE_TYPE_IS_SCSI
327 ///////////////////////////////////////////////////////////////////////////////
328
329 //-----------------------------------------------------------------------------
330 // Function: scsiWrite()
331 //
332 // Input: none
333 // Output: bit flag
334 // 0 = success, 1 = failure
335 //
336 // Global data:
337 // dataTransferLen - Amount of data requested by the host. Counts down.
338 // EP2CS - Endpoint buffer status byte.
339 // EP2BCL - Endpoint LSB byte count register.
340 //
341 // Local data:
342 // wDriveDataLen - Amount of data drive will accept.
343 // wAmountToWrite - Amount of data to write to the drive. This is typically
344 // a portion wDriveDataLen, and is qualified by the packet lenght.
345 // wAmountSent - Amount of data sent to the drive. Counts up to ensure we don't
346 // exceed the packet size.
347 // driveStatus - Drive status from last action.
348 // bDone - loop control flag
349 //
350 // Description:
351 // This function handles the special case of scsi MODE PAGE write (MODE SELECT command).
352 // The drive byte count and the DRQ bit are used to determine how much data to send.
353 // Typically, the host requests to send data that is much larger than what the
354 // drive wants to accept.
355 //
356 // The drive may want to receive data in chunks less than a packet size, and the
357 // total number of bytes to satisfy the command may be less or greater than
358 // a packet length. Drive data request is processed as follows:
359 //
360 // (1) Total number of bytes is less than a packet, and drive wants to receive it in
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 7
361 // increments. The rest of the packet must be processed out of the buffer in
362 // the size requested by the drive. This transaction is governed by the
363 // DRQ bit in the status register.
364 //
365 // (2) Total number of bytes is greater than a packet, but drive wants it
366 // in increments less than a packet lenght. Full packet(s) are processed out
367 // of the buffer using logic from (1) until the drive is satisfied. This
368 // transaction is governed by the DRQ bit in the status register as well as the
369 // byte count from the drive. Any data residue in the endpoint buffer is sent
370 // to ATAPI_NULL_REGISTER.
371 //
372 // If the host is determined to queue up packets to the buffer after the drive
373 // byte count has been satisfied (DRQ=0), the data is processed out of the endpoint
374 // buffer and discarded by setting the skip bit in the endpoint's byte count
375 // register.
376 //
377 // The DRQ bit is valid.
378 //
379 // If a write encounters an error, we return an error and let caller
380 // stall the endpoint.
381 //
382 //-----------------------------------------------------------------------------
383 static BYTE scsiWrite(void)
384 {
385 1
386 1 WORD wDriveDataLen = 0;
387 1 BYTE driveStatus = 0;
388 1 WORD wAmountToWrite = 0;
389 1 WORD wAmountSent = 0;
390 1 bit bDone = 0;
391 1 bit bShortPacketReceived = 0;
392 1 BYTE cReturnStatus = USBS_PASSED;
393 1
394 1
395 1 // See if drive is finished processing command and
396 1 // is ready for data.
397 1 while(readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
398 1 ;
399 1
400 1 driveStatus = readATAPI_STATUS_REG();
401 1
402 1 if (driveStatus & ATAPI_STATUS_DRQ_BIT)
403 1 {
404 2 while( (!(driveStatus & ATAPI_STATUS_ERROR_BIT)) && (!bDone) && dataTransferLen)
405 2 {
406 3 // Make sure the data is already in the endpoint buffer
407 3 if(!(EP2CS & (bmEPEMPTY | bmEPSTALL)))
408 3 {
409 4 if (EP2BC & (wPacketSize - 1))
410 4 bShortPacketReceived = 1;
411 4
412 4 EP2BCL = 00; // Release the endpoint buffer to FIFO.
413 4
414 4 // Get the amount of data the drive is willing to accept
415 4 if(!wDriveDataLen)
416 4 wDriveDataLen = getDriveDataLen();
417 4
418 4 wAmountSent = 0;
419 4 while( (wPacketSize > wAmountSent) && (!bDone) && dataTransferLen)
420 4 {
421 5 // wAmountToWrite is limited by two factors:
422 5 // -- wDriveDataLen -- The amount of data remaining in the drive's most recent request
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 8
423 5 // -- wPacketSize-wAmountSent -- The amount of data remaining in our buffer
424 5 wAmountToWrite = min(wPacketSize-wAmountSent, wDriveDataLen);
425 5 wAmountToWrite = min(dataTransferLen, wAmountToWrite);
426 5
427 5 // Send the packet and adjust counts.
428 5 writePIO16(ATAPI_DATA_REG, wAmountToWrite+1);
429 5 dataTransferLen -= wAmountToWrite;
430 5 wDriveDataLen -= wAmountToWrite;
431 5 wAmountSent += wAmountToWrite;
432 5
433 5 // Make sure the write is successful, otherwise get out. -- First wait for the busy bit to
-clear.
434 5 while(readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
435 5 ;
436 5
437 5 // Don't trust the first result after the busy bit goes away. Read it again.
438 5 // The DELL-07 CDRW has occasional problems if this is not done.
439 5 driveStatus = readATAPI_STATUS_REG();
440 5
441 5 if(driveStatus & ATAPI_STATUS_ERROR_BIT)
442 5 {
443 6 cReturnStatus = USBS_FAILED;
444 6 bDone = 1;
445 6 }
446 5 else
447 5 {
448 6 // Check if drive is finished with transaction.
449 6 if(!(driveStatus & ATAPI_STATUS_DRQ_BIT))
450 6 {
451 7 bDone=1;
452 7 cReturnStatus = USBS_PASSED;
453 7 }
454 6 else if(!wDriveDataLen)
455 6 wDriveDataLen = getDriveDataLen();
456 6
457 6 } // end else
458 5 } // end while(within current packet)
459 4 } // end if(data in endpoint buffer)
460 3 } // end while(all data)
461 2 } // end if (drive has data)
462 1
463 1 // If the device still wants more data from the host at this point, it's a phase error (case 13)
464 1 if ((readATAPI_STATUS_REG() & ATAPI_STATUS_DRQ_BIT) || wDriveDataLen)
465 1 cReturnStatus = (USBS_PHASE_ERROR);
466 1
467 1 // If there is still data in our buffer there are several possibilities:
468 1 // 1) Data in our buffer. No more data coming from the host. Reset the endpoint.
469 1 // 2) Buffer full, more data expected from the host. STALL.
470 1 // 3) Data still on the way from the host that will go beyond our buffer size. STALL.
471 1 // 4) Data still on the way from the host that will fit within our buffer size. Wait for the data, th
-en reset the endpoint.
472 1 // There is no clean way to wait for the data that works with the current TCL scripts. Just rese
-t the endpoing.
473 1 //
474 1 if (dataTransferLen && !bShortPacketReceived)
475 1 stallEP2OUT();
476 1 // This is done in send_usbs()
477 1 // else if (!(EP2468STAT & bmEP2EMPTY)) // Discard residue in the buffer if needed. This is
-required so that the FIFO will give the buffer back to us (if we DON'T stall)
478 1 // // For example, case 11 with 250 bytes of data.
479 1 // ResetAndArmEp2();
480 1 return(cReturnStatus);
C51 COMPILER V7.50 SCSI 11/07/2006 14:52:10 PAGE 9
481 1 }
482
483
484 //-----------------------------------------------------------------------------
485 // Function: sendSCSICommand()
486 //
487 // Input:
488 // bit useInterrupt
489 // char xdata *cmdbuf - scsi command packet (EP2FIFOBUF + CBW_DATA_START)
490 //
491 // Output: bit flag
492 // 0 = success, 1 = failure
493 //
494 // Local data:
495 // WORD cmd_data - modified command data packet
496 //
497 // Description:
498 // The command packet is sent to the drive using 16-bit register writes to
499 // the drive's data register. Data is modified to handle endian-ness before
500 // before it is sent to the drive.
501 //
502 // ALERT!!!: Sending the command packet to the drive using register writes was
503 // due to an assumption that we could not GPIF the middle of an endpoint's
504 // content. From SSW, we can walk down an endpoint's content using GPIF
505 // as long as the transaction count is not exhausted. For optimization,
506 // we may want to GPIF the start of the CBW (maybe send it to the null
507 // register where it won't cause grief), GPIF the scsi command packet
508 // to the drive then discard the rest of the CBW. This would remove the
509 // need to process the command packet for endian-ness.
510 //-----------------------------------------------------------------------------
511 static bit sendSCSICommand(char xdata *cmdbuf)
512 {
513 1
514 1 BYTE driveStatus;
515 1
516 1 prepareForATAPICommand();
517 1
518 1 CLEAR_INTRQ; // Clear the interrupt bit.
519 1
520 1 // Make sure the device is ready for the packet
521 1 while (readATAPI_STATUS_REG() & ATAPI_STATUS_BUSY_BIT)
522 1 ;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?