/*-------------------------------------------------------------------------- * Procedure reorganize_data(): * This procedure reads the input multidimensional array that is organised * in the order specified by array "X" and breaks it up into chunks of * dimensions specified in "C". * * This is a very slow process, since reading and writing of LARGE files * may be involved. * *------------------------------------------------------------------------- */ static void _ConvertToChunkFile(int n, int baseSize, int dim[], int C[], int srcfd, int destfd) { int max_chunks[MAXDIM], chunk_no[MAXDIM]; int PX[MAXDIM], dist[MAXDIM]; int csize = 1, i, temp; for (i = 0; i < n; chunk_no[i++] = 0) { max_chunks[i] = dim[i]/C[i]; csize *= C[i]; } csize *= baseSize; temp = csize + 4; memmove(a_chunk, &temp, 4); mda_get_prod(n, dim, PX); mda_get_offset_values(n, dist, PX, C); for (i = 0; i < n; dist[i] *= baseSize, i++) ; do { read_chunk(chunk_no, C, &(a_chunk[4]), srcfd, n, baseSize, PX, dist); write_chunk((struct varlena*)a_chunk, destfd); } while (next_tuple(n, chunk_no, max_chunks) != -1); }
static struct srv * next_tuple(void) { struct srv_prio *pe; struct srv *se; uint16_t rnd; unsigned csum = 0; unsigned wsum = 0; pe = ISC_LIST_HEAD(prio_list); if (pe == NULL) return (NULL); for (se = ISC_LIST_HEAD(pe->srv_list); se != NULL; se = ISC_LIST_NEXT(se, link)) { wsum += se->weight; } rnd = random() % (wsum + 1); for (se = ISC_LIST_HEAD(pe->srv_list); se != NULL; se = ISC_LIST_NEXT(se, link)) { csum += se->weight; if (csum >= rnd) { ISC_LIST_UNLINK(pe->srv_list, se, link); break; } } if (se == NULL) { ISC_LIST_UNLINK(prio_list, pe, link); free(pe); return (next_tuple()); } #ifdef DEBUG fprintf(stderr, "rnd=%hu -> prio=%hu weight=%hu port=%hu tname=%s\n", rnd, pe->prio, se->weight, se->port, se->tname); #endif return (se); }
/** * @brief Advance the row iterator until value changes in terms of the join * clauses * @return the end row number, [start_row, end_row) are the rows of the same * value * if the end_row == start_row, the subset is empty */ size_t MergeJoinExecutor::Advance(LogicalTile *tile, size_t start_row, bool is_left) { size_t end_row = start_row + 1; size_t this_row = start_row; size_t tuple_count = tile->GetTupleCount(); if (start_row >= tuple_count) return start_row; while (end_row < tuple_count) { expression::ContainerTuple<executor::LogicalTile> this_tuple(tile, this_row); expression::ContainerTuple<executor::LogicalTile> next_tuple(tile, end_row); bool diff = false; for (auto &clause : *join_clauses_) { // Go through each join clauses auto expr = is_left ? clause.left_.get() : clause.right_.get(); peloton::Value this_value = expr->Evaluate(&this_tuple, &this_tuple, executor_context_); peloton::Value next_value = expr->Evaluate(&next_tuple, &next_tuple, executor_context_); if (this_value.Compare(next_value) != 0) { diff = true; break; } } if (diff) { break; } // the two tuples are the same, we advance by 1 this_row = end_row; end_row++; } LOG_TRACE("Advanced %s with subset size %lu ", is_left ? "left" : "right", end_row - start_row); return end_row; }
/*-------------------------------------------------------------------------- * read_chunk * reads a chunk from the input files into a_chunk, the position of the * chunk is specified by chunk_no *-------------------------------------------------------------------------- */ static void read_chunk(int chunk_no[], int C[], char a_chunk[], int srcfd, int n, int baseSize, int PX[], int dist[]) { int i, j, cp, unit_transfer; int start_pos, pos[MAXDIM]; int indx[MAXDIM]; int fpOff; for ( i = start_pos = 0; i < n; i++) { pos[i] = chunk_no[i] * C[i]; start_pos += pos[i]*PX[i]; } start_pos *= baseSize; /* Read a block of dimesion C starting at co-ordinates pos */ unit_transfer = C[n-1] * baseSize; for (i = 0; i < n; indx[i++] = 0) ; fpOff = start_pos; seek_and_read(fpOff, unit_transfer, a_chunk, srcfd, SEEK_SET); fpOff += unit_transfer; cp = unit_transfer; while ((j = next_tuple(n-1, indx, C)) != -1) { fpOff += dist[j]; seek_and_read(fpOff, unit_transfer, &(a_chunk[cp]), srcfd, SEEK_SET); cp += unit_transfer; fpOff += unit_transfer; } }
static void dump_keyblob (tupledesc_t tuples) { size_t n; unsigned int tag; const void *value; log_info ("keyblob dump:\n"); tag = KEYBLOB_TAG_BLOBVERSION; value = find_tuple (tuples, tag, &n); while (value) { log_info (" tag: %-5u len: %-2u value: ", tag, (unsigned int)n); if (tag == KEYBLOB_TAG_ENCKEY || tag == KEYBLOB_TAG_MACKEY) log_printf ("[confidential]\n"); else if (!n) log_printf ("[none]\n"); else log_printhex ("", value, n); value = next_tuple (tuples, &tag, &n); } }
static int simple_config(dev_link_t *link) { static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static int size_table[2] = { 8, 16 }; client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; config_info_t config; int i, j, try; int s; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) return -1; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; /* If the card is already configured, look up the port and irq */ i = pcmcia_get_configuration_info(handle, &config); if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { kio_addr_t port = 0; if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { port = config.BasePort2; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && (config.NumPorts1 == 0x40)) { port = config.BasePort1 + 0x28; info->slave = 1; } if (info->slave) { kfree(cfg_mem); return setup_serial(handle, info, port, config.AssignedIRQ); } } link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (s = 0; s < 2; s++) { for (try = 0; try < 2; try++) { i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(handle, tuple, parse); } } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(handle, tuple, parse); } found_port: if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link->handle, RequestIO, i); kfree(cfg_mem); return -1; } i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); kfree(cfg_mem); return -1; } kfree(cfg_mem); return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); }
/*---------------------------------------------------------------------------- * _ReadChunkArray -- * returns the subarray specified bu the range indices "st" and "endp" * from the chunked array stored in file "fp" *--------------------------------------------------------------------------- */ int _ReadChunkArray(int st[], int endp[], int bsize, int fp, char *destfp, ArrayType *array, int isDestLO, bool *isNull) { int i,j,jj; int n, temp, words_read; int chunk_span[MAXDIM], chunk_off[MAXDIM]; int chunk_st[MAXDIM], chunk_end[MAXDIM]; int block_seek; int bptr, *C, csize, *dim, *lb; int range_st[MAXDIM], range_end[MAXDIM], range[MAXDIM], array_span[MAXDIM]; int PA[MAXDIM], PCHUNK[MAXDIM], PC[MAXDIM]; int to_read; int cdist[MAXDIM], adist[MAXDIM]; int dist[MAXDIM], temp_seek; int srcOff; /* Needed since LO don't understand SEEK_CUR*/ char *baseDestFp = (char *)destfp; CHUNK_INFO *A = (CHUNK_INFO *) ARR_DATA_PTR(array); n = ARR_NDIM(array); dim = ARR_DIMS(array); lb = ARR_LBOUND(array); C = A->C; csize = C[n-1]; PC[n-1] = 1; temp = dim[n - 1]/C[n-1]; for (i = n-2; i >= 0; i--){ PC[i] = PC[i+1] * temp; temp = dim[i] / C[i]; csize *= C[i]; } for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++) ; mda_get_prod(n, C, PCHUNK); mda_get_range(n, array_span, st, endp); mda_get_prod(n, array_span, PA); array2chunk_coord(n, C, st, chunk_st); array2chunk_coord(n, C, endp, chunk_end); mda_get_range(n, chunk_span, chunk_st, chunk_end); mda_get_offset_values(n, dist, PC, chunk_span); for (i = 0; i < n; i++) { range_st[i] = st[i]; range_end[i] = min(chunk_st[i]*C[i]+C[i]-1, endp[i]); } for (i = j = 0; i < n; i++) j+= chunk_st[i]*PC[i]; temp_seek = srcOff = j * csize * bsize; if (lo_lseek(fp, srcOff, SEEK_SET) < 0) RETURN_NULL; jj = n-1; for (i = 0; i < n; chunk_off[i++] = 0) ; words_read = 0; temp_seek = 0; do { /* Write chunk (chunk_st) to output buffer */ mda_get_range(n, array_span, range_st, range_end); mda_get_offset_values(n, adist, PA, array_span); mda_get_offset_values(n, cdist, PCHUNK, array_span); for (i=0; i < n; range[i] = range_st[i]-st[i], i++); bptr = tuple2linear(n, range, PA); for (i = 0; i < n; range[i++] = 0); j = n-1; bptr *= bsize; if (isDestLO) { if (lo_lseek(destfp, bptr, SEEK_SET) < 0) RETURN_NULL; } else destfp = baseDestFp + bptr; for(i = 0, block_seek = 0; i < n; i++) block_seek += (range_st[i]-(chunk_st[i] + chunk_off[i]) *C[i])*PCHUNK[i]; if (dist[jj] + block_seek + temp_seek) { temp = (dist[jj]*csize+block_seek+temp_seek)*bsize; srcOff += temp; if (lo_lseek(fp, srcOff, SEEK_SET) < 0) RETURN_NULL; } for (i = n-1, to_read = bsize; i >= 0; to_read *= min(C[i], array_span[i]), i--) if (cdist[i] || adist[i]) break; do { if (cdist[j]) { srcOff += (cdist[j]*bsize); if (lo_lseek(fp, srcOff, SEEK_SET) < 0) RETURN_NULL; } block_seek += cdist[j]; bptr += adist[j]*bsize; if (isDestLO) { if (lo_lseek(destfp, bptr, SEEK_SET) < 0) RETURN_NULL; } else destfp = baseDestFp + bptr; temp = _LOtransfer ((char**)&destfp, to_read, 1, (char**)&fp, 1, isDestLO); if (temp < to_read) RETURN_NULL; srcOff += to_read; words_read+=to_read; bptr += to_read; block_seek += (to_read/bsize); /* * compute next tuple in range[] */ { int x; if (!(i+1)) j = -1; else { range[i] = (range[i]+1)%array_span[i]; for (x = i; x*(!range[x]); x--) range[x-1] = (range[x-1]+1)%array_span[x-1]; if (x) j = x; else { if (range[0]) j = 0; else j = -1; } } } /* * end of compute next tuple -- * j is set to -1 if tuple generation is over */ } while (j != -1); block_seek = csize - block_seek; temp_seek = block_seek; jj = next_tuple(n, chunk_off, chunk_span); if (jj == -1) break; range_st[jj] = (chunk_st[jj]+chunk_off[jj])*C[jj]; range_end[jj] = min(range_st[jj] + C[jj]-1, endp[jj]); for (i = jj+1; i < n; i++) { range_st[i] = st[i]; range_end[i] = min((chunk_st[i]+chunk_off[i])*C[i]+C[i]-1, endp[i]); } } while (jj != -1); return(words_read); }
static int multi_config(dev_link_t *link) { client_handle_t handle = link->handle; serial_info_t *info = link->priv; tuple_t tuple; u_char buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; int i, base2 = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } i = next_tuple(handle, &tuple, &parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } i = next_tuple(handle, &tuple, &parse); } } if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); return -1; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* Socket Dual IO: this enables irq's for second port */ if (info->multi && (info->manfid == MANFID_SOCKET)) { link->conf.Present |= PRESENT_EXT_STATUS; link->conf.ExtStatus = ESR_REQ_ATTN_ENA; } i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); return -1; } setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) return 0; for (i = 0; i < info->multi-1; i++) setup_serial(info, base2+(8*i), link->irq.AssignedIRQ); return 0; }
static int btuart_config(struct pcmcia_device *link) { static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; btuart_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; int i, j, try; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(link, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { BT_ERR("No usable port range found"); cs_error(link, RequestIO, i); goto failed; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); goto failed; } if (btuart_open(info) != 0) goto failed; strcpy(info->node.dev_name, info->hdev->name); link->dev_node = &info->node; return 0; failed: btuart_release(link); return -ENODEV; }
/* gpib_config() is scheduled to run after a CARD_INSERTION event is received, to configure the PCMCIA socket, and to make the ethernet device available to the system. */ static void ines_gpib_config( struct pcmcia_device *link ) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int i; u_char buf[64]; win_req_t req; memreq_t mem; void *virt; dev = link->priv; DEBUG(0, "ines_gpib_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = pcmcia_get_first_tuple(link, &tuple); if (i != 0) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = pcmcia_get_tuple_data(link, &tuple); if (i != 0) break; i = PCMCIA_PARSE_TUPLE(&tuple, &parse); if (i != 0) break; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; } while (0); if (i != 0) { cs_error(link, ParseTuple, i); return; } /* Configure card */ do { /* * try to get manufacturer and card ID */ tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; if( first_tuple(link,&tuple,&parse) == 0 ) { dev->manfid = parse.manfid.manf; dev->cardid = parse.manfid.card; printk(KERN_DEBUG "ines_cs: manufacturer: 0x%x card: 0x%x\n", dev->manfid, dev->cardid); } /* try to get board information from CIS */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; if( first_tuple(link,&tuple,&parse) == 0 ) { while(1) { if( parse.cftable_entry.io.nwin > 0) { link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = 32; link->io.BasePort2 = 0; link->io.NumPorts2 = 0; i = pcmcia_request_io(link, &link->io); if (i == 0) { printk( KERN_DEBUG "ines_cs: base=0x%x len=%d registered\n", link->io.BasePort1, link->io.NumPorts1 ); link->conf.ConfigIndex = parse.cftable_entry.index; break; } } if ( next_tuple(link,&tuple,&parse) != 0 ) break; } if (i != 0) { cs_error(link, RequestIO, i); } } else { printk("ines_cs: can't get card information\n"); } link->conf.Status = CCSR_IOIS8; /* for the ines card we have to setup the configuration registers in attribute memory here */ req.Attributes=WIN_MEMORY_TYPE_AM | WIN_DATA_WIDTH_8 | WIN_ENABLE; req.Base=0; req.Size=0x1000; req.AccessSpeed=250; i= pcmcia_request_window(&link, &req, &link->win); if (i != 0) { cs_error(link, RequestWindow, i); break; } mem.CardOffset=0; mem.Page=0; i= pcmcia_map_mem_page(link->win, &mem); if (i != 0) { cs_error(link, MapMemPage, i); break; } virt = ioremap( req.Base, req.Size ); writeb( ( link->io.BasePort1 >> 2 ) & 0xff, virt + 0xf0 ); // IOWindow base iounmap( ( void* ) virt ); } while (0); /* Now allocate an interrupt line. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { i = pcmcia_request_irq(link, &link->irq); if (i != 0) { cs_error(link, RequestIRQ, i); } printk(KERN_DEBUG "ines_cs: IRQ_Line=%d\n",link->irq.AssignedIRQ); } /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. */ i = pcmcia_request_configuration(link, &link->conf); if (i != 0) { cs_error(link, RequestConfiguration, i); } /* If any step failed, release any partially configured state */ if (i != 0) { ines_gpib_release(link); return; } printk(KERN_DEBUG "ines gpib device loaded\n"); } /* gpib_config */
int main(int argc, char **argv) { char *qname; ns_msg msg; int len, rc = 0; unsigned char answer[NS_MAXMSG]; unsigned rcode; struct srv *se; if (argc < 3) usage(); ISC_LIST_INIT(prio_list); srandom(time(NULL)); res_init(); qname = argv[1]; len = res_query(qname, ns_c_in, ns_t_srv, answer, sizeof answer); if (len < 0) { herror("res_query"); return (EXIT_FAILURE); } if (ns_initparse(answer, len, &msg) < 0) { perror("ns_initparse"); return (EXIT_FAILURE); } rcode = ns_msg_getflag(msg, ns_f_rcode); if (rcode != ns_r_noerror) { fprintf(stderr, "wrapsrv: query for %s returned rcode %u\n", qname, rcode); return (EXIT_FAILURE); } if (ns_msg_count(msg, ns_s_an) == 0) { fprintf(stderr, "wrapsrv: query for %s returned no answers\n", qname); return (EXIT_FAILURE); } parse_answer_section(&msg); #ifdef DEBUG print_tuples(); fprintf(stderr, "\n"); #endif while ((se = next_tuple()) != NULL) { if ((rc = do_cmd(se, argc, argv)) == 0) break; #ifdef DEBUG fprintf(stderr, "\n"); #endif } free_tuples(); return (rc); }
static int multi_config(struct pcmcia_device * link) { struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; int i, rc, base2 = 0; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) return -1; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } i = next_tuple(link, tuple, parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } i = next_tuple(link, tuple, parse); } } if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); rc = -1; goto free_cfg_mem; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* * Apply any configuration quirks. */ if (info->quirk && info->quirk->config) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); rc = -1; goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: * 8 registers are for the UART, the others are extra registers. * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too. */ if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC)) { int err; if (cf->index == 1 || cf->index == 3) { err = setup_serial(link, info, base2, link->irq.AssignedIRQ); base2 = link->io.BasePort1; } else { err = setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); } info->c950ctrl = base2; /* * FIXME: We really should wake up the port prior to * handing it over to the serial layer. */ if (info->quirk && info->quirk->wakeup) info->quirk->wakeup(link); rc = 0; goto free_cfg_mem; } setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); for (i = 0; i < info->multi - 1; i++) setup_serial(link, info, base2 + (8 * i), link->irq.AssignedIRQ); rc = 0; free_cfg_mem: kfree(cfg_mem); return rc; }
static int elsa_cs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int i, j, last_fn; u_short buf[128]; cistpl_cftable_entry_t *cf = &parse.cftable_entry; IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } break; } i = next_tuple(link, &tuple, &parse); } if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev_node = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: ", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard); if (i < 0) { printk(KERN_ERR "elsa_cs: failed to initialize Elsa PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); elsa_cs_release(link); } else ((local_info_t*)link->priv)->cardnr = i; return 0; cs_failed: cs_error(link, last_fn, i); elsa_cs_release(link); return -ENODEV; } /* elsa_cs_config */
static void avma1cs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u8 buf[64]; char devname[128]; int busy = 0; handle = link->handle; dev = link->priv; DEBUG(0, "avma1cs_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = CardServices(GetFirstTuple, handle, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = CardServices(GetTupleData, handle, &tuple); if (i != CS_SUCCESS) break; i = CardServices(ParseTuple, handle, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { cs_error(link->handle, ParseTuple, i); link->state &= ~DEV_CONFIG_PENDING; return; } /* Configure card */ link->state |= DEV_CONFIG; do { tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1 - 1); i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); break; } /* * allocate an interrupt line */ i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); CardServices(ReleaseIO, link->handle, &link->io); break; } /* * configure the PCMCIA socket */ i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseIRQ, link->handle, &link->irq); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ strcpy(dev->node.dev_name, "A1"); dev->node.major = 45; dev->node.minor = 0; link->dev = &dev->node; link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { avma1cs_release(link); return; } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", link->io.BasePort1, link->irq.AssignedIRQ); if (avm_a1_init_pcmcia((void *)(int)link->io.BasePort1, link->irq.AssignedIRQ, &busy, isdnprot) != 0) { printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); return; } i = 0; /* no returncode for cardnr :-( */ dev->node.minor = i; } /* avma1cs_config */
static int multi_config(dev_link_t * link) { client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; config_info_t config; int i, rc, base2 = 0; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) return -1; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; i = pcmcia_get_configuration_info(handle, &config); if (i != CS_SUCCESS) { cs_error(handle, GetConfigurationInfo, i); rc = -1; goto free_cfg_mem; } link->conf.Vcc = config.Vcc; tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } i = next_tuple(handle, tuple, parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } i = next_tuple(handle, tuple, parse); } } if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); rc = -1; goto free_cfg_mem; } i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* Socket Dual IO: this enables irq's for second port */ if (info->multi && (info->manfid == MANFID_SOCKET)) { link->conf.Present |= PRESENT_EXT_STATUS; link->conf.ExtStatus = ESR_REQ_ATTN_ENA; } i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); rc = -1; goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 8 registers are for the UART, the others are extra registers */ if (info->manfid == MANFID_OXSEMI) { if (cf->index == 1 || cf->index == 3) { setup_serial(handle, info, base2, link->irq.AssignedIRQ); outb(12, link->io.BasePort1 + 1); } else { setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); outb(12, base2 + 1); } rc = 0; goto free_cfg_mem; } setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) { rc = 0; goto free_cfg_mem; } for (i = 0; i < info->multi - 1; i++) setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ); rc = 0; free_cfg_mem: kfree(cfg_mem); return rc; }
static void btuart_config(dev_link_t *link) { static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; client_handle_t handle = link->handle; btuart_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; config_info_t config; int i, j, try, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; last_ret = first_tuple(handle, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; i = pcmcia_get_configuration_info(handle, &config); link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(handle, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { BT_ERR("No usable port range found"); cs_error(link->handle, RequestIO, i); goto failed; } i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); goto failed; } if (btuart_open(info) != 0) goto failed; strcpy(info->node.dev_name, info->hdev->name); link->dev = &info->node; link->state &= ~DEV_CONFIG_PENDING; return; cs_failed: cs_error(link->handle, last_fn, last_ret); failed: btuart_release(link); }
static int avma1cs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u_char buf[64]; char devname[128]; IsdnCard_t icard; int busy = 0; dev = link->priv; DEBUG(0, "avma1cs_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = pcmcia_get_first_tuple(link, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = pcmcia_get_tuple_data(link, &tuple); if (i != CS_SUCCESS) break; i = pcmcia_parse_tuple(link, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { cs_error(link, ParseTuple, i); return -ENODEV; } do { tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1 - 1); i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); break; } /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); break; } /* * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ strcpy(dev->node.dev_name, "A1"); dev->node.major = 45; dev->node.minor = 0; link->dev_node = &dev->node; /* If any step failed, release any partially configured state */ if (i != 0) { avma1cs_release(link); return -ENODEV; } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", link->io.BasePort1, link->irq.AssignedIRQ); icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = isdnprot; icard.typ = ISDN_CTYPE_A1_PCMCIA; i = hisax_init_pcmcia(link, &busy, &icard); if (i < 0) { printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); avma1cs_release(link); return -ENODEV; } dev->node.minor = i; return 0; } /* avma1cs_config */
static void elsa_cs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; int i, j, last_fn; u_short buf[128]; cistpl_cftable_entry_t *cf = &parse.cftable_entry; DEBUG(0, "elsa_config(0x%p)\n", link); handle = link->handle; dev = link->priv; /* This reads the card's CONFIG tuple to find its configuration registers. */ tuple.DesiredTuple = CISTPL_CONFIG; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; i = first_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } break; } i = next_tuple(handle, &tuple, &parse); } if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", dev->node.dev_name, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10); if (link->conf.Vpp1) printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; elsa_init_pcmcia(link->io.BasePort1, link->irq.AssignedIRQ, &(((local_info_t*)link->priv)->busy), protocol); return; cs_failed: cs_error(link->handle, last_fn, i); elsa_cs_release((u_long)link); } /* elsa_cs_config */
static int avmcs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u_char buf[64]; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); dev = link->priv; do { devname[0] = 0; if (link->prod_id[1]) strlcpy(devname, link->prod_id[1], sizeof(devname)); /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); break; } /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); break; } /* * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ if (devname[0]) { char *s = strrchr(devname, ' '); if (!s) s = devname; else s++; strcpy(dev->node.dev_name, s); if (strcmp("M1", s) == 0) { cardtype = AVM_CARDTYPE_M1; } else if (strcmp("M2", s) == 0) { cardtype = AVM_CARDTYPE_M2; } else { cardtype = AVM_CARDTYPE_B1; } } else { strcpy(dev->node.dev_name, "b1"); cardtype = AVM_CARDTYPE_B1; } dev->node.major = 64; dev->node.minor = 0; link->dev_node = &dev->node; /* If any step failed, release any partially configured state */ if (i != 0) { avmcs_release(link); return -ENODEV; } switch (cardtype) { case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; default: case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; } if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); avmcs_release(link); return -ENODEV; } dev->node.minor = i; return 0; } /* avmcs_config */
static void avmcs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u_char buf[64]; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); handle = link->handle; dev = link->priv; /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = pcmcia_get_first_tuple(handle, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = pcmcia_get_tuple_data(handle, &tuple); if (i != CS_SUCCESS) break; i = pcmcia_parse_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { cs_error(link->handle, ParseTuple, i); link->state &= ~DEV_CONFIG_PENDING; return; } /* Configure card */ link->state |= DEV_CONFIG; do { tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); break; } /* * allocate an interrupt line */ i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); pcmcia_release_io(link->handle, &link->io); break; } /* * configure the PCMCIA socket */ i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ if (devname[0]) { char *s = strrchr(devname, ' '); if (!s) s = devname; else s++; strcpy(dev->node.dev_name, s); if (strcmp("M1", s) == 0) { cardtype = AVM_CARDTYPE_M1; } else if (strcmp("M2", s) == 0) { cardtype = AVM_CARDTYPE_M2; } else { cardtype = AVM_CARDTYPE_B1; } } else { strcpy(dev->node.dev_name, "b1"); cardtype = AVM_CARDTYPE_B1; } dev->node.major = 64; dev->node.minor = 0; link->dev = &dev->node; link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { avmcs_release(link); return; } switch (cardtype) { case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; default: case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; } if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); avmcs_release(link); return; } dev->node.minor = i; } /* avmcs_config */
static int simple_config(dev_link_t *link) { static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; client_handle_t handle = link->handle; serial_info_t *info = link->priv; tuple_t tuple; u_char buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; config_info_t config; int i, j, try; /* If the card is already configured, look up the port and irq */ i = CardServices(GetConfigurationInfo, handle, &config); if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { ioaddr_t port = 0; if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { port = config.BasePort2; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && (config.NumPorts1 == 0x40)) { port = config.BasePort1 + 0x28; info->slave = 1; } if (info->slave) return setup_serial(info, port, config.AssignedIRQ); } link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM]/10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(handle, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); return -1; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); return -1; } return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); }