// bus reset handler, update bus generation int my_bus_reset_handler(raw1394handle_t h, unsigned int gen) { nodeid_t id = raw1394_get_local_id(h); std::cout << "Reset bus to gen " << gen << " local id " << id << std::endl; // update handle gen value raw1394_update_generation(h, gen); }
/* * When an ieee1394 bus reset happens, usually a device has been removed * or added. We send a message on the message bus with the node count * and whether the capture device used in this element connected, disconnected * or was unchanged * Message structure: * nodecount - integer with number of nodes on bus * current-device-change - integer (1 if device connected, 0 if no change to * current device status, -1 if device disconnected) */ static int gst_hdv1394src_bus_reset (raw1394handle_t handle, unsigned int generation) { GstHDV1394Src *src; gint nodecount; GstMessage *message; GstStructure *structure; gint current_device_change; gint i; src = gst_hdv1394src_from_raw1394handle (handle); GST_INFO_OBJECT (src, "have bus reset"); /* update generation - told to do so by docs */ raw1394_update_generation (handle, generation); nodecount = raw1394_get_nodecount (handle); /* allocate memory for portinfo */ /* current_device_change is -1 if camera disconnected, 0 if other device * connected or 1 if camera has now connected */ current_device_change = -1; for (i = 0; i < nodecount; i++) { if (src->guid == rom1394_get_guid (handle, i)) { /* Camera is with us */ GST_DEBUG ("Camera is with us"); if (!src->connected) { current_device_change = 1; src->connected = TRUE; } else current_device_change = 0; } } if (src->connected && current_device_change == -1) { GST_DEBUG ("Camera has disconnected"); src->connected = FALSE; } else if (!src->connected && current_device_change == -1) { GST_DEBUG ("Camera is still not with us"); current_device_change = 0; } structure = gst_structure_new ("ieee1394-bus-reset", "nodecount", G_TYPE_INT, nodecount, "current-device-change", G_TYPE_INT, current_device_change, NULL); message = gst_message_new_element (GST_OBJECT (src), structure); gst_element_post_message (GST_ELEMENT (src), message); return 0; }
/* bus reset handler checks if device is still on the bus. if it is removed -> set device_present to 0 . bandwidth and channel are remotely freed on bus reset if device still present -> reallocate bw and channel -> channel is not guarranted to be the same after reallocation -> set new channel to camera if changed */ int dcam_busreset_handler( raw1394handle_t raw1394handle, unsigned int generation ) { dcam_handle_t dcamhandle = ( dcam_handle_t ) raw1394_get_userdata( raw1394handle ); int port; int channel; raw1394_update_generation( raw1394handle, generation ); // check if the device is still there or if it has changed if( _dcam_find_device( &dcamhandle->unicap_device, &port, &dcamhandle->node, &dcamhandle->directory ) != STATUS_SUCCESS ) { dcamhandle->device_present = 0; dcam_device_removed_event( dcamhandle ); return 0; } // what happens if a PC-Card is removed ? does this change the port??? if( port != dcamhandle->port ) { if( raw1394_set_port( raw1394handle, port ) < 0 ) { dcamhandle->device_present = 0; dcam_device_removed_event( dcamhandle ); return 0; } dcamhandle->port = port; } // reallocate bandwidth // ( reallocation should always succeed ) if( dcamhandle->allocate_bandwidth ) { if( !SUCCESS(_1394util_allocate_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ) ) ) { TRACE( "dcam.cpi: failed to reallocate bandwidth\n" ); dcam_capture_stop( dcamhandle ); return 0; } } // channel is freed on busreset // -> reallocate channel // check if newly allocated channel matches previous channel // -> conditionaly set new channel on the camera if( !SUCCESS(_1394util_allocate_channel(dcamhandle->raw1394handle, dcamhandle->channel_allocated ) ) ) { if( ( channel = _1394util_find_free_channel( dcamhandle->raw1394handle ) ) < 0 ) { TRACE( "dcam.cpi: failed to allocate channel\n"); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); dcam_capture_stop( dcamhandle ); return 0; } if( channel != dcamhandle->channel_allocated ) { quadlet_t quad = 0; if( dcam_isoch_table[dcamhandle->current_iso_index].min_speed <= S400 ) { quad = ( channel << 28 ) | ( S400 << 24 ); } else { quad = ( channel << 28 ) | ( dcam_isoch_table[dcamhandle->current_iso_index].min_speed << 24 ); } if( _dcam_write_register( dcamhandle->raw1394handle, dcamhandle->node, dcamhandle->command_regs_base + 0x60c, quad ) < 0 ) { _1394util_free_channel( dcamhandle->raw1394handle, channel ); _1394util_free_bandwidth( dcamhandle->raw1394handle, dcam_isoch_table[dcamhandle->current_iso_index].bytes_per_packet ); return 0; } } } return 0; }
static int bus_reset_default(struct raw1394_handle *handle, unsigned int gen) { raw1394_update_generation(handle, gen); return 0; }