@@ -136,10 +136,9 @@ PATAChannel::PATAChannel(PCI::Address address, ChannelType type, bool force_pio)
136
136
{
137
137
disable_irq ();
138
138
139
- m_dma_enabled.resource () = true ;
139
+ m_dma_enabled.resource () = !force_pio ;
140
140
ProcFS::add_sys_bool (" ide_dma" , m_dma_enabled);
141
141
142
- m_prdt_page = MM.allocate_supervisor_physical_page ();
143
142
initialize (force_pio);
144
143
detect_disks ();
145
144
disable_irq ();
@@ -157,14 +156,15 @@ void PATAChannel::prepare_for_irq()
157
156
158
157
void PATAChannel::initialize (bool force_pio)
159
158
{
160
-
159
+ PCI::enable_interrupt_line ( pci_address ());
161
160
if (force_pio) {
162
161
klog () << " PATAChannel: Requested to force PIO mode; not setting up DMA" ;
163
162
return ;
164
163
}
164
+
165
165
// Let's try to set up DMA transfers.
166
166
PCI::enable_bus_mastering (pci_address ());
167
- PCI::enable_interrupt_line ( pci_address () );
167
+ m_prdt_page = MM. allocate_supervisor_physical_page ( );
168
168
prdt ().end_of_table = 0x8000 ;
169
169
m_dma_buffer_page = MM.allocate_supervisor_physical_page ();
170
170
klog () << " PATAChannel: Bus master IDE: " << m_bus_master_base;
@@ -402,57 +402,66 @@ bool PATAChannel::ata_write_sectors_with_dma(u32 lba, u16 count, const u8* inbuf
402
402
return true ;
403
403
}
404
404
405
- bool PATAChannel::ata_read_sectors (u32 start_sector , u16 count, u8 * outbuf, bool slave_request)
405
+ bool PATAChannel::ata_read_sectors (u32 lba , u16 count, u8 * outbuf, bool slave_request)
406
406
{
407
407
ASSERT (count <= 256 );
408
408
LOCKER (s_lock ());
409
409
#ifdef PATA_DEBUG
410
- dbg () << " PATAChannel::ata_read_sectors request (" << count << " sector(s) @ " << start_sector << " into " << outbuf << " )" ;
410
+ dbg () << " PATAChannel::ata_read_sectors request (" << count << " sector(s) @ " << lba << " into " << outbuf << " )" ;
411
411
#endif
412
412
413
413
while (m_io_base.offset (ATA_REG_STATUS).in <u8 >() & ATA_SR_BSY)
414
414
;
415
415
416
416
#ifdef PATA_DEBUG
417
- klog () << " PATAChannel: Reading " << count << " sector(s) @ LBA " << start_sector ;
417
+ klog () << " PATAChannel: Reading " << count << " sector(s) @ LBA " << lba ;
418
418
#endif
419
419
420
420
u8 devsel = 0xe0 ;
421
421
if (slave_request)
422
422
devsel |= 0x10 ;
423
423
424
- m_io_base.offset (ATA_REG_SECCOUNT0).out <u8 >(count == 256 ? 0 : LSB (count));
425
- m_io_base.offset (ATA_REG_LBA0).out <u8 >(start_sector & 0xff );
426
- m_io_base.offset (ATA_REG_LBA1).out <u8 >((start_sector >> 8 ) & 0xff );
427
- m_io_base.offset (ATA_REG_LBA2).out <u8 >((start_sector >> 16 ) & 0xff );
428
- m_io_base.offset (ATA_REG_HDDEVSEL).out <u8 >(devsel | ((start_sector >> 24 ) & 0xf ));
424
+ m_control_base.offset (ATA_CTL_CONTROL).out <u8 >(0 );
425
+ m_io_base.offset (ATA_REG_HDDEVSEL).out <u8 >(devsel | (static_cast <u8 >(slave_request) << 4 ) | 0x40 );
426
+ io_delay ();
429
427
430
- IO::out8 (0x3F6 , 0x08 );
431
- while (!(m_io_base.offset (ATA_REG_STATUS).in <u8 >() & ATA_SR_DRDY))
432
- ;
428
+ m_io_base.offset (ATA_REG_FEATURES).out <u8 >(0 );
433
429
434
- prepare_for_irq ();
435
- m_io_base.offset (ATA_REG_COMMAND).out <u8 >(ATA_CMD_READ_PIO);
436
- wait_for_irq ();
430
+ m_io_base.offset (ATA_REG_SECCOUNT0).out <u8 >(0 );
431
+ m_io_base.offset (ATA_REG_LBA0).out <u8 >(0 );
432
+ m_io_base.offset (ATA_REG_LBA1).out <u8 >(0 );
433
+ m_io_base.offset (ATA_REG_LBA2).out <u8 >(0 );
437
434
438
- if (m_device_error)
439
- return false ;
435
+ m_io_base.offset (ATA_REG_SECCOUNT0).out <u8 >(count);
436
+ m_io_base.offset (ATA_REG_LBA0).out <u8 >((lba & 0x000000ff ) >> 0 );
437
+ m_io_base.offset (ATA_REG_LBA1).out <u8 >((lba & 0x0000ff00 ) >> 8 );
438
+ m_io_base.offset (ATA_REG_LBA2).out <u8 >((lba & 0x00ff0000 ) >> 16 );
439
+
440
+ for (;;) {
441
+ auto status = m_io_base.offset (ATA_REG_STATUS).in <u8 >();
442
+ if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY))
443
+ break ;
444
+ }
445
+
446
+ m_io_base.offset (ATA_REG_COMMAND).out <u8 >(ATA_CMD_READ_PIO);
440
447
441
448
for (int i = 0 ; i < count; i++) {
442
- io_delay ();
449
+ prepare_for_irq ();
450
+ wait_for_irq ();
451
+ if (m_device_error)
452
+ return false ;
443
453
444
- while (m_io_base .offset (ATA_REG_STATUS ).in <u8 >() & ATA_SR_BSY)
445
- ;
454
+ u8 status = m_control_base .offset (ATA_CTL_ALTSTATUS ).in <u8 >();
455
+ ASSERT (!(status & ATA_SR_BSY)) ;
446
456
447
- u8 status = m_io_base.offset (ATA_REG_STATUS).in <u8 >();
448
- ASSERT (status & ATA_SR_DRQ);
457
+ auto * buffer = (u16 *)(outbuf + i * 512 );
449
458
#ifdef PATA_DEBUG
450
- dbg () << " PATAChannel: Retrieving 512 bytes (part " << i << " ) (status=" << String::format (" %b" , status) << " ), outbuf=(" << (outbuf + ( 512 * i)) << " )..." ;
459
+ dbg () << " PATAChannel: Retrieving 512 bytes (part " << i << " ) (status=" << String::format (" %b" , status) << " ), outbuf=(" << buffer << " )..." ;
451
460
#endif
452
-
453
- IO::repeated_in16 (m_io_base.offset (ATA_REG_DATA).get (), outbuf + (512 * i), 256 );
461
+ for (int i = 0 ; i < 256 ; i++) {
462
+ buffer[i] = IO::in16 (m_io_base.offset (ATA_REG_DATA).get ());
463
+ }
454
464
}
455
-
456
465
return true ;
457
466
}
458
467
@@ -489,7 +498,7 @@ bool PATAChannel::ata_write_sectors(u32 start_sector, u16 count, const u8* inbuf
489
498
490
499
for (int i = 0 ; i < count; i++) {
491
500
io_delay ();
492
- while (m_io_base.offset (ATA_REG_STATUS).in <u8 >() & ATA_SR_BSY)
501
+ while (( m_io_base.offset (ATA_REG_STATUS).in <u8 >() & ATA_SR_BSY) || !(m_io_base. offset (ATA_REG_STATUS). in < u8 >() & ATA_SR_DRQ) )
493
502
;
494
503
495
504
u8 status = m_io_base.offset (ATA_REG_STATUS).in <u8 >();
@@ -499,7 +508,10 @@ bool PATAChannel::ata_write_sectors(u32 start_sector, u16 count, const u8* inbuf
499
508
dbg () << " PATAChannel: Writing 512 bytes (part " << i << " ) (status=" << String::format (" %b" , status) << " ), inbuf=(" << (inbuf + (512 * i)) << " )..." ;
500
509
#endif
501
510
502
- IO::repeated_out16 (m_io_base.offset (ATA_REG_DATA).get (), inbuf + (512 * i), 256 );
511
+ auto * buffer = (u16 *)(const_cast <u8 *>(inbuf) + i * 512 );
512
+ for (int i = 0 ; i < 256 ; i++) {
513
+ IO::out16 (m_io_base.offset (ATA_REG_DATA).get (), buffer[i]);
514
+ }
503
515
prepare_for_irq ();
504
516
wait_for_irq ();
505
517
status = m_io_base.offset (ATA_REG_STATUS).in <u8 >();
0 commit comments