From: <ls...@us...> - 2011-07-25 07:57:32
|
Revision: 5837 http://jnode.svn.sourceforge.net/jnode/?rev=5837&view=rev Author: lsantha Date: 2011-07-25 07:57:25 +0000 (Mon, 25 Jul 2011) Log Message: ----------- Patch contributed by griff with the following comments: The patch implements: 48 bit ide lba addresses. 28 bit lba addresses were implemented but 48 bit was not and it is required for larger disks (> 137G) . Extended partition tables were mostly there and just needed fixing. Fixed an exception that sometimes caused the cd to fail to load while booting from the cd. The cause was that read atapi commands did not deal with padding. Modified Paths: -------------- trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEBus.java trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEConstants.java trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDriveDescriptor.java trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDERWSectorsCommand.java trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEReadSectorsCommand.java trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEWriteSectorsCommand.java trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java Modified: trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -49,6 +49,7 @@ import org.jnode.driver.bus.ide.IDEDeviceFactory; import org.jnode.driver.bus.ide.IDEDriveDescriptor; import org.jnode.driver.bus.ide.IDEDriverUtils; +import org.jnode.driver.bus.ide.command.IDERWSectorsCommand; import org.jnode.driver.bus.ide.command.IDEReadSectorsCommand; import org.jnode.driver.bus.ide.command.IDEWriteSectorsCommand; import org.jnode.naming.InitialNaming; @@ -83,7 +84,7 @@ /** * Support 48-bit addressing? */ - private boolean s48bit; + private boolean is48bit; private IDEDiskBus diskBus; private IBMPartitionTable pt; @@ -97,12 +98,8 @@ final IDEDriveDescriptor descr = dev.getDescriptor(); //lba = descr.supportsLBA(); //dma = descr.supportsDMA(); - s48bit = descr.supports48bitAddressing(); - if (s48bit) { - maxSector = descr.getSectorsIn48bitAddressing(); - } else { - maxSector = descr.getSectorsIn28bitAddressing(); - } + is48bit = descr.supports48bitAddressing(); + maxSector = descr.getSectorsAddressable(); // Look for partitions try { @@ -126,17 +123,16 @@ if (pte == null) { BootLogInstance.get().warn("PartitionTableEntry #" + i + " is null"); } else if (pte.isValid()) { - if (pte.isExtended()) { - // Create partition devices for the extended partition - partIndex = registerExtendedPartition(devMan, dev, partIndex); - } else { - // Create a partition device. - registerPartition(devMan, dev, pte, partIndex); - } + registerPartition(devMan, dev, pte, partIndex); } partIndex++; i++; } + if (!pt.getExtendedPartitions().isEmpty()) { + // Create partition devices for the extended partition + log.debug("Extended"); + partIndex = registerExtendedPartition(devMan, dev, partIndex); + } } catch (DeviceAlreadyRegisteredException ex) { throw new DriverException("Partition device is already known???? Probably a bug", ex); } catch (IOException ex) { @@ -184,87 +180,66 @@ } public void read(long devOffset, ByteBuffer destBuf) throws IOException { - int destOffset = 0; - int length = destBuf.remaining(); + transfer(devOffset, destBuf, false); + } + public void write(long devOffset, ByteBuffer srcBuf) throws IOException { + transfer(devOffset, srcBuf, true); + } + + protected void transfer(long devOffset, ByteBuffer buf, boolean isWrite) throws IOException { +// int bufOffset = 0; + int length = buf.remaining(); + BlockDeviceAPIHelper.checkBounds(this, devOffset, length); BlockDeviceAPIHelper.checkAlignment(SECTOR_SIZE, this, devOffset, length); final long lbaStart = devOffset / SECTOR_SIZE; final int sectors = length / SECTOR_SIZE; + final String errorSource = isWrite ? "write" : "read"; if (lbaStart + sectors > this.maxSector) { - throw new IOException("read beyond device sectors"); + throw new IOException(errorSource + " beyond device sectors"); } final IDEDevice dev = (IDEDevice) getDevice(); final IDEBus bus = (IDEBus) dev.getBus(); + final int maxSectorCount = is48bit ? MAX_SECTOR_COUNT_48 : MAX_SECTOR_COUNT_28; while (length > 0) { final long partLbaStart = devOffset / SECTOR_SIZE; - final int partSectors = Math.min(length / SECTOR_SIZE, 256); + final int partSectors = Math.min(length / SECTOR_SIZE, maxSectorCount); final int partLength = partSectors * SECTOR_SIZE; - final IDEReadSectorsCommand cmd; - cmd = new IDEReadSectorsCommand(dev.isPrimary(), dev.isMaster(), partLbaStart, partSectors, destBuf); + final IDERWSectorsCommand cmd = isWrite ? new IDEWriteSectorsCommand( + dev.isPrimary(), + dev.isMaster(), + is48bit, + partLbaStart, + partSectors, + buf) : new IDEReadSectorsCommand( + dev.isPrimary(), + dev.isMaster(), + is48bit, + partLbaStart, + partSectors, + buf); try { bus.executeAndWait(cmd, IDE_DATA_XFER_TIMEOUT); } catch (InterruptedException ex) { - final IOException ioe = new IOException("IDE read interrupted"); - ioe.initCause(ex); - throw ioe; + throw new IOException("IDE " + errorSource + " interrupted", ex); } catch (TimeoutException ex) { throw new InterruptedIOException("IDE timeout: " + ex.getMessage()); } if (cmd.hasError()) { - throw new IOException("IDE read error:" + cmd.getError()); + throw new IOException("IDE " + errorSource + " error:" + cmd.getError()); } length -= partLength; - destOffset += partLength; devOffset += partLength; } } - public void write(long devOffset, ByteBuffer srcBuf) throws IOException { - int srcOffset = 0; - int length = srcBuf.remaining(); - - BlockDeviceAPIHelper.checkBounds(this, devOffset, length); - BlockDeviceAPIHelper.checkAlignment(SECTOR_SIZE, this, devOffset, length); - final long lbaStart = devOffset / SECTOR_SIZE; - final int sectors = length / SECTOR_SIZE; - - if (lbaStart + sectors > this.maxSector) { - throw new IOException("write beyond device sectors"); - } - - final IDEDevice dev = (IDEDevice) getDevice(); - final IDEBus bus = (IDEBus) dev.getBus(); - final IDEWriteSectorsCommand cmd; - cmd = - new IDEWriteSectorsCommand( - dev.isPrimary(), - dev.isMaster(), - lbaStart, - sectors, - srcBuf, - srcOffset, - length); - try { - bus.executeAndWait(cmd, IDE_DATA_XFER_TIMEOUT); - } catch (InterruptedException ex) { - final IOException ioe = new IOException("IDE write interrupted"); - ioe.initCause(ex); - throw ioe; - } catch (TimeoutException ex) { - throw new InterruptedIOException("IDE timeout: " + ex.getMessage()); - } - if (cmd.hasError()) { - throw new IOException("IDE write error:" + cmd.getError()); - } - } - static class IDEDiskBus extends Bus { public IDEDiskBus(IDEDevice parent) { Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEBus.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEBus.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEBus.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -328,12 +328,18 @@ * @param length */ public final void readData(byte[] dst, int ofs, int length) { + final int srcLen = dst.length - ofs; + int len = Math.min(length, srcLen); //waitUntilNotBusy(); - for (; length > 0; length -= 2) { + for (; len > 0; len -= 2, length -= 2) { final int v = io.getDataReg(); dst[ofs++] = (byte) (v & 0xFF); dst[ofs++] = (byte) ((v >> 8) & 0xFF); } + // Recieve padding + for (; length > 0; length -= 2) { + io.getDataReg(); + } } /** Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEConstants.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEConstants.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEConstants.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -192,6 +192,32 @@ public static final long IDE_DATA_XFER_TIMEOUT = 10000; /* ms */ // -------------------------------- + // IDE sector maximum addresses + + /** + * Maximum sector for 28 bit addresses + */ + public static final int MAX_SECTOR_COUNT_28 = 256; + + /** + * Maximum sector for 48 bit addresses + */ + public static final int MAX_SECTOR_COUNT_48 = 65536; + + // -------------------------------- + // IDE sector maximum addresses + + /** + * Maximum sector for 28 bit addresses + */ + public static final long MAX_SECTOR_28 = 0xfffffffL; + + /** + * Maximum sector for 48 bit addresses + */ + public static final long MAX_SECTOR_48 = 0xfffffffffffffL; + + // -------------------------------- // ATA/ATAPI Commands pre T13 Spec public static final int CMD_NOP = 0x00; public static final int CFA_REQ_EXT_ERROR_CODE = 0x03; /* CFA Request Extended Error Code */ Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDriveDescriptor.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDriveDescriptor.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDriveDescriptor.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -193,15 +193,22 @@ * @return True if this device supports 48-bit addressing, false otherwise */ public boolean supports48bitAddressing() { - return ((data[83] & 0x40) != 0); + return ((data[83] & 0x400) != 0); } /** + * Gets the number of addressable sectors + */ + public long getSectorsAddressable() { + return supports48bitAddressing() ? getSectorsIn48bitAddressing() : getSectorsIn28bitAddressing(); + } + + /** * Gets the number of addressable sectors in 28-addressing. * * @return the number of addressable sectors */ - public long getSectorsIn28bitAddressing() { + private long getSectorsIn28bitAddressing() { final long h = data[61]; final long l = data[60]; return ((h << 16) & 0xFFFF0000) | (l & 0xFFFF); @@ -212,12 +219,11 @@ * * @return the number of addressable sectors */ - public long getSectorsIn48bitAddressing() { + private long getSectorsIn48bitAddressing() { final long v3 = data[103] & 0xFFFF; final long v2 = data[102] & 0xFFFF; final long v1 = data[101] & 0xFFFF; final long v0 = data[100] & 0xFFFF; - return (v3 << 48) | (v2 << 16) | (v1 << 16) | v0; + return (v3 << 48) | (v2 << 32) | (v1 << 16) | v0; } - } Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDERWSectorsCommand.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDERWSectorsCommand.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDERWSectorsCommand.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -33,43 +33,69 @@ public abstract class IDERWSectorsCommand extends IDECommand { protected final long lbaStart; protected final int sectors; + protected final boolean is48bit; public IDERWSectorsCommand( boolean primary, boolean master, + boolean is48bit, long lbaStart, int sectors) { super(primary, master); + this.is48bit = is48bit; this.lbaStart = lbaStart; this.sectors = sectors; - if ((sectors < 1) || (sectors > 256)) { - throw new IllegalArgumentException("Sectors must be between 1 and 256, not " + sectors); + if (lbaStart < 0L) { + throw new IllegalArgumentException(String.format("LBA must be between 0 and {0}, not {1}", maxSector() - 1, + lbaStart)); } + if ((sectors < 1) || (sectors > maxSectorCount())) { + throw new IllegalArgumentException(String.format("Sectors must be between 1 and {0}, not {1}", + maxSectorCount(), sectors)); + } + if ((lbaStart + sectors) >= maxSector()) { + throw new IllegalArgumentException(String.format("The maximum sector must be between 0 and {0}, not {1}", + maxSector(), lbaStart + sectors)); + } } + protected long maxSector() { + return is48bit ? MAX_SECTOR_48 : MAX_SECTOR_28; + } + + protected int maxSectorCount() { + return is48bit ? MAX_SECTOR_COUNT_48 : MAX_SECTOR_COUNT_28; + } + protected void setup(IDEBus ide, IDEIO io) throws TimeoutException { - final int select; - final int sectors; - final int lbaLow = (int) (lbaStart & 0xFF); - final int lbaMid = (int) ((lbaStart >> 8) & 0xFF); - final int lbaHigh = (int) ((lbaStart >> 16) & 0xFF); - final int lbaRem = (int) ((lbaStart >> 24) & 0x0F); - if (master) { - select = lbaRem | SEL_BLANK | SEL_LBA | SEL_DRIVE_MASTER; - } else { - select = lbaRem | SEL_BLANK | SEL_LBA | SEL_DRIVE_SLAVE; + int select = SEL_LBA | getSelect(); + + final int scCurrent = sectors & 0xFF; + final int lbaLowCurrent = (int) (lbaStart & 0xFF); + final int lbaMidCurrent = (int) ((lbaStart >> 8) & 0xFF); + final int lbaHighCurrent = (int) ((lbaStart >> 16) & 0xFF); + + io.waitUntilNotBusy(IDE_TIMEOUT); + if (is48bit) { + final int scPrevious = (sectors & 0xFF00) >> 8; + final int lbaLowPrevious = (int) ((lbaStart >> 24) & 0xFF); + final int lbaMidPrevious = (int) ((lbaStart >> 32) & 0xFF); + final int lbaHighPrevious = (int) ((lbaStart >> 40) & 0xFF); + + io.setSectorCountReg(scPrevious); + io.setLbaLowReg(lbaLowPrevious); + io.setLbaMidReg(lbaMidPrevious); + io.setLbaHighReg(lbaHighPrevious); } - if (this.sectors == 256) { - sectors = 0; - } else { - sectors = this.sectors; + io.setSectorCountReg(scCurrent); + io.setLbaLowReg(lbaLowCurrent); + io.setLbaMidReg(lbaMidCurrent); + io.setLbaHighReg(lbaHighCurrent); + if (!is48bit) { + final int lbaRem = (int) ((lbaStart >> 24) & 0xF); + + select |= lbaRem; } - - io.setSectorCountReg(sectors); - io.setLbaLowReg(lbaLow); - io.setLbaMidReg(lbaMid); - io.setLbaHighReg(lbaHigh); io.setSelectReg(select); - } } Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEReadSectorsCommand.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEReadSectorsCommand.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEReadSectorsCommand.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -32,10 +32,16 @@ public class IDEReadSectorsCommand extends IDERWSectorsCommand { private final ByteBuffer buf; - private int readSectors; + private int readSectors = 0; - public IDEReadSectorsCommand(boolean primary, boolean master, long lbaStart, int sectors, ByteBuffer dest) { - super(primary, master, lbaStart, sectors); + public IDEReadSectorsCommand( + boolean primary, + boolean master, + boolean is48bit, + long lbaStart, + int sectors, + ByteBuffer dest) { + super(primary, master, is48bit, lbaStart, sectors); buf = dest; } @@ -44,7 +50,7 @@ */ protected void setup(IDEBus ide, IDEIO io) throws TimeoutException { super.setup(ide, io); - io.setCommandReg(CMD_READ); + io.setCommandReg(is48bit ? CMD_READ_EXT : CMD_READ); } /** Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEWriteSectorsCommand.java =================================================================== --- trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEWriteSectorsCommand.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/driver/org/jnode/driver/bus/ide/command/IDEWriteSectorsCommand.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -34,25 +34,18 @@ public class IDEWriteSectorsCommand extends IDERWSectorsCommand { private final ByteBuffer buf; - private final int offset; - private final int length; - private int currentPosition; - //private int readSectors; + private int readSectors = 0; public IDEWriteSectorsCommand( boolean primary, boolean master, + boolean is48bit, long lbaStart, int sectors, - ByteBuffer src, - int srcOffset, - int length) { - super(primary, master, lbaStart, sectors); + ByteBuffer src) { + super(primary, master, is48bit, lbaStart, sectors); this.buf = src; - this.offset = srcOffset; - this.currentPosition = srcOffset; - this.length = length; } /** @@ -61,17 +54,18 @@ protected void setup(IDEBus ide, IDEIO io) throws TimeoutException { super.setup(ide, io); - io.setCommandReg(CMD_WRITE); - transfertASector(ide, io); + io.setCommandReg(is48bit ? CMD_WRITE_EXT : CMD_WRITE); + io.waitUntilNotBusy(IDE_TIMEOUT); + transferASector(ide, io); } - private void transfertASector(IDEBus ide, IDEIO io) throws TimeoutException { - io.waitUntilNotBusy(IDE_TIMEOUT); + private void transferASector(IDEBus ide, IDEIO io) throws TimeoutException { +// io.waitUntilNotBusy(IDE_TIMEOUT); for (int i = 0; i < 256; i++) { int v = ((buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8)); io.setDataReg(v); - currentPosition += 2; } + readSectors++; } /** @@ -83,8 +77,8 @@ setError(io.getErrorReg()); } else { if ((state & (ST_BUSY | ST_DEVICE_READY)) == ST_DEVICE_READY) { - if (currentPosition < offset + length) { - transfertASector(ide, io); + if (readSectors < sectors) { + transferASector(ide, io); } else { notifyFinished(); } Modified: trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java 2011-07-15 19:52:00 UTC (rev 5836) +++ trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java 2011-07-25 07:57:25 UTC (rev 5837) @@ -166,7 +166,7 @@ int sectorSize = IDEConstants.SECTOR_SIZE; if (ideDev != null) { out.println("IDE Disk : " + ideDev.getId() + ": " + - descriptor.getSectorsIn28bitAddressing() * 512 + " bytes"); + descriptor.getSectorsAddressable() * 512 + " bytes"); } out.println("Device Boot Start End Blocks System"); IBMPartitionTable partitionTable = helper.getPartitionTable(); @@ -206,7 +206,7 @@ IDEDriveDescriptor desc = ideDevice.getDescriptor(); if (desc.isDisk()) { out.println(" IDE Disk : " + ideDevice.getId() + "(" + desc.getModel() + - " " + desc.getSectorsIn28bitAddressing() * IDEConstants.SECTOR_SIZE + + " " + desc.getSectorsAddressable() * IDEConstants.SECTOR_SIZE + ")"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |