|
|
struct cm_args cm_args ; cm_range_t range ;cm_args.cm_key = key ; cm_args.cm_n = 0 ; cm_args.cm_param = CM_IOADDR ; cm_args.cm_val = &range ; cm_args.cm_vallen = sizeof(struct cm_addr_rng) ;
cm_begin_trans(cm_args.cm_key, RM_READ); if (cm_getval(&cm_args) != 0) { cm_end_trans(cm_args.cm_key); cmn_err(CE_NOTE,"e3Dverify: IOADDR not found in resmgr\n"); return(ENODEV); } cm_end_trans(cm_args.cm_key);
if ( e3Dpresent(&e3Dtmpdevice, 1) == TRUE ) { /* we don't need the memory mapping any more */ if (e3Dtmpdevice.ex_rambase) { devmem_mapout(e3Dtmpdevice.ex_rambase, e3Dtmpdevice.ex_memsize); e3Dtmpdevice.ex_rambase = (caddr_t) 0; } ... if (e3Dtmpdevice.ex_rambase) { /* e3Dpresent returned false. free devmem_mapin'd memory */ devmem_mapout(e3Dtmpdevice.ex_rambase, e3Dtmpdevice.ex_memsize); e3Dtmpdevice.ex_rambase = (caddr_t) 0; }return(ENODEV);
if (getset == MDI_ISAVERIFY_TRADITIONAL) { /* * Probably called from the dcu. * We have already confirmed that the board is * present at the io address given by CM_IOADDR * in the resmgr in e3Dpresent so we know there * is a board at this address. Return success * as this is all the traditional verify * routine does. */ return(0); } else if (getset == MDI_ISAVERIFY_GET) { /* * Retrieve parameters from firmware, set * custom parameters in resmgr, call * mdi_AT_verify again with updated information, * and return 0. * We've already read EEPROM information by * calling e3Dpresent */cm_args.cm_key = key ; cm_args.cm_n = 0 ; cm_args.cm_val = &answer ; cm_args.cm_vallen = strlen(answer)+1 ; /* * ex_bnc is 0 for AUI or HROM_BNC(0x80) for * other. The bcfg file says '0' is * BNC/TP and '1' is AUI. */
/* cm_param must be less than 11 chars */ cm_args.cm_param = "CABLETYPE"; answer[0] = (e3Dtmpdevice.ex_bnc == 0 ? '1' : '0');
cm_begin_trans(cm_args.cm_key, RM_RDWR); (void) cm_delval(&cm_args); if (cm_addval(&cm_args)) { cm_abort_trans(cm_args.cm_key); cmn_err(CE_WARN,"e3Dverify: cm_addval for CABLETYPE at key %d failed", key); return(ENODEV); } cm_end_trans(cm_args.cm_key); ... sioa = e3Dtmpdevice.ex_ioaddr; eioa = e3Dtmpdevice.ex_ioaddr + 0xf; /* * if your board/bcfg uses 2 for the irq you * should translate it to 9 here */ vector = e3Dtmpdevice.ex_int; scma = (ulong_t) e3Dtmpdevice.ex_base; ecma = (ulong_t) e3Dtmpdevice.ex_base + e3Dtmpdevice.ex_memsize - 1;
/* * We have filled in the custom parameters and * other ISA parameters. Tell ndcfg about them. * We set DMA to null as we don't need it. * Only call mdi_AT_verify after all custom * parameters have been added to the resmgr. */ getset = MDI_ISAVERIFY_GET_REPLY; err = mdi_AT_verify(key, &getset, &sioa, &eioa, &vector, &scma, &ecma, NULL);
if (err != 0) { cmn_err(CE_CONT,"e3Dverify: mdi_AT_verify returned %d",err); return(ENODEV); } return(0);
} else if (getset == MDI_ISAVERIFY_SET) { extern void e3Dconfigure(e3Ddev_t *);
/* * set the eeprom/nvram to parameters indicated by * those returned from mdi_AT_verify. If the parameter * is -1 then it shouldn't change from its current * value. Note we must read custom parameters from * the resmgr by calling cm_getval explicitly */
if (sioa != -1) { e3Dtmpdevice.ex_ioaddr = sioa; }
/* irq 2 and 9 are the same on isa machines */ if (vector != -1) { e3Dtmpdevice.ex_int = vector; } if (scma != -1 && ecma != -1) { e3Dtmpdevice.ex_base = (caddr_t) scma; e3Dtmpdevice.ex_memsize = ecma+1-scma; } /* now get custom parameters */ cm_args.cm_key = key; cm_args.cm_n = 0; cm_args.cm_val = &answer; cm_args.cm_vallen = sizeof(answer); cm_args.cm_param = "CABLETYPE"; /* less than 11 chars */
/* * If the custom parameter shouldn't change, it may not * be set in the resmgr. Don't error, continue on to * next parameter. */ ... /* * There is no way to change the ROM base address * or ROM size. We'll set its size to 0 so as not * to interfere with anything else on the system. */ e3Dtmpdevice.ex_romsize = 0;
/* * We must call cm_AT_putconf again to indicate the new * settings at the key. if we are modifying an existing * board this is not an issue as the specific parameter * will already have been changed by ndcfg but if we * are adding a new board this is necessary. Why? * The order is as follows: * 1) netcfg issues the 'idinstall' command to ndcfg * 2) ndcfg creates new key(we're ISA), populates with * all information necessary * 3) ndcfg idinstalls the driver * 4) ndcfg loads the driver. This calls our init * routine which calls cm_AT_putconf giving it * the firmware's current arguments, not necessarily * what the user wanted to use. * 5) ndcfg calls our verify routine with * MDI_ISAVERIFY_SET telling us to reprogram * firmware. Ok, we will do that, but the resmgr * still has old values, which are wrong. * Of course, this will be taken care of at next boot * since we will call cm_AT_putconf again, but why * prolong the agony? * 6) We reprogram firmware and call cm_AT_putconf * again here, updating the resmgr * 7) ndcfg calls idconfupdate after we return from the * verify routine (in both idinstall and idmodify * cases) If this driver never called cm_AT_putconf * in the init routine then we wouldn't have to call * it again here. Also, since many of these values * may not be set from mdi_AT_verify, we must use * the later of: * a) current firmware * b) modified setting from mdi_AT_verify * in our call to cm_AT_putconf below. * Finally, the key passed to our verify routine is not * the key we need to modify with cm_AT_putconf. * The key to pass to cm_AT_putconf is stored in the * parameter "PUTCONFKEY". This parameter only exists * for MDI_ISAVERIFY_SET mode.
cm_args.cm_key = key; cm_args.cm_n = 0; cm_args.cm_param = "PUTCONFKEY"; cm_args.cm_val = &putconfkey; cm_args.cm_vallen = sizeof(rm_key_t);
cm_begin_trans(cm_args.cm_key, RM_READ); if (cm_getval(&cm_args) != 0) { cm_end_trans(cm_args.cm_key); cmn_err(CE_WARN, "e3Dverify: no PUTCONFKEY at key 0x%x\n", key); return(ENODEV); } cm_end_trans(cm_args.cm_key);
/* update resmgr */ e3Dputconf(putconfkey, &e3Dtmpdevice);
e3Dconfigure(&e3Dtmpdevice); /* update firmware */
return(0); } else { cmn_err(CE_WARN, "!e3Dverify: unknown mode %d\n",getset); return(ENODEV); }
switch(func) { case CFG_ADD: { void **idatap = idata; int unit; struct cm_args cm_args; cm_range_t range; cm_num_t cm_num; char macaddr[18]; /* 22:33:44:55:66:77<NUL> */ e3Ddev_t *dev; extern char *e3Dpartnostr(unsigned char *);/* determine if this instance has been configured with netcfg. While * just a good thing for ISA drivers, calling mdi_get_unit is essential for * ALL smart-bus (PCI, EISA, MCA) drivers - your CFG_ADD code will be * invoked for each instance in the resmgr that has MODNAME set to your * driver(e3D in this example driver). */ if (mdi_get_unit(rmkey, NULL) == B_FALSE) { return(ENXIO); }
``Hotplug devices'' in HDK Technical Reference