2  * eisa_enumerator.c - provide support for EISA adapters in PA-RISC machines
 
   4  * This program is free software; you can redistribute it and/or
 
   5  * modify it under the terms of the GNU General Public License
 
   6  * as published by the Free Software Foundation; either version
 
   7  * 2 of the License, or (at your option) any later version.
 
   9  * Copyright (c) 2002 Daniel Engstrom <5116@telia.com>
 
  13 #include <linux/ioport.h>
 
  14 #include <linux/init.h>
 
  15 #include <linux/kernel.h>
 
  16 #include <linux/slab.h>
 
  18 #include <asm/uaccess.h>
 
  19 #include <asm/byteorder.h>
 
  21 #include <asm/eisa_bus.h>
 
  22 #include <asm/eisa_eeprom.h>
 
  28  * PORT init with MASK attr and other size than byte
 
  29  * MEMORY with other decode than 20 bit
 
  36 #define SLOT2PORT(x) (x<<12)
 
  39 /* macros to handle unaligned accesses and 
 
  40  * byte swapping. The data in the EEPROM is
 
  41  * little-endian on the big-endian PAROSC */
 
  42 #define get_8(x) (*(u_int8_t*)(x))
 
  44 static inline u_int16_t get_16(const unsigned char *x)
 
  46         return (x[1] << 8) | x[0];
 
  49 static inline u_int32_t get_32(const unsigned char *x)
 
  51         return (x[3] << 24) | (x[2] << 16) | (x[1] << 8) | x[0];
 
  54 static inline u_int32_t get_24(const unsigned char *x)
 
  56         return (x[2] << 24) | (x[1] << 16) | (x[0] << 8);
 
  59 static void print_eisa_id(char *s, u_int32_t id)
 
  70         vendor[2] = '@' + (id & 0x1f);
 
  72         vendor[1] = '@' + (id & 0x1f);
 
  74         vendor[0] = '@' + (id & 0x1f);
 
  77         sprintf(s, "%s%02X%02X", vendor, device, rev);
 
  80 static int configure_memory(const unsigned char *buf, 
 
  81                        struct resource *mem_parent,
 
  91         for (i=0;i<HPEE_MEMORY_MAX_ENT;i++) {
 
  94                 if (NULL != (res = kmalloc(sizeof(struct resource), GFP_KERNEL))) {
 
  98                         res->start = mem_parent->start + get_24(buf+len+2);
 
  99                         res->end = res->start + get_16(buf+len+5)*1024;
 
 100                         res->flags = IORESOURCE_MEM;
 
 101                         printk("memory %lx-%lx ", res->start, res->end);
 
 102                         result = request_resource(mem_parent, res);
 
 104                                 printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
 
 111                 if (!(c & HPEE_MEMORY_MORE)) {
 
 120 static int configure_irq(const unsigned char *buf)
 
 128         for (i=0;i<HPEE_IRQ_MAX_ENT;i++) {
 
 131                 printk("IRQ %d ", c & HPEE_IRQ_CHANNEL_MASK);
 
 132                 if (c & HPEE_IRQ_TRIG_LEVEL) {
 
 133                         eisa_make_irq_level(c & HPEE_IRQ_CHANNEL_MASK);
 
 135                         eisa_make_irq_edge(c & HPEE_IRQ_CHANNEL_MASK);
 
 139                 /* hpux seems to allow for
 
 140                  * two bytes of irq data but only defines one of
 
 142                 if  (!(c & HPEE_IRQ_MORE)) {
 
 151 static int configure_dma(const unsigned char *buf)
 
 159         for (i=0;i<HPEE_DMA_MAX_ENT;i++) {
 
 161                 printk("DMA %d ", c&HPEE_DMA_CHANNEL_MASK);
 
 162                 /* fixme: maybe initialize the dma channel withthe timing ? */
 
 164                 if (!(c & HPEE_DMA_MORE)) {
 
 172 static int configure_port(const unsigned char *buf, struct resource *io_parent,
 
 178         struct resource *res;
 
 183         for (i=0;i<HPEE_PORT_MAX_ENT;i++) {
 
 186                 if (NULL != (res = kmalloc(sizeof(struct resource), GFP_KERNEL))) {
 
 188                         res->start = get_16(buf+len+1);
 
 189                         res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
 
 190                         res->flags = IORESOURCE_IO;
 
 191                         printk("ioports %lx-%lx ", res->start, res->end);
 
 192                         result = request_resource(io_parent, res);
 
 194                                 printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
 
 200                 if (!(c & HPEE_PORT_MORE)) {
 
 209 /* byte 1 and 2 is the port number to write
 
 210  * and at byte 3 the value to write starts.
 
 211  * I assume that there are and- and or- masks
 
 212  * here when HPEE_PORT_INIT_MASK is set but I have 
 
 213  * not yet encountered this. */
 
 214 static int configure_port_init(const unsigned char *buf)
 
 219         while (len<HPEE_PORT_INIT_MAX_LEN) {
 
 223                 switch (c & HPEE_PORT_INIT_WIDTH_MASK)  {
 
 224                  case HPEE_PORT_INIT_WIDTH_BYTE:
 
 226                         if (c & HPEE_PORT_INIT_MASK) {
 
 227                                 printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
 
 228                                 outb((inb(get_16(buf+len+1) & 
 
 230                                       get_8(buf+len+4)), get_16(buf+len+1));
 
 233                                 outb(get_8(buf+len+3), get_16(buf+len+1));
 
 237                  case HPEE_PORT_INIT_WIDTH_WORD:
 
 239                         if (c & HPEE_PORT_INIT_MASK) {
 
 240                                 printk(KERN_WARNING "port_init: unverified mask attribute\n");
 
 241                                        outw((inw(get_16(buf+len+1)) &
 
 246                                 outw(cpu_to_le16(get_16(buf+len+3)), get_16(buf+len+1));
 
 249                  case HPEE_PORT_INIT_WIDTH_DWORD:
 
 251                         if (c & HPEE_PORT_INIT_MASK) {
 
 252                                 printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
 
 253                                 outl((inl(get_16(buf+len+1) &
 
 255                                       get_32(buf+len+7)), get_16(buf+len+1));
 
 257                                 outl(cpu_to_le32(get_32(buf+len+3)), get_16(buf+len+1));
 
 262                         printk("\n" KERN_ERR "Invalid port init word %02x\n", c);
 
 266                 if (c & HPEE_PORT_INIT_MASK) {   
 
 271                 if (!(c & HPEE_PORT_INIT_MORE)) {
 
 279 static int configure_choise(const unsigned char *buf, u_int8_t *info)
 
 283         /* theis record contain the value of the functions
 
 284          * configuration choises and an info byte which 
 
 285          * describes which other records to expect in this 
 
 288         *info=get_8(buf+len+1);
 
 293 static int configure_type_string(const unsigned char *buf) 
 
 297         /* just skip past the type field */
 
 300                 printk("\n" KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
 
 306 static int configure_function(const unsigned char *buf, int *more) 
 
 308         /* the init field seems to be a two-byte field
 
 309          * which is non-zero if there are an other function following
 
 310          * I think it is the length of the function def 
 
 317 static int parse_slot_config(int slot,
 
 318                              const unsigned char *buf,
 
 319                              struct eeprom_eisa_slot_info *es, 
 
 320                              struct resource *io_parent,
 
 321                              struct resource *mem_parent)
 
 332         int id_string_used=0;
 
 334         if (NULL == (board = kmalloc(8, GFP_KERNEL))) {
 
 337         print_eisa_id(board, es->eisa_slot_id);
 
 338         printk(KERN_INFO "EISA slot %d: %s %s ", 
 
 339                slot, board, es->flags&HPEE_FLAG_BOARD_IS_ISA ? "ISA" : "EISA");
 
 341         maxlen = es->config_data_length < HPEE_MAX_LENGTH ?
 
 342                          es->config_data_length : HPEE_MAX_LENGTH;
 
 343         while ((pos < maxlen) && (num_func <= es->num_functions)) {
 
 344                 pos+=configure_function(buf+pos, &function_len); 
 
 351                 pos += configure_choise(buf+pos, &flags);
 
 353                 if (flags & HPEE_FUNCTION_INFO_F_DISABLED) {
 
 354                         /* function disabled, skip silently */
 
 355                         pos = p0 + function_len;
 
 358                 if (flags & HPEE_FUNCTION_INFO_CFG_FREE_FORM) {
 
 359                         /* I have no idea how to handle this */
 
 360                         printk("function %d have free-form confgiuration, skipping ",
 
 362                         pos = p0 + function_len;
 
 366                 /* the ordering of the sections need
 
 367                  * more investigation.
 
 368                  * Currently I think that memory comaed before IRQ
 
 369                  * I assume the order is LSB to MSB in the 
 
 371                  * eg type, memory, irq, dma, port, HPEE_PORT_init 
 
 374                 if (flags & HPEE_FUNCTION_INFO_HAVE_TYPE) {
 
 375                         pos += configure_type_string(buf+pos);
 
 378                 if (flags & HPEE_FUNCTION_INFO_HAVE_MEMORY) {
 
 380                         pos += configure_memory(buf+pos, mem_parent, board);
 
 383                 if (flags & HPEE_FUNCTION_INFO_HAVE_IRQ) {
 
 384                         pos += configure_irq(buf+pos);
 
 387                 if (flags & HPEE_FUNCTION_INFO_HAVE_DMA) {
 
 388                         pos += configure_dma(buf+pos);
 
 391                 if (flags & HPEE_FUNCTION_INFO_HAVE_PORT) {
 
 393                         pos += configure_port(buf+pos, io_parent, board);
 
 396                 if (flags &  HPEE_FUNCTION_INFO_HAVE_PORT_INIT) {
 
 397                         pos += configure_port_init(buf+pos);
 
 400                 if (p0 + function_len < pos) {
 
 401                         printk("\n" KERN_ERR "eisa_enumerator: function %d length mis-match "
 
 402                                "got %d, expected %d\n",
 
 403                                num_func, pos-p0, function_len);
 
 407                 pos = p0 + function_len;
 
 410         if (!id_string_used) {
 
 414         if (pos != es->config_data_length) {
 
 415                 printk(KERN_ERR "eisa_enumerator: config data length mis-match got %d, expected %d\n",
 
 416                         pos, es->config_data_length);
 
 420         if (num_func != es->num_functions) {
 
 421                 printk(KERN_ERR "eisa_enumerator: number of functions mis-match got %d, expected %d\n",
 
 422                         num_func, es->num_functions);
 
 430 static int init_slot(int slot, struct eeprom_eisa_slot_info *es)
 
 436         if (!(es->slot_info&HPEE_SLOT_INFO_NO_READID)) {
 
 437                 /* try to read the id of the board in the slot */
 
 438                 id = le32_to_cpu(inl(SLOT2PORT(slot)+EPI));
 
 440                 if (0xffffffff == id) {
 
 441                         /* Maybe we didn't expect a card to be here... */
 
 442                         if (es->eisa_slot_id == 0xffffffff)
 
 445                         /* this board is not here or it does not 
 
 448                         printk(KERN_ERR "EISA slot %d a configured board was not detected (", 
 
 451                         print_eisa_id(id_string, es->eisa_slot_id);
 
 452                         printk(" expected %s)\n", id_string);
 
 457                 if (es->eisa_slot_id != id) {
 
 458                         print_eisa_id(id_string, id);
 
 459                         printk(KERN_ERR "EISA slot %d id mis-match: got %s", 
 
 462                         print_eisa_id(id_string, es->eisa_slot_id);
 
 463                         printk(" expected %s \n", id_string);
 
 470         /* now: we need to enable the board if 
 
 471          * it supports enabling and run through
 
 472          * the port init sction if present
 
 473          * and finally record any interrupt polarity
 
 475         if (es->slot_features & HPEE_SLOT_FEATURES_ENABLE) {
 
 477                 outb(0x01| inb(SLOT2PORT(slot)+EPI+4),
 
 478                      SLOT2PORT(slot)+EPI+4);
 
 485 int eisa_enumerator(unsigned long eeprom_addr,
 
 486                     struct resource *io_parent, struct resource *mem_parent) 
 
 489         struct eeprom_header *eh;
 
 490         static char eeprom_buf[HPEE_MAX_LENGTH];
 
 492         for (i=0; i < HPEE_MAX_LENGTH; i++) {
 
 493                 eeprom_buf[i] = gsc_readb(eeprom_addr+i);
 
 496         printk(KERN_INFO "Enumerating EISA bus\n");
 
 498         eh = (struct eeprom_header*)(eeprom_buf);
 
 499         for (i=0;i<eh->num_slots;i++) {
 
 500                 struct eeprom_eisa_slot_info *es;
 
 502                 es = (struct eeprom_eisa_slot_info*)
 
 503                         (&eeprom_buf[HPEE_SLOT_INFO(i)]);
 
 505                 if (-1==init_slot(i+1, es)) {
 
 509                 if (es->config_data_offset < HPEE_MAX_LENGTH) {
 
 510                         if (parse_slot_config(i+1, &eeprom_buf[es->config_data_offset],
 
 511                                               es, io_parent, mem_parent)) {
 
 515                         printk (KERN_WARNING "EISA EEPROM offset 0x%x out of range\n",es->config_data_offset);
 
 519         return eh->num_slots;