Changeset 832cbe7 in mainline for uspace/drv/bus/pci/pciintel/pci.c


Ignore:
Timestamp:
2025-02-05T12:30:20Z (9 days ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
accdf882
Parents:
0dab4850
git-author:
Jiri Svoboda <jiri@…> (2025-02-04 21:30:06)
git-committer:
Jiri Svoboda <jiri@…> (2025-02-05 12:30:20)
Message:

Add proper IDE PCI to ISA fallback mechanism.

To determine if legacy IDE I/O ports are free, isa-ide asks isa,
who asks pciintel. pciintel waits for bus enumeration to complete,
then waits for all functions except the one who is asking
(which is ISA bus) to stabilize. During attach pci-ide will claim
the legacy IDE ports. Thus, if at this point legacy IDE ports
are unclaimed, pciintel tells ISA they are free, which tells isa-ide,
which continues to attach. If they are not free, isa-ide will not
attach.

This works for all use cases, including system without PCI bus,
system with PCI bus, but no (or disabled) PCI IDE, system with PCI
IDE with unrecognized VID/PID (which we will handle in legacy ISA mode).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/pci/pciintel/pci.c

    r0dab4850 r832cbe7  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * Copyright (c) 2010 Lenka Trochtova
    44 * All rights reserved.
     
    143143}
    144144
     145/** Handle legacy IO availability query from function.
     146 *
     147 * @param fnode Function performing the query
     148 * @param rclaims Place to store the legacy IO claims bitmask
     149 * @return EOK on success or an error code
     150 */
     151static errno_t pciintel_query_legacy_io(ddf_fun_t *fnode,
     152    hw_res_claims_t *rclaims)
     153{
     154        pci_fun_t *fun = pci_fun(fnode);
     155        pci_bus_t *bus = fun->busptr;
     156        pci_fun_t *f;
     157        hw_res_claims_t claims;
     158
     159        /*
     160         * We need to wait for enumeration to complete so that we give
     161         * the PCI IDE driver a chance to claim the legacy ISA IDE
     162         * ranges.
     163         */
     164        ddf_msg(LVL_DEBUG, "pciintel_query_legacy_io");
     165
     166        fun->querying = true;
     167
     168        fibril_mutex_lock(&bus->enum_done_lock);
     169        while (!bus->enum_done)
     170                fibril_condvar_wait(&bus->enum_done_cv, &bus->enum_done_lock);
     171        fibril_mutex_unlock(&bus->enum_done_lock);
     172
     173        ddf_msg(LVL_DEBUG, "Wait for PCI devices to stabilize");
     174
     175        f = pci_fun_first(bus);
     176        while (f != NULL) {
     177                if (!f->querying)
     178                        ddf_fun_wait_stable(f->fnode);
     179                f = pci_fun_next(f);
     180        }
     181
     182        /* Devices are stable. Now we can determine if ISA IDE was claimed. */
     183
     184        claims = 0;
     185
     186        ddf_msg(LVL_DEBUG, "PCI devices stabilized, leg_ide_claimed=%d\n",
     187            (int)bus->leg_ide_claimed);
     188        if (bus->leg_ide_claimed != false) {
     189                ddf_msg(LVL_NOTE, "Legacy IDE I/O ports claimed by PCI driver.");
     190                claims |= hwc_isa_ide;
     191        }
     192
     193        fun->querying = false;
     194        *rclaims = claims;
     195        return EOK;
     196}
     197
     198/** Handle legacy IO claim from function.
     199 *
     200 * @param fnode Function claiming the legacy I/O ports
     201 * @param claims Bitmask of claimed I/O
     202 * @return EOK on success or an error code
     203 */
     204static errno_t pciintel_claim_legacy_io(ddf_fun_t *fnode,
     205    hw_res_claims_t claims)
     206{
     207        pci_fun_t *fun = pci_fun(fnode);
     208        pci_bus_t *bus = fun->busptr;
     209
     210        ddf_msg(LVL_DEBUG, "pciintel_claim_legacy_io() claims=%x", claims);
     211        if ((claims & hwc_isa_ide) != 0)
     212                bus->leg_ide_claimed = true;
     213
     214        return EOK;
     215}
     216
    145217static pio_window_t *pciintel_get_pio_window(ddf_fun_t *fnode)
    146218{
     
    211283        .disable_interrupt = &pciintel_disable_interrupt,
    212284        .clear_interrupt = &pciintel_clear_interrupt,
     285        .query_legacy_io = &pciintel_query_legacy_io,
     286        .claim_legacy_io = &pciintel_claim_legacy_io
    213287};
    214288
     
    755829        list_initialize(&bus->funs);
    756830        fibril_mutex_initialize(&bus->conf_mutex);
     831        fibril_mutex_initialize(&bus->enum_done_lock);
     832        fibril_condvar_initialize(&bus->enum_done_cv);
    757833
    758834        bus->dnode = dnode;
     
    863939        hw_res_clean_resource_list(&hw_resources);
    864940
     941        ddf_msg(LVL_DEBUG, "Bus enumeration done.");
     942
     943        fibril_mutex_lock(&bus->enum_done_lock);
     944        bus->enum_done = true;
     945        fibril_mutex_unlock(&bus->enum_done_lock);
     946        fibril_condvar_broadcast(&bus->enum_done_cv);
     947
    865948        return EOK;
    866 
    867949fail:
    868950        if (got_res)
Note: See TracChangeset for help on using the changeset viewer.