/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.driver.bus.ide.command;
import org.jnode.driver.bus.ide.IDEBus;
import org.jnode.driver.bus.ide.IDECommand;
import org.jnode.driver.bus.ide.IDEDriveDescriptor;
import org.jnode.driver.bus.ide.IDEIO;
import org.jnode.util.NumberUtils;
/**
* @author epr
*/
public class IDEIdCommand extends IDECommand {
/**
* The result of this command
*/
private IDEDriveDescriptor result;
/**
* Should an ATAP ID command be issued(true) or a normal ID command (false)
*/
private final boolean atapiID;
/**
* Read data
*/
private final int[] data = new int[256];
/**
* Did IDENTIFY DEVICE return a packet response signature?
*/
private boolean packetResponse;
/**
* Create a new instance
*
* @param master Command intended for master (true) or slave (false)
* @param atapiID Should an ATAP ID command be issued(true) or a normal ID command (false)
* @throws IllegalArgumentException Invalid argument
*/
public IDEIdCommand(boolean primary, boolean master, boolean atapiID)
throws IllegalArgumentException {
super(primary, master);
this.atapiID = atapiID;
}
/**
* @see org.jnode.driver.bus.ide.IDECommand#setup(IDEBus, IDEIO)
*/
protected void setup(IDEBus ide, IDEIO io) {
final int command = (atapiID ? CMD_PIDENTIFY : CMD_IDENTIFY);
io.setSelectReg(getSelect());
io.setCommandReg(command);
}
/**
* @see org.jnode.driver.bus.ide.IDECommand#handleIRQ(IDEBus, IDEIO)
*/
protected void handleIRQ(IDEBus ide, IDEIO io) {
final int[] data = this.data;
final int state = io.getStatusReg();
if ((state & ST_ERROR) != 0) {
// Error in ID command.
final int error = io.getErrorReg();
if ((error & ERR_ABORT) != 0) {
final int sectCount = io.getSectorCountReg();
final int lbaLow = io.getLbaLowReg();
final int lbaMid = io.getLbaMidReg();
final int lbaHigh = io.getLbaHighReg();
io.getSelectReg();
if ((sectCount == 0x01) && (lbaLow == 0x01) &&
(lbaMid == 0x14) && (lbaHigh == 0xEB)) {
packetResponse = true;
} else {
log.debug("Reponse st=" + NumberUtils.hex(state, 2) +
" lbal=" + NumberUtils.hex(lbaLow, 2) +
" lbam=" + NumberUtils.hex(lbaMid, 2) +
" lbah=" + NumberUtils.hex(lbaHigh, 2) +
" sectc=" + NumberUtils.hex(sectCount, 2));
packetResponse = false;
}
log.debug("Abort " + (packetResponse ? "packet" : "error"));
} else {
log.debug("Error " + NumberUtils.hex(error));
}
result = null;
notifyFinished();
} else if ((state & ST_BUSY) == 0) {
if ((state & ST_DATA_REQUEST) != 0) {
// Data is ready to read
for (int i = 0; i < 256; i++) {
data[i] = io.getDataReg();
}
result = new IDEDriveDescriptor(data, atapiID);
} else {
// Not busy, but still no data ready??? strange
//log.debug("irq:!drq");
result = null;
}
notifyFinished();
} else {
// Controller is still busy, wait for the following IRQ.
log.debug("irq:busy st=" + NumberUtils.hex(state) +
"lbal=" + NumberUtils.hex(io.getLbaLowReg()) +
"lbam=" + NumberUtils.hex(io.getLbaMidReg()) +
"lbah=" + NumberUtils.hex(io.getLbaHighReg()) +
"select=" + NumberUtils.hex(io.getSelectReg()));
}
}
/**
* The result of this command. Only valid when <code>isFinished</code>
* returns <code>true</code>.
*/
public IDEDriveDescriptor getResult() {
return result;
}
/**
* Did IDENTIFY DEVICE return a packet response signature?
*/
public boolean isPacketResponse() {
return packetResponse;
}
}