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:
parent
32960ab4b9
commit
48d8d5e84e
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user