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