Re: HP9000 K-Series support, howto and diffs

Jochen Kunz <[email protected]> Fri, 31 Oct 2003 23:59:16 +0100
Newsgroups gmane.os.openbsd.hppa
Message-ID <20031031225916.GK2865021@MrPomeroy2>
On 2003.10.31 22:55 Michael Shalayeff wrote:

> so you are saying that my code is false and yet it works on
> all supported machines (including all that you have problems on)
> w/o detecting any device twice or any other artifacts.
I should have written this more precise.
The OpenBSD code uses the device path parameter nca.ca_dp.dp_bc with
PDC_TYPE_MEMMAP in the same way as it is used with PDC_TYPE_SYSMAP. But
this _seams_ to be wrong. I found no documentation for PDC_TYPE_MEMMAP.
All I have is the Linux code that was written by HP people und I think
they knew how PDC_TYPE_MEMMAP works.

For PDC_TYPE_MEMMAP:
nca.ca_dp.dp_bc[0] to nca.ca_dp.dp_bc[3] are allways == -1.
nca.ca_dp.dp_bc[4] is == -1 when devices on the mainbus are scanned.
(i.e. pdc_scanbus is called from mbattach()). 
nca.ca_dp.dp_bc[4] is set to the module number when devices on a bus
below mainbus are scaned, e.g. lasi/gsc.
nca.ca_dp.dp_bc[5] is == -1 when devices on the mainbus are scanned. It
is set to 0 when devices on a bus below mainbus are scaned.
nca.ca_dp.dp_mod is iterated from 15 to 0.

Or to show code:
pdc_scanbus_memory_map(self, ca, callback)
        struct device *self;
        struct confargs *ca;
        void (*callback) __P((struct device *, struct confargs *));
{
    struct pdc_memmap pdc_memmap;
    int i;

    for (i = 15; i >= 0 ; i--) {
        struct confargs nca;
        struct pdc_iodc_read pdc_iodc_read;

        nca.ca_dp.dp_bc[0] = -1; 
        nca.ca_dp.dp_bc[1] = -1; 
        nca.ca_dp.dp_bc[2] = -1; 
        nca.ca_dp.dp_bc[3] = -1; 
        nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_mod;
        nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod < 0 ? -1 : 0;
        nca.ca_dp.dp_mod = i;

        if (pdc_call((iodcio_t)pdc, 0, PDC_MEMMAP, PDC_MEMMAP_HPA, 
            &pdc_memmap, &nca.ca_dp) < 0)
                continue;

        if (pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ,
             &pdc_iodc_read, pdc_memmap.hpa, IODC_DATA,
             &nca.ca_type, sizeof(nca.ca_type)) < 0)
                continue;

        nca.ca_mod = i;
        nca.ca_hpa = pdc_memmap.hpa;
        nca.ca_irq = HP700CF_IRQ_UNDEF;
        nca.ca_pdc_iodc_read = &pdc_iodc_read;
        nca.ca_name = hppa_mod_info(nca.ca_type.iodc_type,
            nca.ca_type.iodc_sv_model);
        (*callback)(self, &nca); /* this calls config_found_sm() */
    }   
}

Your code contains:
        nca.ca_dp.dp_bc[0] = ca->ca_dp.dp_bc[1];
        nca.ca_dp.dp_bc[1] = ca->ca_dp.dp_bc[2];
        nca.ca_dp.dp_bc[2] = ca->ca_dp.dp_bc[3];
        nca.ca_dp.dp_bc[3] = ca->ca_dp.dp_bc[4];
        nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_bc[5];
        nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod;
        nca.ca_dp.dp_mod = i;
So when a bus below mainbus is scaned (lasi/gsc or asp/gsc) you set
nca.ca_dp.dp_bc[5] to the module number. This seams to be wrong in your
code. The Linux code sets nca.ca_dp.dp_bc[4] to the module number and so
did I. 

Setting 
        nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_bc[5];
        nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod;
is only correct when PDC_TYPE_SYSMAP is used. 

I use a separate pdc_scanbus_system_map() function on machines that
suport PDC_TYPE_SYSMAP. My code for PDC_TYPE_SYSMAP is mostly the same
as the OpenBSD code. It works well on all machines that use only
PDC_TYPE_SYSMAP. 

> on the other hand your "true" (i suppose) code does not work.
It does work. At one point during developement I had the problem with
double detected devices. Then I split the code into two different
algorithems, similar to Hellmuth's code. This solved the problem.
-- 


tschüß,
       Jochen

Homepage: http://www.unixag-kl.fh-kl.de/~jkunz/