コード例 #1
0
ファイル: driver.c プロジェクト: AppEngine/linux-2.6
/*
	Asynchronously send part of a raw message.
*/
static int line6_send_raw_message_async_part(struct message *msg,
					     struct urb *urb)
{
	int retval;
	struct usb_line6 *line6 = msg->line6;
	int done = msg->done;
	int bytes = min(msg->size - done, line6->max_packet_size);

	usb_fill_int_urb(urb, line6->usbdev,
			 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
			 (char *)msg->buffer + done, bytes,
			 line6_async_request_sent, msg, line6->interval);

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
#endif

	msg->done += bytes;
	retval = usb_submit_urb(urb, GFP_ATOMIC);

	if (retval < 0) {
		dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
			__func__, retval);
		usb_free_urb(urb);
		kfree(msg);
		return -EINVAL;
	}

	return 0;
}
コード例 #2
0
ファイル: driver.c プロジェクト: AppEngine/linux-2.6
/*
	Transmit Line6 control parameter.
*/
int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
{
	int retval;
	unsigned char *buffer;
	unsigned int partial;

	buffer = kmalloc(3, GFP_KERNEL);

	if (!buffer) {
		dev_err(line6->ifcdev, "out of memory\n");
		return -ENOMEM;
	}

	buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
	buffer[1] = param;
	buffer[2] = value;

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', buffer, 3);
#endif

	retval = usb_interrupt_msg(line6->usbdev,
														 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
														 buffer, 3, &partial, LINE6_TIMEOUT * HZ);

	if (retval)
		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);

	kfree(buffer);
	return retval;
}
コード例 #3
0
ファイル: driver.c プロジェクト: AppEngine/linux-2.6
/*
	Send raw message in pieces of wMaxPacketSize bytes.
*/
int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
			   int size)
{
	int i, done = 0;

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', buffer, size);
#endif

	for (i = 0; i < size; i += line6->max_packet_size) {
		int partial;
		const char *frag_buf = buffer + i;
		int frag_size = min(line6->max_packet_size, size - i);
		int retval;

		retval = usb_interrupt_msg(line6->usbdev,
					   usb_sndintpipe(line6->usbdev,
							  line6->ep_control_write),
					   (char *)frag_buf, frag_size,
					   &partial, LINE6_TIMEOUT * HZ);

		if (retval) {
			dev_err(line6->ifcdev,
				"usb_interrupt_msg failed (%d)\n", retval);
			break;
		}

		done += frag_size;
	}

	return done;
}
コード例 #4
0
ファイル: driver.c プロジェクト: ANFS/ANFS-kernel
/*
	Send channel number (i.e., switch to a different sound).
*/
int line6_send_program(struct usb_line6 *line6, int value)
{
	int retval;
	unsigned char *buffer;
	int partial;

	buffer = kmalloc(2, GFP_KERNEL);

	if (!buffer) {
		dev_err(line6->ifcdev, "out of memory\n");
		return -ENOMEM;
	}

	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
	buffer[1] = value;

#ifdef CONFIG_LINE6_USB_DUMP_CTRL
	line6_write_hexdump(line6, 'S', buffer, 2);
#endif

	retval = usb_interrupt_msg(line6->usbdev,
				   usb_sndintpipe(line6->usbdev,
						  line6->ep_control_write),
				   buffer, 2, &partial, LINE6_TIMEOUT * HZ);

	if (retval)
		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
			retval);

	kfree(buffer);
	return retval;
}
コード例 #5
0
ファイル: driver.c プロジェクト: AppEngine/linux-2.6
/*
	Dump URB data to syslog.
*/
static void line6_dump_urb(struct urb *urb)
{
	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;

	if (urb->status < 0)
		return;

	line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer,
			    urb->actual_length);
}
コード例 #6
0
ファイル: midi.c プロジェクト: CSCLOG/beaglebone
/*
	Read data from MIDI buffer and transmit them via USB.
*/
static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
{
	struct usb_line6 *line6 =
	    line6_rawmidi_substream_midi(substream)->line6;
	struct snd_line6_midi *line6midi = line6->line6midi;
	struct MidiBuffer *mb = &line6midi->midibuf_out;
	unsigned long flags;
	unsigned char chunk[line6->max_packet_size];
	int req, done;

	spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);

	for (;;) {
		req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
		done = snd_rawmidi_transmit_peek(substream, chunk, req);

		if (done == 0)
			break;

#ifdef CONFIG_LINE6_USB_DUMP_MIDI
		line6_write_hexdump(line6, 's', chunk, done);
#endif
		line6_midibuf_write(mb, chunk, done);
		snd_rawmidi_transmit_ack(substream, done);
	}

	for (;;) {
		done = line6_midibuf_read(mb, chunk, line6->max_packet_size);

		if (done == 0)
			break;

		if (line6_midibuf_skip_message
		    (mb, line6midi->midi_mask_transmit))
			continue;

		send_midi_async(line6, chunk, done);
	}

	spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
}
コード例 #7
0
ファイル: midi.c プロジェクト: flwh/Alcatel_OT_985_kernel
static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
			   int length)
{
	struct urb *urb;
	int retval;
	unsigned char *transfer_buffer;

	urb = usb_alloc_urb(0, GFP_ATOMIC);

	if (urb == 0) {
		dev_err(line6->ifcdev, "Out of memory\n");
		return -ENOMEM;
	}

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', data, length);
#endif

	transfer_buffer = kmalloc(length, GFP_ATOMIC);

	if (transfer_buffer == 0) {
		usb_free_urb(urb);
		dev_err(line6->ifcdev, "Out of memory\n");
		return -ENOMEM;
	}

	memcpy(transfer_buffer, data, length);
	usb_fill_int_urb(urb, line6->usbdev,
			 usb_sndbulkpipe(line6->usbdev,
					 line6->ep_control_write),
			 transfer_buffer, length, midi_sent, line6,
			 line6->interval);
	urb->actual_length = 0;
	retval = usb_submit_urb(urb, GFP_ATOMIC);

	if (retval < 0) {
		dev_err(line6->ifcdev, "usb_submit_urb failed\n");
		usb_free_urb(urb);
		return -EINVAL;
	}

	++line6->line6midi->num_active_send_urbs;

	switch (line6->usbdev->descriptor.idProduct) {
	case LINE6_DEVID_BASSPODXT:
	case LINE6_DEVID_BASSPODXTLIVE:
	case LINE6_DEVID_BASSPODXTPRO:
	case LINE6_DEVID_PODXT:
	case LINE6_DEVID_PODXTLIVE:
	case LINE6_DEVID_PODXTPRO:
	case LINE6_DEVID_POCKETPOD:
		pod_midi_postprocess((struct usb_line6_pod *)line6, data,
				     length);
		break;

	default:
		MISSING_CASE;
	}

	return 0;
}
コード例 #8
0
ファイル: driver.c プロジェクト: AppEngine/linux-2.6
/*
	Notification of data received from the Line6 device.
*/
static void line6_data_received(struct urb *urb)
{
	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
	struct MidiBuffer *mb = &line6->line6midi->midibuf_in;
	int done;

	if (urb->status == -ESHUTDOWN)
		return;

#if DO_DUMP_URB_RECEIVE
	line6_dump_urb(urb);
#endif

	done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);

	if (done < urb->actual_length) {
		midibuf_ignore(mb, done);
		DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
	}

	for (;;) {
		done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);

		if (done == 0)
			break;

		/* MIDI input filter */
		if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
			continue;

		line6->message_length = done;
#if DO_DUMP_MIDI_RECEIVE
		line6_write_hexdump(line6, 'r', line6->buffer_message, done);
#endif
		line6_midi_receive(line6, line6->buffer_message, done);

		switch (line6->usbdev->descriptor.idProduct) {
		case LINE6_DEVID_BASSPODXT:
		case LINE6_DEVID_BASSPODXTLIVE:
		case LINE6_DEVID_BASSPODXTPRO:
		case LINE6_DEVID_PODXT:
		case LINE6_DEVID_PODXTPRO:
		case LINE6_DEVID_POCKETPOD:
			pod_process_message((struct usb_line6_pod *)line6);
			break;

		case LINE6_DEVID_PODXTLIVE:
			switch (line6->interface_number) {
			case PODXTLIVE_INTERFACE_POD:
				pod_process_message((struct usb_line6_pod *)line6);
				break;

			case PODXTLIVE_INTERFACE_VARIAX:
				variax_process_message((struct usb_line6_variax *)line6);
				break;

			default:
				dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
			}
			break;

		case LINE6_DEVID_VARIAX:
			variax_process_message((struct usb_line6_variax *)line6);
			break;

		default:
			MISSING_CASE;
		}
	}

	line6_start_listen(line6);
}
コード例 #9
0
ファイル: capture.c プロジェクト: 33d/linux-2.6.21-hh20
/*
 * Callback for completed capture URB.
 */
static void audio_in_callback(struct urb *urb)
{
	int i, index, length = 0, shutdown = 0;
	unsigned long flags;

	struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;

	line6pcm->last_frame_in = urb->start_frame;

	/* find index of URB */
	for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
		if (urb == line6pcm->urb_audio_in[index])
			break;

#ifdef CONFIG_LINE6_USB_DUMP_PCM
	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
		struct usb_iso_packet_descriptor *fout =
		    &urb->iso_frame_desc[i];
		line6_write_hexdump(line6pcm->line6, 'C',
				    urb->transfer_buffer + fout->offset,
				    fout->length);
	}
#endif

	spin_lock_irqsave(&line6pcm->lock_audio_in, flags);

	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
		char *fbuf;
		int fsize;
		struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];

		if (fin->status == -EXDEV) {
			shutdown = 1;
			break;
		}

		fbuf = urb->transfer_buffer + fin->offset;
		fsize = fin->actual_length;

		if (fsize > line6pcm->max_packet_size) {
			dev_err(line6pcm->line6->ifcdev,
				"driver and/or device bug: packet too large (%d > %d)\n",
				fsize, line6pcm->max_packet_size);
		}

		length += fsize;

		/* the following assumes LINE6_ISO_PACKETS == 1: */
		line6pcm->prev_fbuf = fbuf;
		line6pcm->prev_fsize = fsize;

#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
		if (!(line6pcm->flags & MASK_PCM_IMPULSE))
#endif
			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)
			    && (fsize > 0))
				line6_capture_copy(line6pcm, fbuf, fsize);
	}

	clear_bit(index, &line6pcm->active_urb_in);

	if (test_and_clear_bit(index, &line6pcm->unlink_urb_in))
		shutdown = 1;

	spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);

	if (!shutdown) {
		submit_audio_in_urb(line6pcm);

#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
		if (!(line6pcm->flags & MASK_PCM_IMPULSE))
#endif
			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
				line6_capture_check_period(line6pcm, length);
	}
}