// set up default device ID static void GetDefaultDeviceName(BYTE * dn, const BYTE * sn, const struct connection_in * in) { switch (get_busmode(in)) { case bus_tester: // "bus number" dn[1] = BYTE_MASK(in->master.tester.index >> 0) ; dn[2] = BYTE_MASK(in->master.tester.index >> 8) ; // repeat family code dn[3] = sn[0] ; // family code complement dn[4] = BYTE_INVERSE(sn[0]) ; // "device" number dn[5] = BYTE_MASK(DirblobElements(&(in->master.fake.main)) >> 0) ; dn[6] = BYTE_MASK(DirblobElements(&(in->master.fake.main)) >> 8) ; break ; case bus_fake: case bus_mock: default: // only for compiler warning dn[1] = BYTE_MASK(rand()) ; dn[2] = BYTE_MASK(rand()) ; dn[3] = BYTE_MASK(rand()) ; dn[4] = BYTE_MASK(rand()) ; dn[5] = BYTE_MASK(rand()) ; dn[6] = BYTE_MASK(rand()) ; break ; } }
static enum e_visibility VISIBLE_HA5( const struct parsedname * pn ) { switch ( get_busmode(pn->selected_connection) ) { case bus_ha5: return visible_now ; default: return visible_not_now ; } }
static ZERO_OR_ERROR FS_r_PPM(struct one_wire_query *owq) { struct connection_in * in = PN(owq)->selected_connection ; switch ( get_busmode(in) ) { case bus_i2c: OWQ_Y(owq) = ( (in->master.i2c.configreg & DS2482_REG_CFG_PPM) != 0x00 ) ; return 0; default: return -ENOTSUP ; } }
static ZERO_OR_ERROR FS_r_APU(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); switch ( get_busmode(pn->selected_connection) ) { case bus_i2c: OWQ_Y(owq) = ( (pn->selected_connection->master.i2c.configreg & DS2482_REG_CFG_APU) != 0x00 ) ; return 0; default: return -ENOTSUP ; } }
static enum e_visibility VISIBLE_PSEUDO( const struct parsedname * pn ) { switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_tester: case bus_mock: return visible_now ; default: return visible_not_now ; } }
static enum e_visibility VISIBLE_DS2480B( const struct parsedname * pn ) { switch ( get_busmode(pn->selected_connection) ) { case bus_serial: case bus_xport: case bus_pbm: return visible_now ; default: return visible_not_now ; } }
/* * Value is between 0 and 7. * Default value is 3. * * PARMSET_Slew15Vus 0x0 * PARMSET_Slew2p20Vus 0x1 * PARMSET_Slew1p65Vus 0x2 * PARMSET_Slew1p37Vus 0x3 (default with altUSB) * PARMSET_Slew1p10Vus 0x4 * PARMSET_Slew0p83Vus 0x5 (default without altUSB) * PARMSET_Slew0p70Vus 0x6 * PARMSET_Slew0p55Vus 0x7 */ static ZERO_OR_ERROR FS_r_pulldownslewrate(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if (get_busmode(pn->selected_connection) != bus_usb) { return -ENOTSUP; #if OW_USB } else { OWQ_U(owq) = pn->selected_connection->master.usb.pulldownslewrate; #endif /* OW_USB */ } return 0; }
/* * Value is between 8 and 15, which represents 8us and 15us. * Default value is 10us. (with altUSB) * Default value is 12us. (without altUSB) */ static ZERO_OR_ERROR FS_r_writeonelowtime(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if (get_busmode(pn->selected_connection) != bus_usb) { OWQ_U(owq) = 10; #if OW_USB } else { OWQ_U(owq) = pn->selected_connection->master.usb.writeonelowtime + 8; #endif /* OW_USB */ } return 0; }
/* * Value is between 3 and 10, which represents 3us and 10us. * Default value is 8us. (with altUSB) * Default value is 7us. (without altUSB) */ static ZERO_OR_ERROR FS_r_datasampleoffset(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if (get_busmode(pn->selected_connection) != bus_usb) { OWQ_U(owq) = 8; #if OW_USB } else { OWQ_U(owq) = pn->selected_connection->master.usb.datasampleoffset + 3; #endif /* OW_USB */ } return 0; }
/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_Dir(const struct dirblob *db, const struct parsedname *pn) { time_t duration = TimeOut(fc_directory); struct tree_node *tn; size_t size = DirblobElements(db) * SERIAL_NUMBER_SIZE; struct parsedname pn_directory; if (pn==NO_PARSEDNAME || pn->selected_connection==NO_CONNECTION) { return gbGOOD; // do check here to avoid needless processing } switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_tester: case bus_mock: case bus_w1: case bus_bad: case bus_unknown: return gbGOOD ; default: break ; } if (duration <= 0) { return 0; /* in case timeout set to 0 */ } if ( DirblobElements(db) < 1 ) { // only cache long directories. // zero (or one?) entry is possibly an error and needs to be repeated more quickly LEVEL_DEBUG("Won\'t cache empty directory"); Cache_Del_Dir( pn ) ; return gbGOOD ; } // allocate space for the node and data tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size); if (!tn) { return gbBAD; } LEVEL_DEBUG("Adding directory for " SNformat " elements=%d", SNvar(pn->sn), DirblobElements(db)); // populate node with directory name and dirblob FS_LoadDirectoryOnly(&pn_directory, pn); LoadTK( pn_directory.sn, Directory_Marker, pn->selected_connection->index, tn ); tn->expires = duration + NOW_TIME; tn->dsize = size; if (size) { memcpy(TREE_DATA(tn), db->snlist, size); } return Add_Stat(&cache_dir, Cache_Add_Common(tn)); }
/* fake adapter temperature limits */ static ZERO_OR_ERROR FS_r_templimit(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_mock: case bus_tester: OWQ_F(owq) = pn->selected_filetype->data.i ? pn->selected_connection->master.fake.templow : pn->selected_connection->master.fake.temphigh; return 0; default: return -ENOTSUP ; } }
/* Serial baud rate */ static ZERO_OR_ERROR FS_r_baud(struct one_wire_query *owq) { struct connection_in * in = PN(owq)->selected_connection ; switch ( get_busmode(in) ) { case bus_serial: case bus_link: case bus_ha5: case bus_ha7e: case bus_pbm: OWQ_U(owq) = COM_BaudRate( in->pown->baud ) ; return 0; default: return -ENOTSUP ; } }
static ZERO_OR_ERROR FS_w_baud(struct one_wire_query *owq) { struct connection_in * in = PN(owq)->selected_connection ; switch ( get_busmode(in) ) { case bus_serial: case bus_link: case bus_pbm: in->pown->baud = COM_MakeBaud( (speed_t) OWQ_U(owq) ) ; ++in->changed_bus_settings ; break ; default: break ; } return 0 ; }
static ZERO_OR_ERROR FS_w_APU(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); switch ( get_busmode(pn->selected_connection) ) { case bus_i2c: if ( OWQ_Y(owq) ) { pn->selected_connection->master.i2c.configreg |= DS2482_REG_CFG_APU ; } else { pn->selected_connection->master.i2c.configreg &= ~DS2482_REG_CFG_APU ; } break ; default: break ; } return 0 ; }
static ZERO_OR_ERROR FS_w_PPM(struct one_wire_query *owq) { struct connection_in * in = PN(owq)->selected_connection ; switch ( get_busmode(in) ) { case bus_i2c: if ( OWQ_Y(owq) ) { in->master.i2c.configreg |= DS2482_REG_CFG_PPM ; } else { in->master.i2c.configreg &= ~DS2482_REG_CFG_PPM ; } break ; default: break ; } return 0 ; }
static ZERO_OR_ERROR FS_w_datasampleoffset(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if (get_busmode(pn->selected_connection) != bus_usb){ return -ENOTSUP; } #if OW_USB if ((OWQ_U(owq) < 3) || (OWQ_U(owq) > 10)) { return -ENOTSUP; } pn->selected_connection->master.usb.datasampleoffset = OWQ_U(owq) - 3; pn->selected_connection->changed_bus_settings |= CHANGED_USB_OFFSET; // force a reset #endif /* OW_USB */ return 0; }
static ZERO_OR_ERROR FS_w_writeonelowtime(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if (get_busmode(pn->selected_connection) != bus_usb) { return -ENOTSUP; } #if OW_USB if ((OWQ_U(owq) < 8) || (OWQ_U(owq) > 15)) { return -ENOTSUP; } pn->selected_connection->master.usb.writeonelowtime = OWQ_U(owq) - 8; pn->selected_connection->changed_bus_settings |= CHANGED_USB_LOW ; // force a reset #endif /* OW_USB */ return 0; }
static ZERO_OR_ERROR FS_w_pulldownslewrate(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); if (get_busmode(pn->selected_connection) != bus_usb) { return -ENOTSUP; } #if OW_USB if (OWQ_U(owq) > 7) { return -ENOTSUP; } pn->selected_connection->master.usb.pulldownslewrate = OWQ_U(owq); pn->selected_connection->changed_bus_settings |= CHANGED_USB_SLEW ; // force a reset LEVEL_DEBUG("Set slewrate to %d", pn->selected_connection->master.usb.pulldownslewrate); #endif /* OW_USB */ return 0; }
static ZERO_OR_ERROR FS_w_templimit(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_mock: case bus_tester: if (pn->selected_filetype->data.i) { pn->selected_connection->master.fake.templow = OWQ_F(owq); } else { pn->selected_connection->master.fake.temphigh = OWQ_F(owq); } return 0; default: break ; } return 0 ; }
/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_Simul(const enum simul_type type, const struct parsedname *pn) { // Note: pn already points to directory time_t duration = TimeOut(fc_volatile); struct tree_node *tn; if (pn==NO_PARSEDNAME || pn->selected_connection==NO_CONNECTION) { return gbGOOD; // do check here to avoid needless processing } switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_tester: case bus_mock: case bus_bad: case bus_unknown: return gbGOOD ; default: break ; } if (duration <= 0) { return gbGOOD; /* in case timeout set to 0 */ } // allocate space for the node and data LEVEL_DEBUG("Adding for conversion time for "SNformat, SNvar(pn->sn)); tn = (struct tree_node *) owmalloc(sizeof(struct tree_node)); if (!tn) { return gbBAD; } LEVEL_DEBUG(SNformat, SNvar(pn->sn)); // populate node with directory name and dirblob LoadTK( pn->sn, Simul_Marker[type], pn->selected_connection->index, tn) ; LEVEL_DEBUG("Simultaneous add type=%d",type); tn->expires = duration + NOW_TIME; tn->dsize = 0; return Add_Stat(&cache_dir, Cache_Add_Common(tn)); }
void FreeIn(struct connection_in *target) { if (target == NULL) { return; } switch (target->state) { case connection_vacant: break; case connection_pending: if (target->name) { free(target->name); target->name = NULL; } break; case connection_active: switch (get_busmode(target)) { case bus_zero: if (target->connin.tcp.type) free(target->connin.tcp.type); if (target->connin.tcp.domain) free(target->connin.tcp.domain); if (target->connin.tcp.fqdn) free(target->connin.tcp.fqdn); // fall through case bus_server: LEVEL_DEBUG("FreeClientAddr\n"); FreeClientAddr(target); break; default: break; } if (target->name) { free(target->name); target->name = NULL; } #if OW_MT my_pthread_mutex_destroy(&(target->bus_mutex)); #endif } target->state = connection_vacant; }
static ZERO_OR_ERROR FS_r_ds2490status(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); char res[256]; char buffer[ DS9490_getstatus_BUFFER_LENGTH ]; int ret; res[0] = '\0'; if (get_busmode(pn->selected_connection) == bus_usb) { #if OW_USB ret = DS9490_getstatus(buffer, 0, PN(owq)); if (ret < 0) { sprintf(res, "DS9490_getstatus failed: %d\n", ret); } else { sprintf(res, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15]); } /* uchar EnableFlags; uchar OneWireSpeed; uchar StrongPullUpDuration; uchar ProgPulseDuration; uchar PullDownSlewRate; uchar Write1LowTime; uchar DSOW0RecoveryTime; uchar Reserved1; uchar StatusFlags; uchar CurrentCommCmd1; uchar CurrentCommCmd2; uchar CommBufferStatus; // Buffer for COMM commands uchar WriteBufferStatus; // Buffer we write to uchar ReadBufferStatus; // Buffer we read from */ #endif } return OWQ_format_output_offset_and_size_z(res, owq); }
static int IsThisPersistent( const struct parsedname * pn ) { return ( (pn->selected_filetype->change==fc_persistent) || get_busmode(pn->selected_connection)==bus_mock ) ; }
/* If error, try twice more */ static ZERO_OR_ERROR FS_write_real(int depth, struct one_wire_query *owq) { ZERO_OR_ERROR write_or_error; struct parsedname *pn = PN(owq); struct filetype * ft = pn->selected_filetype ; INDEX_OR_ERROR initial_bus = pn->selected_connection->index ; // current selected bus INDEX_OR_ERROR rechecked_bus ; if ( depth > 1 ) { LEVEL_DEBUG("Too many bus changes for write"); return -ENODEV ; } if ( ft->write == FS_w_alias ) { // Special check for alias // it's ok for fake and tester and mock as well // so do this before the fake test // also no need to three-peat. return FS_write_owq(owq) ; } /* Special case for "fake" adapter */ switch (get_busmode(pn->selected_connection)) { case bus_mock: // Mock -- write even "unwritable" to the cache for testing OWQ_Cache_Add(owq) ; // fall through case bus_fake: case bus_tester: return ( ft->write == NO_WRITE_FUNCTION ) ? -ENOTSUP : 0 ; default: // non-virtual devices get handled below break ; } /* First try */ /* in and bus_nr already set */ STAT_ADD1(write_tries[0]); write_or_error = FS_w_given_bus(owq); if ( write_or_error ==0 ) { return 0 ; } /* Second Try */ STAT_ADD1(write_tries[1]); if (SpecifiedBus(pn)) { // The bus number casn't be changed -- it was specified in the path write_or_error = FS_w_given_bus(owq); if ( write_or_error == 0 ) { return 0 ; } // The bus number casn't be changed -- it was specified in the path STAT_ADD1(write_tries[2]); return FS_w_given_bus(owq); } /* Recheck location */ /* if not a specified bus, relook for chip location */ rechecked_bus = ReCheckPresence(pn) ; if ( rechecked_bus < 0 ) { // can't find the location return -ENOENT ; } if ( initial_bus == rechecked_bus ) { // special handling for remote // only repeat if the bus number is wrong // because the remote does the rewrites if (BusIsServer(pn->selected_connection)) { return write_or_error ; } // try again STAT_ADD1(write_tries[1]); write_or_error = FS_w_given_bus(owq); if ( write_or_error == 0 ) { return 0 ; } // third try STAT_ADD1(write_tries[2]); return FS_w_given_bus(owq); } // Changed location retry everything LEVEL_DEBUG("Bus location changed from %d to %d\n",initial_bus,rechecked_bus); return FS_write_real(depth+1,owq); }
/* return 0 if ok */ static ZERO_OR_ERROR FS_w_local(struct one_wire_query *owq) { // Device already locked struct parsedname *pn = PN(owq); struct filetype * ft = pn->selected_filetype ; /* Writable? */ if ( ft->write == NO_WRITE_FUNCTION ) { return -ENOTSUP; } /* Special case for "fake" adapter */ switch (get_busmode(pn->selected_connection)) { case bus_mock: case bus_fake: case bus_tester: return 0 ; default: // non-virtual devices get handled below break ; } /* Non-array? */ if ( ft->ag == NON_AGGREGATE ) { LEVEL_DEBUG("Write a non-array element %s",pn->path); return FS_write_owq(owq); } /* array */ switch ( ft->ag->combined ) { case ag_sparse: // avoid cache return (ft->write) (owq);; case ag_aggregate: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Write an aggregate .BYTE %s",pn->path); return FS_write_owq(owq); case EXTENSION_ALL: LEVEL_DEBUG("Write an aggregate .ALL %s",pn->path); return FS_write_all(owq); default: LEVEL_DEBUG("Write an aggregate element %s",pn->path); return FS_write_a_part(owq) ; } case ag_mixed: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Write a mixed .BYTE %s",pn->path); OWQ_Cache_Del_parts(owq); return FS_write_owq(owq); case EXTENSION_ALL: LEVEL_DEBUG("Write a mixed .ALL %s",pn->path); OWQ_Cache_Del_parts(owq); return FS_write_all(owq); default: LEVEL_DEBUG("Write a mixed element %s",pn->path); OWQ_Cache_Del_ALL(owq); OWQ_Cache_Del_BYTE(owq); return FS_write_owq(owq); } case ag_separate: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Write a separate .BYTE %s",pn->path); return FS_write_as_bits(owq); case EXTENSION_ALL: LEVEL_DEBUG("Write a separate .ALL %s",pn->path); return FS_write_in_parts(owq); default: LEVEL_DEBUG("Write a separate element %s",pn->path); return FS_write_owq(owq); } default: return -ENOENT ; } }