📄 pcmcia.c
字号:
//==========================================================================//// io/pcmcia/pcmcia.c//// PCMCIA support (Card Services)////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): gthomas// Contributors: gthomas// Date: 2000-07-06// Purpose: PCMCIA support// Description: ////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/io_pcmcia.h>#include <cyg/io/pcmcia.h>#include <cyg/infra/diag.h>#if CYGHWR_IO_PCMCIA_DEVICE == 0#error Need hardware package for PCMCIA support#endif#define CF_NUM_SLOTS CYGHWR_IO_PCMCIA_DEVICEstatic struct cf_slot cf_slots[CF_NUM_SLOTS];// Implementation routinesvoid cf_hwr_init(struct cf_slot *slot);void cf_hwr_change_state(struct cf_slot *slot, int desired_state);void cf_hwr_clear_interrupt(struct cf_slot *slot);boolcf_get_CIS(struct cf_slot *slot, unsigned char id, unsigned char *buf, int *len, int *ptr){ int i, size; unsigned char *cis = slot->attr; unsigned char *cis_end = cis + slot->attr_length; cis += *ptr; while (cis < cis_end) { if (*cis == 0xFF) { break; } if (*cis == id) { size = *(cis+2) + 2; for (i = 0; i < size; i++) { *buf++ = *cis; cis += 2; } *len = size; *ptr = (unsigned long)(cis - slot->attr); return true; } else { // Skip to next entry cis += (*(cis+2) * 2) + 4; } } return false;}voidcf_set_COR(struct cf_slot *slot, unsigned long cor, unsigned char val){ volatile unsigned char *cfg = slot->attr; cfg[cor] = val;}static voidcf_parse_power_structure(unsigned char **buf){ unsigned char *bp = *buf; unsigned char tpce_pd = *bp++; unsigned char settings; int indx; for (indx = 6; indx >= 0; indx--) { if (tpce_pd & (1<<indx)) { settings = *bp++; // main value if (settings & 0x80) { bp++; // extension byte - FIXME } } } *buf = bp;}static voidcf_parse_timing_structure(unsigned char **buf){ unsigned char *bp = *buf; unsigned char tpce_td = *bp++; if ((tpce_td & 0x1C) != 0x1C) {// diag_printf("READY = %x.%x\n",(tpce_td & 0x1C)>>2, *bp); bp++; } if ((tpce_td & 0x03) != 0x03) {// diag_printf("WAIT = %x.%x\n",(tpce_td & 0x03)>>0, *bp); bp++; } *buf = bp;}static voidcf_parse_IO_space_structure(unsigned char **buf, struct cf_io_space *io_space){ unsigned char *bp = *buf; unsigned char tpce_io = *bp++; unsigned char rd; unsigned long base = 0, length = 0; int i; io_space->mode = (tpce_io & 0x60) >> 5; if (tpce_io & 0x80) { rd = *bp++; io_space->num_addrs = (rd & 0x0F) + 1; for (i = 0; i < io_space->num_addrs; i++) { // Address switch ((rd & 0x30) >> 4) { case 0: break; // Not present (shouldn't happen) case 1: base = *bp++; break; case 2: base = (bp[1] << 8) | bp[0]; bp += 2; break; case 3: base = (bp[3] << 24) | (bp[2] << 16) | (bp[1] << 8) | bp[0]; bp += 4; break; } io_space->base[i] = base; // Length switch ((rd & 0xC0) >> 6) { case 0: break; // Not present (shouldn't happen) case 1: length = *bp++; break; case 2: length = (bp[1] << 8) | bp[0]; bp += 2; break; case 3: length = (bp[3] << 24) | (bp[2] << 16) | (bp[1] << 8) | bp[0]; bp += 4; break; } length++; io_space->size[i] = length;// diag_printf("IO addr %d - base: %x, length: %x\n", i, base, length); } } *buf = bp;}boolcf_parse_cftable(unsigned char *buf, int len, struct cf_cftable *cftable){ unsigned char tpce_indx, tpce_fs; if (*buf++ != CF_CISTPL_CFTABLE_ENTRY) { diag_printf("%s - called with invalid CIS: %x\n", __FUNCTION__, *--buf); return false; } buf++; // Skip length/link tpce_indx = *buf++; cftable->cor = tpce_indx & 0x3F; if (tpce_indx & 0x80) { cftable->interface = *buf++; } cftable->feature_select = tpce_fs = *buf++; if (tpce_fs & 0x01) { cf_parse_power_structure(&buf); } if (tpce_fs & 0x02) { cf_parse_power_structure(&buf); } if (tpce_fs & 0x04) { cf_parse_timing_structure(&buf); } if (tpce_fs & 0x08) { cf_parse_IO_space_structure(&buf, &cftable->io_space); } return true;}boolcf_parse_config(unsigned char *buf, int len, struct cf_config *config){ unsigned char tpcc_sz; int i; if (*buf++ != CF_CISTPL_CONFIG) { diag_printf("%s - called with invalid CIS: %x\n", __FUNCTION__, *--buf); return false; } buf++; // Skip length/link tpcc_sz = *buf++; buf++; // Skip 'last' pointer config->base = 0; for (i = (tpcc_sz & 0x03); i >= 0; i--) { config->base = (config->base << 8) | buf[i]; } buf += (tpcc_sz & 0x03) + 1; config->mask_length = ((tpcc_sz & 0x3C) >> 2) + 1; for (i = 0; i < config->mask_length; i++) { config->mask[i] = *buf++; } return true;}//// Return a pointer to the slot descriptor for a given slot//struct cf_slot *cf_get_slot(int indx){ if ((indx >= 0) && (indx < CF_NUM_SLOTS)) { return &cf_slots[indx]; } else { diag_printf("PCMCIA: Invalid slot %d\n", indx); return (struct cf_slot *)0; }}//// Initialize all PCMCIA (Compact Flash) slots//voidcf_init(void){ int i; for (i = 0; i < CF_NUM_SLOTS; i++) { cf_slots[i].index = i; cf_hwr_init(&cf_slots[i]); }}//// Transition a card/slot//voidcf_change_state(struct cf_slot *slot, int desired_state){ cf_hwr_change_state(slot, desired_state);}//// Register an interrupt handler//void cf_register_handler(struct cf_slot *slot, void (*handler)(int, int, void *), void *param){ slot->irq_handler.handler = handler; slot->irq_handler.param = param;}//// Allow interrupt function to acknowledge interrupt//voidcf_clear_interrupt(struct cf_slot *slot){ cf_hwr_clear_interrupt(slot);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -