ide.lst
来自「HIGH_SPEED_USB_To_ATA(IDE)Firmware相关代码(E」· LST 代码 · 共 1,377 行 · 第 1/5 页
LST
1,377 行
252 3 // Page 0x3F, All Pages, is also responded to, I just return the single page 5 though.
253 3 // I do this because page 5 is the only page with significant information anyway, and
254 3 // this simplification reduces the code by eliminating the need to return a number of
255 3 // additional pages (which would change if additional pages are later supported).
256 3 // The supported pages are (see INF-8070_1_3.pdf p37 Table 25):
257 3 // case 0x01: // Read-Write Error Recovery Page
258 3 // case 0x08: // Caching Page
259 3 // case 0x05: // Flexible Disk Page: needed to boot from USB
260 3 // case 0x1B: // Removable Block Access Capabilities Page
261 3 // case 0x3F: // All Pages
262 3
263 3 EP8FIFOBUF[0] = 0x00;
264 3 mymemmovexx(EP8FIFOBUF+1, EP8FIFOBUF, 18-1); // clear buffer - 18 bytes in all responses
265 3
266 3 EP8FIFOBUF[1] = 0x12; // Mode Data length (LSB) in Mode Parameter Header is
267 3 // 8(MPH) + 12(1 page) - 2(offset of 2 byte length field itself)
268 3
269 3 EP8FIFOBUF[8+0] = pagenum; // fill out the page num - fields are all 0x0
270 3 EP8FIFOBUF[8+1] = 0x0A; // set individual Page Length
271 3
272 3 if((pagenum == 0x05) || (pagenum == 0x3F))
273 3 { // Note: a request for All Pages just returns the single page 5 here
274 4 EP8FIFOBUF[8+0] = 0x05;
275 4 if(EZUSB_HIGHSPEED())
276 4 {
277 5 EP8FIFOBUF[8+2] = 0xFF; // HS Transfer Rate (MSB) (field limited to 65Mb/Sec)
278 5 EP8FIFOBUF[8+3] = 0xFF; // HS Transfer Rate (LSB)
279 5 }
280 4 else
281 4 {
282 5 EP8FIFOBUF[8+2] = 0x2E; // FS Transfer Rate (MSB) (12Mb/Sec)
283 5 EP8FIFOBUF[8+3] = 0xE0; // FS Transfer Rate (LSB)
284 5 }
285 4 EP8FIFOBUF[8+4] = NumHeads; // #Heads
286 4 EP8FIFOBUF[8+5] = NumSectPerTrack; // #SectorsPerTrack
287 4 EP8FIFOBUF[8+6] = (ATA_SECTOR_SIZE >> 8) & 0xff; // Data Bytes per sector (truncated)
288 4 EP8FIFOBUF[8+7] = (ATA_SECTOR_SIZE >> 0) & 0xff; // Data Bytes per sector
289 4 EP8FIFOBUF[8+8] = NumCylindersMSB; // #Cyl MSB
290 4 EP8FIFOBUF[8+9] = NumCylindersLSB; // #Cyl LSB
291 4 }
292 3 else if(pagenum == 0x1B)
293 3 {
294 4 EP8FIFOBUF[8+3] = 0x01; // set TLUN = 1 for page 0x1B
295 4 }
C51 COMPILER V7.50 IDE 11/07/2006 14:52:09 PAGE 6
296 3
297 3 packetLen = min(0x12, dataTransferLen);
298 3 if (packetLen)
299 3 {
300 4 EP8BCH = MSB(packetLen);
301 4 EP8BCL = LSB(packetLen);
302 4
303 4 dataTransferLen -= packetLen;
304 4 }
305 3 sensePtr = senseOk;
306 3 return(USBS_PASSED);
307 3 } // end case
308 2
309 2 case MODE_SELECT_06:
310 2 case MODE_SENSE_06:
311 2 case STOP_START_UNIT:
312 2 default:
313 2 {
314 3 // relinquish control of the bulk buffer occupied by the CBW
315 3 EP2BCL = 0x80;
316 3
317 3 sensePtr = senseInvalidFieldInCDB;
318 3 failedIn();
319 3 return(USBS_FAILED);
320 3 }
321 2 }
322 1 }
323
324 bit generalIDEOutCommand()
325 {
326 1 BYTE cmd;
327 1
328 1 cmd = EP2FIFOBUF[0xf];
329 1
330 1 switch (cmd)
331 1 {
332 2 case WRITE_10:
333 2 sensePtr = senseOk;
334 2 checkForMedia();
335 2 if (sensePtr == senseOk)
336 2 return(ideWriteCommand());
337 2 else
338 2 {
339 3 // relinquish control of the bulk buffer occupied by the CBW
340 3 EP2BCL = 0x80;
341 3 if (dataTransferLen)
342 3 stallEP2OUT();
343 3
344 3 return(USBS_FAILED);
345 3 }
346 2
347 2 default:
348 2 // relinquish control of the bulk buffer occupied by the CBW
349 2 EP2BCL = 0x80;
350 2
351 2 if (dataTransferLen)
352 2 stallEP2OUT();
353 2
354 2 return(USBS_FAILED);
355 2 break;
356 2 }
357 1 }
C51 COMPILER V7.50 IDE 11/07/2006 14:52:09 PAGE 7
358
359
360
361 void waitForInBuffer()
362 {
363 1 while((EP8CS & bmEPFULL)); // Wait for an available buffer from the host
364 1
365 1 return;
366 1 }
367
368
369 static bit ideReadCommand(bit verify)
370 {
371 1 BYTE driveStatus;
372 1 WORD sectorcount;
373 1 BYTE i;
374 1 WORD wordCtr;
375 1
376 1 writePIO8(ATA_DRIVESEL_REG, 0xe0);
377 1 if (waitForBusyBit() == USBS_FAILED)
378 1 {
379 2 // Oddly enough, an error bit is okay here. It means that the LAST command failed, not this one.
380 2 // A new command is required to clear many error conditions.
381 2 }
382 1
383 1 ((BYTE *) &dwLBA)[0] = EP2FIFOBUF[CBW_DATA_START+2];
384 1 ((BYTE *) &dwLBA)[1] = EP2FIFOBUF[CBW_DATA_START+3];
385 1 ((BYTE *) &dwLBA)[2] = EP2FIFOBUF[CBW_DATA_START+4];
386 1 ((BYTE *) &dwLBA)[3] = EP2FIFOBUF[CBW_DATA_START+5];
387 1
388 1 // relinquish control of the bulk buffer occupied by the CBW
389 1 EP2BCL = 0x80;
390 1
391 1 // This loop breaks up the 32 bit length into 8 bits * sectors.
392 1 // For example, a read of 0x10000 turns into 0x80 sectors.
393 1 while (dataTransferLen)
394 1 {
395 2 dwLBAtoLBARegs();
396 2
397 2 // First stuff the length register (number of sectors to read)
398 2 if (dataTransferLenMSW & 0xfffe)
399 2 {
400 3 writePIO8(ATA_SECTOR_COUNT_REG, 1); // if (bExtAddrSupport) we need to stuff the MSB
401 3 writePIO8(ATA_SECTOR_COUNT_REG, 0); // 0 means 256 blocks of 512 bytes -- Max drive xfer, max
- TC
402 3 sectorcount = 0x100;
403 3 }
404 2 else
405 2 {
406 3 sectorcount = (dataTransferLenLSW + ATA_SECTOR_SIZE-1)/ATA_SECTOR_SIZE + (dataTransferLenMSW & 1)
- * 0x80;
407 3 writePIO8(ATA_SECTOR_COUNT_REG, 0); // for extended addressing
408 3 writePIO8(ATA_SECTOR_COUNT_REG, sectorcount); // divide len into blocks
409 3 }
410 2
411 2 dwLBA += sectorcount;
412 2
413 2 if (!udmaMode || verify || (dataTransferLenLSW & 0x1ff)) // UDMA cannot handle sub-sector sized r
-eads
414 2 {
415 3 // Execute the read command
416 3 if (bExtAddrSupport)
C51 COMPILER V7.50 IDE 11/07/2006 14:52:09 PAGE 8
417 3 {
418 4 if (verify)
419 4 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_VERIFY_10_EXT);
420 4 else
421 4 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_READ_10_EXT);
422 4 }
423 3 else
424 3 {
425 4 if (verify)
426 4 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_VERIFY_10);
427 4 else
428 4 writePIO8(ATA_COMMAND_REG, ATA_COMMAND_READ_10);
429 4 }
430 3
431 3
432 3 // The verify command reads from the drive, but doesn't transfer data
433 3 // to us.
434 3 if (verify)
435 3 {
436 4 if(waitForBusyBit() == USBS_FAILED)
437 4 return(USBS_FAILED);
438 4 else
439 4 continue;
440 4 }
441 3
442 3 // set up for GPIF transfer - wordwide
443 3 //EP8GPIFTCH = MSB(wPacketSize >> 1);
444 3 //EP8GPIFTCL = LSB(wPacketSize >> 1);
445 3
446 3 while (sectorcount--)
447 3 {
448 4 // Wait for the drive to be non-busy and have either data or an error
449 4 while (1)
450 4 {
451 5 driveStatus = readATAPI_STATUS_REG();
452 5 if ((driveStatus & (ATAPI_STATUS_BUSY_BIT | ATAPI_STATUS_DRQ_BIT)) == ATAPI_STATUS_DRQ_BIT)
453 5 break;
454 5 if (driveStatus & (ATAPI_STATUS_BUSY_BIT | ATAPI_STATUS_ERROR_BIT) == ATAPI_STATUS_ERROR_BI
-T)
455 5 break;
456 5 }
457 4
458 4 // If there's an error, the drive may still want to send us the data.
459 4 if (driveStatus & ATAPI_STATUS_ERROR_BIT)
460 4 {
461 5 readPIO8(ATAPI_ERROR_REG);
462 5 if (driveStatus & ATAPI_STATUS_DRQ_BIT)
463 5 for (wordCtr = 0; wordCtr < 0x100; wordCtr++)
464 5 readPIO8(ATAPI_DATA_REG);
465 5 failedIn();
466 5 return(USBS_FAILED);
467 5 }
468 4 else
469 4 {
470 5 BYTE bLimit;
471 5 WORD wThisPacketSize;
472 5
473 5 if (wPacketSize == 0x40)
474 5 bLimit = 8;
475 5 else
476 5 bLimit = 1;
477 5 for (i = 0; i < bLimit && dataTransferLen; i++)
C51 COMPILER V7.50 IDE 11/07/2006 14:52:09 PAGE 9
478 5 {
479 6 waitForInBuffer();
480 6
481 6 wThisPacketSize = min(wPacketSize, dataTransferLen);
482 6 readPIO16(ATAPI_DATA_REG, wThisPacketSize+1);
483 6 while (!gpifIdle()) // Wait for xfer to complete
484 6 ;
485 6 EP8BCH = MSB(wThisPacketSize);
486 6 EP8BCL = LSB(wThisPacketSize);
487 6 dataTransferLen -= wThisPacketSize;
488 6 }
489 5 }
490 4 }//while (sectorcount--)
491 3 }
492 2 else // transfer is udma mode
493 2 {
494 3 initUdmaRead();
495 3 if (bExtAddrSupport)
496 3 writePIO8(ATAPI_COMMAND_REG, ATA_COMMAND_DMAREAD_RETRY_EXT);
497 3 else
498 3 writePIO8(ATAPI_COMMAND_REG, ATA_COMMAND_DMAREAD_RETRY);
499 3 readUDMA((DWORD) sectorcount << 8); // Words = sectors * 256
500 3 driveStatus = readATAPI_STATUS_REG();
501 3 if (driveStatus & ATAPI_STATUS_ERROR_BIT)
502 3 {
503 4 if (readPIO8(ATAPI_ERROR_REG) & ATAPI_ERROR_ICRC_BIT)
504 4 {
505 5 sensePtr = senseCRCError;
506 5 }
507 4 // No need to do failedIn() -- All data is already xferred.
508 4 return(USBS_FAILED);
509 4 }
510 3
511 3 // Two choices -- Either we're limited to 0x100 sectors, or limited to dataTransferLen.
512 3 // BUGBUG -- No capability here to report Hi > Di.
513 3 if (sectorcount == 0x100)
514 3 dataTransferLenMSW -= 2;
515 3 else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?