diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index d18aa355900..dcd40f442e5 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -404,7 +404,9 @@ ata_ahci_chipinit(device_t dev) ATA_INL(ctlr->r_res2, ATA_AHCI_GHC) | ATA_AHCI_GHC_AE); /* get the number of HW channels */ - ctlr->channels = (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_NPMASK)+1; + ctlr->channels = + MAX(flsl(ATA_INL(ctlr->r_res2, ATA_AHCI_PI)), + (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_NPMASK) + 1); /* clear interrupts */ ATA_OUTL(ctlr->r_res2, ATA_AHCI_IS, ATA_INL(ctlr->r_res2, ATA_AHCI_IS)); @@ -427,7 +429,8 @@ ata_ahci_chipinit(device_t dev) device_printf(dev, "AHCI Version %x%x.%x%x controller with %d ports detected\n", (version >> 24) & 0xff, (version >> 16) & 0xff, - (version >> 8) & 0xff, version & 0xff, ctlr->channels); + (version >> 8) & 0xff, version & 0xff, + (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_NPMASK) + 1); return 0; } @@ -464,7 +467,7 @@ ata_ahci_allocate(device_t dev) ch->hw.end_transaction = ata_ahci_end_transaction; ch->hw.command = NULL; /* not used here */ - /* setup the work areas */ + /* setup work areas */ ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, ch->dma->work_bus + ATA_AHCI_CL_OFFSET); ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, 0x00000000); @@ -663,6 +666,11 @@ ata_ahci_reset(device_t dev) int offset = ch->unit << 7; int timeout; + if (!(ATA_INL(ctlr->r_res2, ATA_AHCI_PI) & (1 << ch->unit))) { + device_printf(dev, "port not implemented\n"); + ch->devices = 0; + } + /* kill off all activity on this channel */ cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset); ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 1acd68d179e..3bc6d8ff057 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 - 2006 Søren Schmidt + * Copyright (c) 1998 - 2007 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -568,8 +568,11 @@ ata_pcichannel_attach(device_t dev) if (ch->dma) ch->dma->alloc(dev); - if ((error = ctlr->allocate(dev))) + if ((error = ctlr->allocate(dev))) { + if (ch->dma) + ch->dma->free(dev); return error; + } return ata_attach(dev); }