22 |
#include "nova-intern.h" |
#include "nova-intern.h" |
23 |
#include "module.h" |
#include "module.h" |
24 |
#include "dv-ide.h" |
#include "dv-ide.h" |
25 |
#include "io.h" |
#include "io-bus.h" |
26 |
#include "io-buf.h" |
#include "io-buf.h" |
27 |
|
|
28 |
#ifndef DEV_BSIZE |
#ifndef DEV_BSIZE |
132 |
return EIO; |
return EIO; |
133 |
} |
} |
134 |
|
|
135 |
p = (u_int16_t *) sc->sc_bp->b_data; |
p = (u_int16_t *) sc->sc_bp->data; |
136 |
memset (p, 0, sc->sc_bp->b_bcount); |
for (n = 0; n < (sc->sc_bp->bcount >> 1); n++) |
|
for (n = 0; n < (sc->sc_bp->b_bcount >> 1); n++) |
|
137 |
*p++ = io_read_2 (&ide_bus_tag, sc->sc_cmd_handle, IDE_REGISTER_DATA); |
*p++ = io_read_2 (&ide_bus_tag, sc->sc_cmd_handle, IDE_REGISTER_DATA); |
138 |
|
|
139 |
|
sc->sc_bp->flags &= ~B_INVAL; |
140 |
|
io_buf_done (sc->sc_bp); |
141 |
return 0; |
return 0; |
142 |
} |
} |
143 |
|
|
165 |
static int |
static int |
166 |
init_transfer (struct ide_softc *sc, struct io_buf *bp, bool read_p) |
init_transfer (struct ide_softc *sc, struct io_buf *bp, bool read_p) |
167 |
{ |
{ |
168 |
u_int32_t temp, sector = bp->b_rblkno; |
u_int32_t temp, sector = bp->rblkno; |
169 |
|
|
170 |
sc->sc_bio.bio_rcyl = sector / (sc->sc_ataparams.atap_heads |
sc->sc_bio.bio_rcyl = sector / (sc->sc_ataparams.atap_heads |
171 |
* sc->sc_ataparams.atap_sectors); |
* sc->sc_ataparams.atap_sectors); |
173 |
* sc->sc_ataparams.atap_sectors); |
* sc->sc_ataparams.atap_sectors); |
174 |
sc->sc_bio.bio_rhead = temp / sc->sc_ataparams.atap_sectors; |
sc->sc_bio.bio_rhead = temp / sc->sc_ataparams.atap_sectors; |
175 |
sc->sc_bio.bio_rsect = temp % sc->sc_ataparams.atap_sectors + 1; |
sc->sc_bio.bio_rsect = temp % sc->sc_ataparams.atap_sectors + 1; |
176 |
sc->sc_bio.bio_rnsects = bp->b_bcount / DEV_BSIZE; |
sc->sc_bio.bio_rnsects = bp->bcount / DEV_BSIZE; |
177 |
sc->sc_bio.bio_cmd = read_p ? IDE_COMMAND_READ : IDE_COMMAND_WRITE; |
sc->sc_bio.bio_cmd = read_p ? IDE_COMMAND_READ : IDE_COMMAND_WRITE; |
178 |
sc->sc_bp = bp; |
sc->sc_bp = bp; |
179 |
return 0; |
return 0; |
183 |
static int |
static int |
184 |
start_transfer (struct ide_softc *sc, struct io_buf *bp) |
start_transfer (struct ide_softc *sc, struct io_buf *bp) |
185 |
{ |
{ |
186 |
init_transfer (sc, bp, bp->b_flags & B_READ); |
init_transfer (sc, bp, bp->flags & B_READ); |
187 |
exec_transfer (sc); |
exec_transfer (sc); |
188 |
return transfer_intr (sc); |
return transfer_intr (sc); |
189 |
} |
} |
190 |
|
|
|
/* Wait for data request. */ |
|
|
static int |
|
|
ready_data (struct ide_softc *sc, int timeout) |
|
|
{ |
|
|
u_int8_t value, mask, old = 0; |
|
|
int retries = 1; |
|
|
|
|
|
mask = IDE_STATUS_READY | IDE_STATUS_BUSY | IDE_STATUS_DRQ; |
|
|
|
|
|
do |
|
|
{ |
|
|
value = io_read_1 (&ide_bus_tag, sc->sc_cmd_handle, |
|
|
IDE_REGISTER_STATUS); |
|
|
if (value != old) |
|
|
{ |
|
|
printf ("ready data: new value: %x\n", value); |
|
|
old = value; |
|
|
} |
|
|
|
|
|
if ((value & mask) == (IDE_STATUS_READY | IDE_STATUS_DRQ)) |
|
|
return 0; |
|
|
} |
|
|
while (!timeout || retries++ < timeout); |
|
|
return EIO; |
|
|
} |
|
|
|
|
191 |
/* Wait for controler to finish. */ |
/* Wait for controler to finish. */ |
192 |
static int |
static int |
193 |
controler_wait (struct ide_softc *sc, u_int8_t mask, u_int8_t bits, |
controler_wait (struct ide_softc *sc, u_int8_t mask, u_int8_t bits, |
275 |
return disk_mask; |
return disk_mask; |
276 |
} |
} |
277 |
|
|
|
static int |
|
|
fetch_data (struct ide_softc *sc, void *buffer, size_t size) |
|
|
{ |
|
|
u_int16_t *p; |
|
|
int err, n; |
|
|
|
|
|
err = controler_wait (sc, sc->sc_drq_mask, sc->sc_drq_bits, 6000); |
|
|
if (err) |
|
|
return EIO; |
|
|
|
|
|
p = (u_int16_t *) buffer; |
|
|
for (n = 0; n < (size >> 1); n++) |
|
|
*p++ = io_read_2 (&ide_bus_tag, sc->sc_cmd_handle, IDE_REGISTER_DATA); |
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
278 |
/* ??? */ |
/* ??? */ |
279 |
static int |
static int |
280 |
fetch_ata_params (struct ide_softc *sc, struct ata_params *params) |
fetch_ata_params (struct ide_softc *sc, struct ata_params *params) |
335 |
if (part != RAW_PART && !sc->sc_part [part].p_lba_start) |
if (part != RAW_PART && !sc->sc_part [part].p_lba_start) |
336 |
return ENXIO; |
return ENXIO; |
337 |
|
|
338 |
bp->b_rblkno = bp->b_blkno + sc->sc_part [part].p_lba_start; |
bp->rblkno = bp->blkno + sc->sc_part [part].p_lba_start; |
339 |
return start_transfer (sc, bp); |
return start_transfer (sc, bp); |
340 |
} |
} |
341 |
|
|
346 |
struct ide_softc *sc; |
struct ide_softc *sc; |
347 |
char tb [DEV_BSIZE]; |
char tb [DEV_BSIZE]; |
348 |
unsigned char *p; |
unsigned char *p; |
349 |
struct io_buf *bp; |
struct io_buf param_buf; |
350 |
int err, i; |
int err, i; |
351 |
|
|
352 |
sc = (struct ide_softc *) malloc (sizeof (struct ide_softc)); |
sc = (struct ide_softc *) malloc (sizeof (struct ide_softc)); |
365 |
err = fetch_ata_params (sc, &sc->sc_ataparams); |
err = fetch_ata_params (sc, &sc->sc_ataparams); |
366 |
if (err) |
if (err) |
367 |
return err; |
return err; |
368 |
|
|
369 |
bp = io_buf_init (tb, DEV_BSIZE); |
param_buf.mutex = PTHREAD_MUTEX_INITIALIZER; |
370 |
assert (bp); |
param_buf.cond = PTHREAD_COND_INITIALIZER; |
371 |
|
param_buf.data = tb; |
372 |
bp->b_bcount = DEV_BSIZE; |
param_buf.size = DEV_BSIZE; |
373 |
bp->b_rblkno = 0; |
param_buf.bcount = DEV_BSIZE; |
374 |
bp->b_flags = B_READ; |
param_buf.rblkno = 0; |
375 |
err = start_transfer (sc, bp); |
param_buf.flags = B_READ; |
376 |
|
param_buf.iodone = 0; |
377 |
|
param_buf.vp = 0; |
378 |
|
err = start_transfer (sc, ¶m_buf); |
379 |
if (err) |
if (err) |
380 |
return err; |
return err; |
381 |
|
|
382 |
#define PARTITION_OFF 0x1be |
#define PARTITION_OFF 0x1be |
383 |
p = bp->b_data; |
p = param_buf.data; |
384 |
if (p [510] != 0x55 || p [511] != 0xaa) |
if (p [510] != 0x55 || p [511] != 0xaa) |
385 |
{ |
{ |
386 |
printf ("drive contains bad part table %x %x\n", |
printf ("drive contains bad part table %x %x\n", |
396 |
sc->sc_ataparams.atap_capabilities1 & IDE_CAP_LBA |
sc->sc_ataparams.atap_capabilities1 & IDE_CAP_LBA |
397 |
? "(lba)" : ""); |
? "(lba)" : ""); |
398 |
|
|
399 |
memcpy (sc->sc_part, bp->b_data + PARTITION_OFF, |
memcpy (sc->sc_part, param_buf.data + PARTITION_OFF, |
400 |
4 * sizeof (struct partition)); |
4 * sizeof (struct partition)); |
401 |
|
|
402 |
for (i = 0; i < NPART; i++) |
for (i = 0; i < NPART; i++) |