LBA step
This commit is contained in:
parent
fe910fadcf
commit
1732526c50
1 changed files with 139 additions and 64 deletions
|
@ -26,8 +26,11 @@
|
|||
/* I/O Ports used by winchester disk controllers. */
|
||||
|
||||
/* Read and write registers */
|
||||
#define REG_BASE0 0x1F0 /* base register of controller 0 */
|
||||
#define REG_BASE1 0x170 /* base register of controller 1 */
|
||||
#define REG_CMD_BASE0 0x1F0 /* command base register of controller 0 */
|
||||
#define REG_CMD_BASE1 0x170 /* command base register of controller 1 */
|
||||
#define REG_CTL_BASE0 0x3F6 /* control base register of controller 0 */
|
||||
#define REG_CTL_BASE1 0x376 /* control base register of controller 1 */
|
||||
|
||||
#define REG_DATA 0 /* data register (offset from the base reg.) */
|
||||
#define REG_PRECOMP 1 /* start of write precompensation */
|
||||
#define REG_COUNT 2 /* sectors to transfer */
|
||||
|
@ -63,14 +66,17 @@
|
|||
#define CMD_IDLE 0x00 /* for w_command: drive idle */
|
||||
#define CMD_RECALIBRATE 0x10 /* recalibrate drive */
|
||||
#define CMD_READ 0x20 /* read data */
|
||||
#define CMD_READ_EXT 0x24 /* read data (LBA48 addressed) */
|
||||
#define CMD_WRITE 0x30 /* write data */
|
||||
#define CMD_WRITE_EXT 0x34 /* write data (LBA48 addressed) */
|
||||
#define CMD_READVERIFY 0x40 /* read verify */
|
||||
#define CMD_FORMAT 0x50 /* format track */
|
||||
#define CMD_SEEK 0x70 /* seek cylinder */
|
||||
#define CMD_DIAG 0x90 /* execute device diagnostics */
|
||||
#define CMD_SPECIFY 0x91 /* specify parameters */
|
||||
#define ATA_IDENTIFY 0xEC /* identify drive */
|
||||
#define REG_CTL 0x206 /* control register */
|
||||
/* #define REG_CTL 0x206 */ /* control register */
|
||||
#define REG_CTL 0 /* control register */
|
||||
#define CTL_NORETRY 0x80 /* disable access retry */
|
||||
#define CTL_NOECC 0x40 /* disable ecc retry */
|
||||
#define CTL_EIGHTHEADS 0x08 /* more than eight heads */
|
||||
|
@ -172,7 +178,7 @@ struct command {
|
|||
/* Timeouts and max retries. */
|
||||
int timeout_ticks = DEF_TIMEOUT_TICKS, max_errors = MAX_ERRORS;
|
||||
int wakeup_ticks = WAKEUP;
|
||||
long w_standard_timeouts = 0, w_pci_debug = 0, w_instance = 0;
|
||||
long w_standard_timeouts = 0, w_pci_debug = 0, w_instance = 0, w_lba48 = 0;
|
||||
|
||||
int w_testing = 0, w_silent = 0;
|
||||
|
||||
|
@ -187,11 +193,13 @@ int w_next_drive = 0;
|
|||
PRIVATE struct wini { /* main drive struct, one entry per drive */
|
||||
unsigned state; /* drive state: deaf, initialized, dead */
|
||||
unsigned w_status; /* device status register */
|
||||
unsigned base; /* base register of the register file */
|
||||
unsigned base_cmd; /* command base register */
|
||||
unsigned base_ctl; /* control base register */
|
||||
unsigned irq; /* interrupt request line */
|
||||
unsigned irq_mask; /* 1 << irq */
|
||||
unsigned irq_need_ack; /* irq needs to be acknowledged */
|
||||
int irq_hook_id; /* id of irq hook at the kernel */
|
||||
int lba48; /* supports lba48 */
|
||||
unsigned lcylinders; /* logical number of cylinders (BIOS) */
|
||||
unsigned lheads; /* logical number of heads */
|
||||
unsigned lsectors; /* logical number of sectors per track */
|
||||
|
@ -219,7 +227,7 @@ PRIVATE int w_controller; /* selected controller */
|
|||
PRIVATE struct device *w_dv; /* device's base and size */
|
||||
|
||||
FORWARD _PROTOTYPE( void init_params, (void) );
|
||||
FORWARD _PROTOTYPE( void init_drive, (struct wini *, int, int, int, int, int));
|
||||
FORWARD _PROTOTYPE( void init_drive, (struct wini *, int, int, int, int, int, int));
|
||||
FORWARD _PROTOTYPE( void init_params_pci, (int) );
|
||||
FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( struct device *w_prepare, (int dev) );
|
||||
|
@ -298,6 +306,7 @@ PRIVATE void init_params()
|
|||
env_parse("ata_std_timeout", "d", 0, &w_standard_timeouts, 0, 1);
|
||||
env_parse("ata_pci_debug", "d", 0, &w_pci_debug, 0, 1);
|
||||
env_parse("ata_instance", "d", 0, &w_instance, 0, 8);
|
||||
env_parse("ata_lba48", "d", 0, &w_lba48, 0, 1);
|
||||
|
||||
if(w_instance == 0) {
|
||||
/* Get the number of drives from the BIOS data area */
|
||||
|
@ -329,7 +338,10 @@ PRIVATE void init_params()
|
|||
}
|
||||
|
||||
/* Fill in non-BIOS parameters. */
|
||||
init_drive(wn, drive < 2 ? REG_BASE0 : REG_BASE1, NO_IRQ, 0, 0, drive);
|
||||
init_drive(wn,
|
||||
drive < 2 ? REG_CMD_BASE0 : REG_CMD_BASE1,
|
||||
drive < 2 ? REG_CTL_BASE0 : REG_CTL_BASE1,
|
||||
NO_IRQ, 0, 0, drive);
|
||||
w_next_drive++;
|
||||
}
|
||||
}
|
||||
|
@ -350,17 +362,19 @@ PRIVATE void init_params()
|
|||
/*============================================================================*
|
||||
* init_drive *
|
||||
*============================================================================*/
|
||||
PRIVATE void init_drive(struct wini *w, int base, int irq, int ack, int hook, int drive)
|
||||
PRIVATE void init_drive(struct wini *w, int base_cmd, int base_ctl, int irq, int ack, int hook, int drive)
|
||||
{
|
||||
w->state = 0;
|
||||
w->w_status = 0;
|
||||
w->base = base;
|
||||
w->base_cmd = base_cmd;
|
||||
w->base_ctl = base_ctl;
|
||||
w->irq = irq;
|
||||
w->irq_mask = 1 << irq;
|
||||
w->irq_need_ack = ack;
|
||||
w->irq_hook_id = hook;
|
||||
w->ldhpref = ldh_init(drive);
|
||||
w->max_count = MAX_SECS << SECTOR_SHIFT;
|
||||
w->lba48 = 0;
|
||||
}
|
||||
|
||||
/*============================================================================*
|
||||
|
@ -416,26 +430,32 @@ PRIVATE void init_params_pci(int skip)
|
|||
|
||||
/* Primary channel not in compatability mode? */
|
||||
if(interface & ATA_IF_NOTCOMPAT1) {
|
||||
u32_t base;
|
||||
base = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
|
||||
if(base != REG_BASE0 && base != REG_BASE1) {
|
||||
init_drive(&wini[w_next_drive], base, irq, 1, irq_hook, 0);
|
||||
init_drive(&wini[w_next_drive+1], base, irq, 1, irq_hook, 1);
|
||||
if(w_pci_debug)
|
||||
printf("atapci %d: 0x%x irq %d\n", devind, base, irq);
|
||||
} else printf("atapci: ignored drives on primary channel, base %x\n", base);
|
||||
u32_t base_cmd, base_ctl;
|
||||
base_cmd = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
|
||||
base_ctl = pci_attr_r32(devind, PCI_BAR_2) & 0xffffffe0;
|
||||
if(base_cmd != REG_CMD_BASE0 && base_cmd != REG_CMD_BASE1) {
|
||||
init_drive(&wini[w_next_drive],
|
||||
base_cmd, base_ctl, irq, 1, irq_hook, 0);
|
||||
init_drive(&wini[w_next_drive+1],
|
||||
base_cmd, base_ctl, irq, 1, irq_hook, 1);
|
||||
if(w_pci_debug || 1)
|
||||
printf("atapci %d: 0x%x 0x%x irq %d\n", devind, base_cmd, base_ctl, irq);
|
||||
} else printf("atapci: ignored drives on primary channel, base %x\n", base_cmd);
|
||||
}
|
||||
|
||||
/* Secondary channel not in compatability mode? */
|
||||
if(interface & ATA_IF_NOTCOMPAT2) {
|
||||
u32_t base;
|
||||
base = pci_attr_r32(devind, PCI_BAR_3) & 0xffffffe0;
|
||||
if(base != REG_BASE0 && base != REG_BASE1) {
|
||||
init_drive(&wini[w_next_drive+2], base, irq, 1, irq_hook, 2);
|
||||
init_drive(&wini[w_next_drive+3], base, irq, 1, irq_hook, 3);
|
||||
if(w_pci_debug)
|
||||
printf("atapci %d: 0x%x irq %d\n", devind, base, irq);
|
||||
} else printf("atapci: ignored drives on secondary channel, base %x\n", base);
|
||||
u32_t base_cmd, base_ctl;
|
||||
base_cmd = pci_attr_r32(devind, PCI_BAR_3) & 0xffffffe0;
|
||||
base_ctl = pci_attr_r32(devind, PCI_BAR_4) & 0xffffffe0;
|
||||
if(base_cmd != REG_CMD_BASE0 && base_cmd != REG_CMD_BASE1) {
|
||||
init_drive(&wini[w_next_drive+2],
|
||||
base_cmd, base_ctl, irq, 1, irq_hook, 2);
|
||||
init_drive(&wini[w_next_drive+3],
|
||||
base_cmd, base_ctl, irq, 1, irq_hook, 3);
|
||||
if(w_pci_debug || 1)
|
||||
printf("atapci %d: 0x%x 0x%x irq %d\n", devind, base_cmd, base_ctl, irq);
|
||||
} else printf("atapci: ignored drives on secondary channel, base %x\n", base_cmd);
|
||||
}
|
||||
w_next_drive += 4;
|
||||
}
|
||||
|
@ -570,7 +590,7 @@ PRIVATE int w_identify()
|
|||
wn->state |= SMART;
|
||||
|
||||
/* Device information. */
|
||||
if ((s=sys_insw(wn->base + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
|
||||
/* Why are the strings byte swapped??? */
|
||||
|
@ -588,6 +608,23 @@ PRIVATE int w_identify()
|
|||
*/
|
||||
wn->ldhpref |= LDH_LBA;
|
||||
size = id_longword(60);
|
||||
|
||||
if(w_lba48 && ((id_word(83)) & (1L << 10))) {
|
||||
/* Drive is LBA48 capable (and LBA48 is turned on). */
|
||||
if(id_word(102) || id_word(103)) {
|
||||
/* If no. of sectors doesn't fit in 32 bits,
|
||||
* trunacte to this. So it's LBA32 for now.
|
||||
* This can still address devices up to 2TB
|
||||
* though.
|
||||
*/
|
||||
size = ULONG_MAX;
|
||||
} else {
|
||||
/* Actual number of sectors fits in 32 bits. */
|
||||
size = id_longword(100);
|
||||
}
|
||||
|
||||
wn->lba48 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wn->lcylinders == 0) {
|
||||
|
@ -607,7 +644,7 @@ PRIVATE int w_identify()
|
|||
wn->state |= ATAPI;
|
||||
|
||||
/* Device information. */
|
||||
if ((s=sys_insw(wn->base + REG_DATA, SELF, tmp_buf, 512)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, 512)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
|
||||
/* Why are the strings byte swapped??? */
|
||||
|
@ -764,6 +801,40 @@ PRIVATE int w_specify()
|
|||
return(OK);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_transfer *
|
||||
*===========================================================================*/
|
||||
PRIVATE int do_transfer(struct wini *wn, unsigned int precomp, unsigned int count,
|
||||
unsigned int sector, unsigned int opcode)
|
||||
{
|
||||
struct command cmd;
|
||||
unsigned secspcyl = wn->pheads * wn->psectors;
|
||||
|
||||
cmd.precomp = precomp;
|
||||
cmd.count = count;
|
||||
cmd.command = opcode == DEV_SCATTER ? CMD_WRITE : CMD_READ;
|
||||
/*
|
||||
if (w_lba48 && wn->lba48) {
|
||||
} else */
|
||||
if (wn->ldhpref & LDH_LBA) {
|
||||
cmd.sector = (sector >> 0) & 0xFF;
|
||||
cmd.cyl_lo = (sector >> 8) & 0xFF;
|
||||
cmd.cyl_hi = (sector >> 16) & 0xFF;
|
||||
cmd.ldh = wn->ldhpref | ((sector >> 24) & 0xF);
|
||||
} else {
|
||||
int cylinder, head, sec;
|
||||
cylinder = sector / secspcyl;
|
||||
head = (sector % secspcyl) / wn->psectors;
|
||||
sec = sector % wn->psectors;
|
||||
cmd.sector = sec + 1;
|
||||
cmd.cyl_lo = cylinder & BYTE;
|
||||
cmd.cyl_hi = (cylinder >> 8) & BYTE;
|
||||
cmd.ldh = wn->ldhpref | head;
|
||||
}
|
||||
|
||||
return com_out(&cmd);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* w_transfer *
|
||||
*===========================================================================*/
|
||||
|
@ -779,9 +850,7 @@ unsigned nr_req; /* length of request vector */
|
|||
int r, s, errors;
|
||||
unsigned long block;
|
||||
unsigned long dv_size = cv64ul(w_dv->dv_size);
|
||||
struct command cmd;
|
||||
unsigned cylinder, head, sector, nbytes;
|
||||
unsigned secspcyl = wn->pheads * wn->psectors;
|
||||
|
||||
#if ENABLE_ATAPI
|
||||
if (w_wn->state & ATAPI) {
|
||||
|
@ -816,6 +885,10 @@ unsigned nr_req; /* length of request vector */
|
|||
if (!(wn->state & INITIALIZED) && w_specify() != OK) return(EIO);
|
||||
|
||||
/* Tell the controller to transfer nbytes bytes. */
|
||||
#if 1
|
||||
r = do_transfer(wn, wn->precomp, ((nbytes >> SECTOR_SHIFT) & BYTE),
|
||||
block, opcode);
|
||||
#else
|
||||
cmd.precomp = wn->precomp;
|
||||
cmd.count = (nbytes >> SECTOR_SHIFT) & BYTE;
|
||||
if (wn->ldhpref & LDH_LBA) {
|
||||
|
@ -835,6 +908,7 @@ unsigned nr_req; /* length of request vector */
|
|||
cmd.command = opcode == DEV_SCATTER ? CMD_WRITE : CMD_READ;
|
||||
|
||||
r = com_out(&cmd);
|
||||
#endif
|
||||
|
||||
while (r == OK && nbytes > 0) {
|
||||
/* For each sector, wait for an interrupt and fetch the data
|
||||
|
@ -847,7 +921,7 @@ unsigned nr_req; /* length of request vector */
|
|||
if ((r = at_intr_wait()) != OK) {
|
||||
/* An error, send data to the bit bucket. */
|
||||
if (w_wn->w_status & STATUS_DRQ) {
|
||||
if ((s=sys_insw(wn->base + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
}
|
||||
break;
|
||||
|
@ -859,10 +933,10 @@ unsigned nr_req; /* length of request vector */
|
|||
|
||||
/* Copy bytes to or from the device's buffer. */
|
||||
if (opcode == DEV_GATHER) {
|
||||
if ((s=sys_insw(wn->base + REG_DATA, proc_nr, (void *) iov->iov_addr, SECTOR_SIZE)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, (void *) iov->iov_addr, SECTOR_SIZE)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
} else {
|
||||
if ((s=sys_outsw(wn->base + REG_DATA, proc_nr, (void *) iov->iov_addr, SECTOR_SIZE)) != OK)
|
||||
if ((s=sys_outsw(wn->base_cmd + REG_DATA, proc_nr, (void *) iov->iov_addr, SECTOR_SIZE)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
|
||||
/* Data sent, wait for an interrupt. */
|
||||
|
@ -899,7 +973,8 @@ struct command *cmd; /* Command block */
|
|||
/* Output the command block to the winchester controller and return status */
|
||||
|
||||
struct wini *wn = w_wn;
|
||||
unsigned base = wn->base;
|
||||
unsigned base_cmd = wn->base_cmd;
|
||||
unsigned base_ctl = wn->base_ctl;
|
||||
pvb_pair_t outbyte[7]; /* vector for sys_voutb() */
|
||||
int s; /* status for sys_(v)outb() */
|
||||
|
||||
|
@ -911,7 +986,7 @@ struct command *cmd; /* Command block */
|
|||
}
|
||||
|
||||
/* Select drive. */
|
||||
if ((s=sys_outb(base + REG_LDH, cmd->ldh)) != OK)
|
||||
if ((s=sys_outb(base_cmd + REG_LDH, cmd->ldh)) != OK)
|
||||
panic(w_name(),"Couldn't write register to select drive",s);
|
||||
|
||||
if (!w_waitfor(STATUS_BSY, 0)) {
|
||||
|
@ -929,13 +1004,13 @@ struct command *cmd; /* Command block */
|
|||
|
||||
wn->w_status = STATUS_ADMBSY;
|
||||
w_command = cmd->command;
|
||||
pv_set(outbyte[0], base + REG_CTL, wn->pheads >= 8 ? CTL_EIGHTHEADS : 0);
|
||||
pv_set(outbyte[1], base + REG_PRECOMP, cmd->precomp);
|
||||
pv_set(outbyte[2], base + REG_COUNT, cmd->count);
|
||||
pv_set(outbyte[3], base + REG_SECTOR, cmd->sector);
|
||||
pv_set(outbyte[4], base + REG_CYL_LO, cmd->cyl_lo);
|
||||
pv_set(outbyte[5], base + REG_CYL_HI, cmd->cyl_hi);
|
||||
pv_set(outbyte[6], base + REG_COMMAND, cmd->command);
|
||||
pv_set(outbyte[0], base_ctl + REG_CTL, wn->pheads >= 8 ? CTL_EIGHTHEADS : 0);
|
||||
pv_set(outbyte[1], base_cmd + REG_PRECOMP, cmd->precomp);
|
||||
pv_set(outbyte[2], base_cmd + REG_COUNT, cmd->count);
|
||||
pv_set(outbyte[3], base_cmd + REG_SECTOR, cmd->sector);
|
||||
pv_set(outbyte[4], base_cmd + REG_CYL_LO, cmd->cyl_lo);
|
||||
pv_set(outbyte[5], base_cmd + REG_CYL_HI, cmd->cyl_hi);
|
||||
pv_set(outbyte[6], base_cmd + REG_COMMAND, cmd->command);
|
||||
if ((s=sys_voutb(outbyte,7)) != OK)
|
||||
panic(w_name(),"Couldn't write registers with sys_voutb()",s);
|
||||
return(OK);
|
||||
|
@ -951,7 +1026,7 @@ PRIVATE void w_need_reset()
|
|||
int dr = 0;
|
||||
|
||||
for (wn = wini; wn < &wini[MAX_DRIVES]; wn++, dr++) {
|
||||
if (wn->base == w_wn->base) {
|
||||
if (wn->base_cmd == w_wn->base_cmd) {
|
||||
wn->state |= DEAF;
|
||||
wn->state &= ~INITIALIZED;
|
||||
}
|
||||
|
@ -1039,10 +1114,10 @@ PRIVATE int w_reset()
|
|||
tickdelay(RECOVERY_TICKS);
|
||||
|
||||
/* Strobe reset bit */
|
||||
if ((s=sys_outb(wn->base + REG_CTL, CTL_RESET)) != OK)
|
||||
if ((s=sys_outb(wn->base_ctl + REG_CTL, CTL_RESET)) != OK)
|
||||
panic(w_name(),"Couldn't strobe reset bit",s);
|
||||
tickdelay(DELAY_TICKS);
|
||||
if ((s=sys_outb(wn->base + REG_CTL, 0)) != OK)
|
||||
if ((s=sys_outb(wn->base_ctl + REG_CTL, 0)) != OK)
|
||||
panic(w_name(),"Couldn't strobe reset bit",s);
|
||||
tickdelay(DELAY_TICKS);
|
||||
|
||||
|
@ -1055,7 +1130,7 @@ PRIVATE int w_reset()
|
|||
/* The error register should be checked now, but some drives mess it up. */
|
||||
|
||||
for (wn = wini; wn < &wini[MAX_DRIVES]; wn++) {
|
||||
if (wn->base == w_wn->base) {
|
||||
if (wn->base_cmd == w_wn->base_cmd) {
|
||||
wn->state &= ~DEAF;
|
||||
if (w_wn->irq_need_ack) {
|
||||
/* Make sure irq is actually enabled.. */
|
||||
|
@ -1084,7 +1159,7 @@ PRIVATE void w_intr_wait()
|
|||
if (m.m_type == SYN_ALARM) { /* but check for timeout */
|
||||
w_timeout(); /* a.o. set w_status */
|
||||
} else if (m.m_type == HARD_INT) {
|
||||
sys_inb(w_wn->base + REG_STATUS, &w_wn->w_status);
|
||||
sys_inb(w_wn->base_cmd + REG_STATUS, &w_wn->w_status);
|
||||
ack_irqs(m.NOTIFY_ARG);
|
||||
} else {
|
||||
printf("AT_WINI got unexpected message %d from %d\n",
|
||||
|
@ -1110,7 +1185,7 @@ PRIVATE int at_intr_wait()
|
|||
if ((w_wn->w_status & (STATUS_BSY | STATUS_WF | STATUS_ERR)) == 0) {
|
||||
r = OK;
|
||||
} else {
|
||||
if ((s=sys_inb(w_wn->base + REG_ERROR, &inbval)) != OK)
|
||||
if ((s=sys_inb(w_wn->base_cmd + REG_ERROR, &inbval)) != OK)
|
||||
panic(w_name(),"Couldn't read register",s);
|
||||
if ((w_wn->w_status & STATUS_ERR) && (inbval & ERROR_BB)) {
|
||||
r = ERR_BAD_SECTOR; /* sector marked bad, retries won't help */
|
||||
|
@ -1138,7 +1213,7 @@ int value; /* required status */
|
|||
int s;
|
||||
getuptime(&t0);
|
||||
do {
|
||||
if ((s=sys_inb(w_wn->base + REG_STATUS, &w_wn->w_status)) != OK)
|
||||
if ((s=sys_inb(w_wn->base_cmd + REG_STATUS, &w_wn->w_status)) != OK)
|
||||
panic(w_name(),"Couldn't read register",s);
|
||||
if ((w_wn->w_status & mask) == value) {
|
||||
return 1;
|
||||
|
@ -1276,7 +1351,7 @@ unsigned nr_req; /* length of request vector */
|
|||
chunk = before;
|
||||
if (chunk > count) chunk = count;
|
||||
if (chunk > DMA_BUF_SIZE) chunk = DMA_BUF_SIZE;
|
||||
if ((s=sys_insw(wn->base + REG_DATA, SELF, tmp_buf, chunk)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, chunk)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
before -= chunk;
|
||||
count -= chunk;
|
||||
|
@ -1286,7 +1361,7 @@ unsigned nr_req; /* length of request vector */
|
|||
chunk = nbytes;
|
||||
if (chunk > count) chunk = count;
|
||||
if (chunk > iov->iov_size) chunk = iov->iov_size;
|
||||
if ((s=sys_insw(wn->base + REG_DATA, proc_nr, (void *) iov->iov_addr, chunk)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, (void *) iov->iov_addr, chunk)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
position += chunk;
|
||||
nbytes -= chunk;
|
||||
|
@ -1303,7 +1378,7 @@ unsigned nr_req; /* length of request vector */
|
|||
while (count > 0) { /* Excess data. */
|
||||
chunk = count;
|
||||
if (chunk > DMA_BUF_SIZE) chunk = DMA_BUF_SIZE;
|
||||
if ((s=sys_insw(wn->base + REG_DATA, SELF, tmp_buf, chunk)) != OK)
|
||||
if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, chunk)) != OK)
|
||||
panic(w_name(),"Call to sys_insw() failed", s);
|
||||
count -= chunk;
|
||||
}
|
||||
|
@ -1337,7 +1412,7 @@ unsigned cnt;
|
|||
if(wn->state & IGNORING) return ERR;
|
||||
|
||||
/* Select Master/Slave drive */
|
||||
if ((s=sys_outb(wn->base + REG_DRIVE, wn->ldhpref)) != OK)
|
||||
if ((s=sys_outb(wn->base_cmd + REG_DRIVE, wn->ldhpref)) != OK)
|
||||
panic(w_name(),"Couldn't select master/ slave drive",s);
|
||||
|
||||
if (!w_waitfor(STATUS_BSY | STATUS_DRQ, 0)) {
|
||||
|
@ -1358,12 +1433,12 @@ unsigned cnt;
|
|||
#endif
|
||||
|
||||
w_command = ATAPI_PACKETCMD;
|
||||
pv_set(outbyte[0], wn->base + REG_FEAT, 0);
|
||||
pv_set(outbyte[1], wn->base + REG_IRR, 0);
|
||||
pv_set(outbyte[2], wn->base + REG_SAMTAG, 0);
|
||||
pv_set(outbyte[3], wn->base + REG_CNT_LO, (cnt >> 0) & 0xFF);
|
||||
pv_set(outbyte[4], wn->base + REG_CNT_HI, (cnt >> 8) & 0xFF);
|
||||
pv_set(outbyte[5], wn->base + REG_COMMAND, w_command);
|
||||
pv_set(outbyte[0], wn->base_cmd + REG_FEAT, 0);
|
||||
pv_set(outbyte[1], wn->base_cmd + REG_IRR, 0);
|
||||
pv_set(outbyte[2], wn->base_cmd + REG_SAMTAG, 0);
|
||||
pv_set(outbyte[3], wn->base_cmd + REG_CNT_LO, (cnt >> 0) & 0xFF);
|
||||
pv_set(outbyte[4], wn->base_cmd + REG_CNT_HI, (cnt >> 8) & 0xFF);
|
||||
pv_set(outbyte[5], wn->base_cmd + REG_COMMAND, w_command);
|
||||
if ((s=sys_voutb(outbyte,6)) != OK)
|
||||
panic(w_name(),"Couldn't write registers with sys_voutb()",s);
|
||||
|
||||
|
@ -1374,7 +1449,7 @@ unsigned cnt;
|
|||
wn->w_status |= STATUS_ADMBSY; /* Command not at all done yet. */
|
||||
|
||||
/* Send the command packet to the device. */
|
||||
if ((s=sys_outsw(wn->base + REG_DATA, SELF, packet, 12)) != OK)
|
||||
if ((s=sys_outsw(wn->base_cmd + REG_DATA, SELF, packet, 12)) != OK)
|
||||
panic(w_name(),"sys_outsw() failed", s);
|
||||
return(OK);
|
||||
}
|
||||
|
@ -1462,7 +1537,7 @@ PRIVATE void ack_irqs(unsigned int irqs)
|
|||
for (drive = 0; drive < MAX_DRIVES && irqs; drive++) {
|
||||
if(!(wini[drive].state & IGNORING) && wini[drive].irq_need_ack &&
|
||||
(wini[drive].irq_mask & irqs)) {
|
||||
if(sys_inb((wini[drive].base + REG_STATUS), &wini[drive].w_status) != OK)
|
||||
if(sys_inb((wini[drive].base_cmd + REG_STATUS), &wini[drive].w_status) != OK)
|
||||
printf("couldn't ack irq on drive %d\n", drive);
|
||||
if (sys_irqenable(&wini[drive].irq_hook_id) != OK)
|
||||
printf("couldn't re-enable drive %d\n", drive);
|
||||
|
@ -1491,10 +1566,10 @@ PRIVATE int atapi_intr_wait()
|
|||
w_intr_wait();
|
||||
|
||||
/* Request series of device I/O. */
|
||||
inbyte[0].port = wn->base + REG_ERROR;
|
||||
inbyte[1].port = wn->base + REG_CNT_LO;
|
||||
inbyte[2].port = wn->base + REG_CNT_HI;
|
||||
inbyte[3].port = wn->base + REG_IRR;
|
||||
inbyte[0].port = wn->base_cmd + REG_ERROR;
|
||||
inbyte[1].port = wn->base_cmd + REG_CNT_LO;
|
||||
inbyte[2].port = wn->base_cmd + REG_CNT_HI;
|
||||
inbyte[3].port = wn->base_cmd + REG_IRR;
|
||||
if ((s=sys_vinb(inbyte, 4)) != OK)
|
||||
panic(w_name(),"ATAPI failed sys_vinb()", s);
|
||||
e = inbyte[0].value;
|
||||
|
|
Loading…
Reference in a new issue