Fix problem with slave devices.

Fix or rather bring ENOMEM problems back to the state it was before.
Temporarily disable PortMultipliers on AHCI devices.
This commit is contained in:
sos 2008-04-14 18:34:24 +00:00
parent 32960ab4b9
commit 48d8d5e84e
4 changed files with 16 additions and 16 deletions

View File

@ -418,8 +418,8 @@ struct ata_device {
device_t dev; /* device handle */
int unit; /* physical unit */
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x01
#define ATA_PM 0x0f
#define ATA_SLAVE 0x10
struct ata_params param; /* ata param structure */
int mode; /* current transfermode */

View File

@ -1055,9 +1055,10 @@ ata_ahci_softreset(device_t dev, int port)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
int offset = ch->unit << 7;
#ifdef AHCI_PM
struct ata_ahci_cmd_tab *ctp =
(struct ata_ahci_cmd_tab *)(ch->dma.work + ATA_AHCI_CT_OFFSET);
int offset = ch->unit << 7;
int timeout = 0;
/* kick controller into sane state if needed */
@ -1097,7 +1098,7 @@ ata_ahci_softreset(device_t dev, int port)
} while (ATA_INL(ctlr->r_res2, ATA_AHCI_P_TFD + offset) & ATA_S_BUSY);
if (bootverbose)
device_printf(dev, "BUSY wait time=%dms\n", timeout);
#endif
return ATA_INL(ctlr->r_res2, ATA_AHCI_P_SIG + offset);
}
@ -4306,7 +4307,7 @@ ata_promise_mio_softreset(device_t dev, int port)
ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), port & 0x0f);
/* softreset device on this channel */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_MASTER);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER));
DELAY(10);
ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET);
ata_udelay(10000);

View File

@ -112,8 +112,8 @@ ata_dmaalloc(device_t dev)
&ch->dma.work_map))
goto error;
if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map ,ch->dma.work,
MAXWSPCSZ, ata_dmasetupc_cb, &dcba, BUS_DMA_NOWAIT) ||
if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work,
MAXWSPCSZ, ata_dmasetupc_cb, &dcba, 0) ||
dcba.error) {
bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
goto error;
@ -202,8 +202,8 @@ ata_dmaload(struct ata_request *request, void *addr, int *entries)
}
if (bus_dmamap_load(request->dma.sg_tag, request->dma.sg_map,
request->dma.sg, MAXTABSZ,
ata_dmasetupc_cb, &dcba, BUS_DMA_NOWAIT) || dcba.error){
request->dma.sg, MAXTABSZ, ata_dmasetupc_cb, &dcba, 0)||
dcba.error) {
bus_dmamem_free(request->dma.sg_tag,
request->dma.sg, request->dma.sg_map);
device_printf(request->dev, "FAILURE - load sg\n");

View File

@ -463,7 +463,7 @@ ata_generic_reset(device_t dev)
int mask = 0, timeout;
/* do we have any signs of ATA/ATAPI HW being present ? */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_MASTER);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER));
DELAY(10);
ostat0 = ATA_IDX_INB(ch, ATA_STATUS);
if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5) {
@ -473,7 +473,7 @@ ata_generic_reset(device_t dev)
/* in some setups we dont want to test for a slave */
if (!(ch->flags & ATA_NO_SLAVE)) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_SLAVE);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_SLAVE));
DELAY(10);
ostat1 = ATA_IDX_INB(ch, ATA_STATUS);
if ((ostat1 & 0xf8) != 0xf8 && ostat1 != 0xa5) {
@ -493,7 +493,7 @@ ata_generic_reset(device_t dev)
return;
/* reset (both) devices on this channel */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_MASTER);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER));
DELAY(10);
ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET);
ata_udelay(10000);
@ -504,7 +504,7 @@ ata_generic_reset(device_t dev)
/* wait for BUSY to go inactive */
for (timeout = 0; timeout < 310; timeout++) {
if ((mask & 0x01) && (stat0 & ATA_S_BUSY)) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(ATA_MASTER));
DELAY(10);
err = ATA_IDX_INB(ch, ATA_ERROR);
lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
@ -534,7 +534,7 @@ ata_generic_reset(device_t dev)
if ((mask & 0x02) && (stat1 & ATA_S_BUSY) &&
!((mask & 0x01) && (stat0 & ATA_S_BUSY))) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(ATA_SLAVE));
DELAY(10);
err = ATA_IDX_INB(ch, ATA_ERROR);
lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
@ -582,9 +582,8 @@ ata_generic_reset(device_t dev)
}
if (bootverbose)
device_printf(dev, "reset tp2 stat0=%02x stat1=%02x devices=0x%b\n",
stat0, stat1, ch->devices,
"\20\4ATAPI_SLAVE\3ATAPI_MASTER\2ATA_SLAVE\1ATA_MASTER");
device_printf(dev, "reset tp2 stat0=%02x stat1=%02x devices=0x%x\n",
stat0, stat1, ch->devices);
}
/* must be called with ATA channel locked and state_mtx held */