/*************************************************************************** * pci_write.c * * Sun Sep 9 15:25:18 2007 * Copyright 2007 Stephen Wille Padnos * swpadnos @ users.sourceforge.net * loosely based on a work by John Kasunich: bfload.c * ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "upci.h" #include "bitfile.h" /* define DEBUG_PRINTS to print info about command line parameters, the detected board, etc. */ #undef DEBUG_PRINTS #define array_size(x) (sizeof(x)/sizeof(x[0])) struct board_info { char *board_type; char *chip_type; unsigned short vendor_id; unsigned short device_id; unsigned short ss_vendor_id; unsigned short ss_device_id; int fpga_pci_region; int upci_devnum; }; struct board_info board_info_table[] = { { "5i20", "2s200pq208", 0x10B5, 0x9030, 0x10B5, 0x3131, 5, 0}, { "5i22-1M", "3s1000fg320", 0x10B5, 0x9054, 0x10B5, 0x3132, 3, 0}, { "5i22-1.5M", "3s1500fg320", 0x10B5, 0x9054, 0x10B5, 0x3131, 3, 0} }; static void errmsg(const char *funct, const char *fmt, ...); static int parse_cmdline(unsigned argc, char *argv[]); /* globals to pass data from command line parser to main */ struct write_var { __u32 *val; /* value */ __u32 minval, maxval; /* allowable range, set them equal for no limit */ char *shortname; /* name of var */ char *longname; /* more descriptive var name for error messages */ }; /* these could have been stored in the struct above, but it's easier to access them this way */ static __u32 cardnum, cardtype, pci_region, pci_offset, value; static struct write_var params[] = { {&cardnum, 0, 15, "cardnum", "Card Number"}, {&cardtype, 0, array_size(board_info_table), "cardtype", "Card Type"}, {&pci_region, 0, 3, "region", "PCI Region"}, {&pci_offset, 0, 65532, "offset", "Region Offset"}, {&value, 0, 0, "value", "Write Value"} }; /* Exit codes */ #define EC_OK 0 /* Exit OK. */ #define EC_BADCL 100 /* Bad command line. */ #define EC_HDW 101 /* Some sort of hardware failure on the 5I20. */ #define EC_FILE 102 /* File error of some sort. */ #define EC_SYS 103 /* Beyond our scope. */ /***********************************************************************/ int main(int argc, char *argv[]) { int data_region, retval; #ifdef DEBUG_PRINTS int dbg; #endif struct upci_dev_info info; struct board_info board; /* if we are setuid, drop privs until needed */ retval = seteuid(getuid()); if (retval != 0) { fprintf(stderr, "failed to set euid to uid %d: %s\n", getuid(), strerror(errno)); return EC_SYS; } if ( parse_cmdline(argc, argv) != EC_OK ) { return EC_BADCL; } #ifdef DEBUG_PRINTS for (dbg=0;dbg \n\n"); printf("All parameters are required.\n"); printf(" - card number (0-15)\n\n"); printf(" - card type. valid types are:\n"); for (i=0;i - which PCI region to write into\n\n"); printf(" - offset into the region\n\n"); printf(" - value to write\n\n"); } static int parse_cmdline(unsigned argc, char *argv[]) { int i; __u32 temp; char *eptr; if (argc != array_size(params)+1) { usage(); return EC_BADCL; } /* loop through the command line parameters and the list of vars */ for (i=0;i params[i].maxval)) { errmsg(__func__,"Parameter %s out of range: %u", params[i].longname, temp); return EC_BADCL; } } *(params[i].val)=temp; } return EC_OK; }