Path: blob/master/drivers/gpib/agilent_82357a/agilent_82357a.c
38184 views
// SPDX-License-Identifier: GPL-2.012/***************************************************************************3* driver for Agilent 82357A/B usb to gpib adapters *4* copyright : (C) 2004 by Frank Mori Hess *5***************************************************************************/67#define _GNU_SOURCE89#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt10#define dev_fmt pr_fmt11#define DRV_NAME KBUILD_MODNAME1213#include <linux/kernel.h>14#include <linux/module.h>15#include <linux/slab.h>16#include "agilent_82357a.h"17#include "gpibP.h"18#include "tms9914.h"1920MODULE_LICENSE("GPL");21MODULE_DESCRIPTION("GPIB driver for Agilent 82357A/B usb adapters");2223#define MAX_NUM_82357A_INTERFACES 12824static struct usb_interface *agilent_82357a_driver_interfaces[MAX_NUM_82357A_INTERFACES];25static DEFINE_MUTEX(agilent_82357a_hotplug_lock); // protect board insertion and removal2627static unsigned int agilent_82357a_update_status(struct gpib_board *board,28unsigned int clear_mask);2930static int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous);3132static void agilent_82357a_bulk_complete(struct urb *urb)33{34struct agilent_82357a_urb_ctx *context = urb->context;3536complete(&context->complete);37}3839static void agilent_82357a_timeout_handler(struct timer_list *t)40{41struct agilent_82357a_priv *a_priv = timer_container_of(a_priv, t,42bulk_timer);43struct agilent_82357a_urb_ctx *context = &a_priv->context;4445context->timed_out = 1;46complete(&context->complete);47}4849static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void *data,50int data_length, int *actual_data_length,51int timeout_msecs)52{53struct usb_device *usb_dev;54int retval;55unsigned int out_pipe;56struct agilent_82357a_urb_ctx *context = &a_priv->context;5758*actual_data_length = 0;59retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock);60if (retval)61return retval;62if (!a_priv->bus_interface) {63mutex_unlock(&a_priv->bulk_alloc_lock);64return -ENODEV;65}66if (a_priv->bulk_urb) {67mutex_unlock(&a_priv->bulk_alloc_lock);68return -EAGAIN;69}70a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);71if (!a_priv->bulk_urb) {72mutex_unlock(&a_priv->bulk_alloc_lock);73return -ENOMEM;74}75usb_dev = interface_to_usbdev(a_priv->bus_interface);76out_pipe = usb_sndbulkpipe(usb_dev, a_priv->bulk_out_endpoint);77init_completion(&context->complete);78context->timed_out = 0;79usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, out_pipe, data, data_length,80&agilent_82357a_bulk_complete, context);8182if (timeout_msecs)83mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));8485retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);86if (retval) {87dev_err(&usb_dev->dev, "failed to submit bulk out urb, retval=%i\n", retval);88mutex_unlock(&a_priv->bulk_alloc_lock);89goto cleanup;90}91mutex_unlock(&a_priv->bulk_alloc_lock);92if (wait_for_completion_interruptible(&context->complete)) {93retval = -ERESTARTSYS;94goto cleanup;95}96if (context->timed_out) {97retval = -ETIMEDOUT;98} else {99retval = a_priv->bulk_urb->status;100*actual_data_length = a_priv->bulk_urb->actual_length;101}102cleanup:103if (timeout_msecs) {104if (timer_pending(&a_priv->bulk_timer))105timer_delete_sync(&a_priv->bulk_timer);106}107mutex_lock(&a_priv->bulk_alloc_lock);108if (a_priv->bulk_urb) {109usb_kill_urb(a_priv->bulk_urb);110usb_free_urb(a_priv->bulk_urb);111a_priv->bulk_urb = NULL;112}113mutex_unlock(&a_priv->bulk_alloc_lock);114return retval;115}116117static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, void *data,118int data_length, int *actual_data_length,119int timeout_msecs)120{121struct usb_device *usb_dev;122int retval;123unsigned int in_pipe;124struct agilent_82357a_urb_ctx *context = &a_priv->context;125126*actual_data_length = 0;127retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock);128if (retval)129return retval;130if (!a_priv->bus_interface) {131mutex_unlock(&a_priv->bulk_alloc_lock);132return -ENODEV;133}134if (a_priv->bulk_urb) {135mutex_unlock(&a_priv->bulk_alloc_lock);136return -EAGAIN;137}138a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);139if (!a_priv->bulk_urb) {140mutex_unlock(&a_priv->bulk_alloc_lock);141return -ENOMEM;142}143usb_dev = interface_to_usbdev(a_priv->bus_interface);144in_pipe = usb_rcvbulkpipe(usb_dev, AGILENT_82357_BULK_IN_ENDPOINT);145init_completion(&context->complete);146context->timed_out = 0;147usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, in_pipe, data, data_length,148&agilent_82357a_bulk_complete, context);149150if (timeout_msecs)151mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));152153retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);154if (retval) {155dev_err(&usb_dev->dev, "failed to submit bulk in urb, retval=%i\n", retval);156mutex_unlock(&a_priv->bulk_alloc_lock);157goto cleanup;158}159mutex_unlock(&a_priv->bulk_alloc_lock);160if (wait_for_completion_interruptible(&context->complete)) {161retval = -ERESTARTSYS;162goto cleanup;163}164if (context->timed_out) {165retval = -ETIMEDOUT;166goto cleanup;167}168retval = a_priv->bulk_urb->status;169*actual_data_length = a_priv->bulk_urb->actual_length;170cleanup:171if (timeout_msecs)172timer_delete_sync(&a_priv->bulk_timer);173174mutex_lock(&a_priv->bulk_alloc_lock);175if (a_priv->bulk_urb) {176usb_kill_urb(a_priv->bulk_urb);177usb_free_urb(a_priv->bulk_urb);178a_priv->bulk_urb = NULL;179}180mutex_unlock(&a_priv->bulk_alloc_lock);181return retval;182}183184static int agilent_82357a_receive_control_msg(struct agilent_82357a_priv *a_priv, __u8 request,185__u8 requesttype, __u16 value, __u16 index,186void *data, __u16 size, int timeout_msecs)187{188struct usb_device *usb_dev;189int retval;190unsigned int in_pipe;191192retval = mutex_lock_interruptible(&a_priv->control_alloc_lock);193if (retval)194return retval;195if (!a_priv->bus_interface) {196mutex_unlock(&a_priv->control_alloc_lock);197return -ENODEV;198}199usb_dev = interface_to_usbdev(a_priv->bus_interface);200in_pipe = usb_rcvctrlpipe(usb_dev, AGILENT_82357_CONTROL_ENDPOINT);201retval = usb_control_msg(usb_dev, in_pipe, request, requesttype, value, index, data,202size, timeout_msecs);203mutex_unlock(&a_priv->control_alloc_lock);204return retval;205}206207static void agilent_82357a_dump_raw_block(const u8 *raw_data, int length)208{209print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true);210}211212static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,213const struct agilent_82357a_register_pairlet *writes,214int num_writes)215{216struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);217int retval;218u8 *out_data, *in_data;219int out_data_length, in_data_length;220int bytes_written, bytes_read;221int i = 0;222int j;223static const int bytes_per_write = 2;224static const int header_length = 2;225static const int max_writes = 31;226227if (num_writes > max_writes) {228dev_err(&usb_dev->dev, "bug! num_writes=%i too large\n", num_writes);229return -EIO;230}231out_data_length = num_writes * bytes_per_write + header_length;232out_data = kmalloc(out_data_length, GFP_KERNEL);233if (!out_data)234return -ENOMEM;235236out_data[i++] = DATA_PIPE_CMD_WR_REGS;237out_data[i++] = num_writes;238for (j = 0; j < num_writes; j++) {239out_data[i++] = writes[j].address;240out_data[i++] = writes[j].value;241}242243retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);244if (retval) {245kfree(out_data);246return retval;247}248retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);249kfree(out_data);250if (retval) {251dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",252retval, bytes_written, i);253mutex_unlock(&a_priv->bulk_transfer_lock);254return retval;255}256in_data_length = 0x20;257in_data = kmalloc(in_data_length, GFP_KERNEL);258if (!in_data) {259mutex_unlock(&a_priv->bulk_transfer_lock);260return -ENOMEM;261}262retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,263&bytes_read, 1000);264mutex_unlock(&a_priv->bulk_transfer_lock);265266if (retval) {267dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",268retval, bytes_read);269agilent_82357a_dump_raw_block(in_data, bytes_read);270kfree(in_data);271return -EIO;272}273if (in_data[0] != (0xff & ~DATA_PIPE_CMD_WR_REGS)) {274dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_WR_REGS\n", in_data[0]);275return -EIO;276}277if (in_data[1]) {278dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_WR_REGS response\n",279in_data[1]);280return -EIO;281}282kfree(in_data);283return 0;284}285286static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,287struct agilent_82357a_register_pairlet *reads,288int num_reads, int blocking)289{290struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);291int retval;292u8 *out_data, *in_data;293int out_data_length, in_data_length;294int bytes_written, bytes_read;295int i = 0;296int j;297static const int header_length = 2;298static const int max_reads = 62;299300if (num_reads > max_reads) {301dev_err(&usb_dev->dev, "bug! num_reads=%i too large\n", num_reads);302return -EIO;303}304out_data_length = num_reads + header_length;305out_data = kmalloc(out_data_length, GFP_KERNEL);306if (!out_data)307return -ENOMEM;308309out_data[i++] = DATA_PIPE_CMD_RD_REGS;310out_data[i++] = num_reads;311for (j = 0; j < num_reads; j++)312out_data[i++] = reads[j].address;313314if (blocking) {315retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);316if (retval) {317kfree(out_data);318return retval;319}320} else {321retval = mutex_trylock(&a_priv->bulk_transfer_lock);322if (retval == 0) {323kfree(out_data);324return -EAGAIN;325}326}327retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);328kfree(out_data);329if (retval) {330dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",331retval, bytes_written, i);332mutex_unlock(&a_priv->bulk_transfer_lock);333return retval;334}335in_data_length = 0x20;336in_data = kmalloc(in_data_length, GFP_KERNEL);337if (!in_data) {338mutex_unlock(&a_priv->bulk_transfer_lock);339return -ENOMEM;340}341retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,342&bytes_read, 10000);343mutex_unlock(&a_priv->bulk_transfer_lock);344345if (retval) {346dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",347retval, bytes_read);348agilent_82357a_dump_raw_block(in_data, bytes_read);349kfree(in_data);350return -EIO;351}352i = 0;353if (in_data[i++] != (0xff & ~DATA_PIPE_CMD_RD_REGS)) {354dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_RD_REGS\n", in_data[0]);355return -EIO;356}357if (in_data[i++]) {358dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_RD_REGS response\n",359in_data[1]);360return -EIO;361}362for (j = 0; j < num_reads; j++)363reads[j].value = in_data[i++];364kfree(in_data);365return 0;366}367368static int agilent_82357a_abort(struct agilent_82357a_priv *a_priv, int flush)369{370struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);371int retval = 0;372int receive_control_retval;373u16 wIndex = 0;374u8 *status_data;375static const unsigned int status_data_len = 2;376377status_data = kmalloc(status_data_len, GFP_KERNEL);378if (!status_data)379return -ENOMEM;380381if (flush)382wIndex |= XA_FLUSH;383receive_control_retval = agilent_82357a_receive_control_msg(a_priv,384agilent_82357a_control_request,385USB_DIR_IN | USB_TYPE_VENDOR |386USB_RECIP_DEVICE, XFER_ABORT,387wIndex, status_data,388status_data_len, 100);389if (receive_control_retval < 0) {390dev_err(&usb_dev->dev, "82357a_receive_control_msg() returned %i\n",391receive_control_retval);392retval = -EIO;393goto cleanup;394}395if (status_data[0] != (~XFER_ABORT & 0xff)) {396dev_err(&usb_dev->dev, "major code=0x%x != ~XFER_ABORT\n", status_data[0]);397retval = -EIO;398goto cleanup;399}400switch (status_data[1]) {401case UGP_SUCCESS:402retval = 0;403break;404case UGP_ERR_FLUSHING:405if (flush) {406retval = 0;407break;408}409fallthrough;410case UGP_ERR_FLUSHING_ALREADY:411default:412dev_err(&usb_dev->dev, "abort returned error code=0x%x\n", status_data[1]);413retval = -EIO;414break;415}416417cleanup:418kfree(status_data);419return retval;420}421422// interface functions423int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length,424size_t *bytes_written);425426static int agilent_82357a_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,427size_t *nbytes)428{429int retval;430struct agilent_82357a_priv *a_priv = board->private_data;431struct usb_device *usb_dev;432u8 *out_data, *in_data;433int out_data_length, in_data_length;434int bytes_written, bytes_read;435int i = 0;436u8 trailing_flags;437unsigned long start_jiffies = jiffies;438int msec_timeout;439440*nbytes = 0;441*end = 0;442443if (!a_priv->bus_interface)444return -ENODEV;445usb_dev = interface_to_usbdev(a_priv->bus_interface);446out_data_length = 0x9;447out_data = kmalloc(out_data_length, GFP_KERNEL);448if (!out_data)449return -ENOMEM;450out_data[i++] = DATA_PIPE_CMD_READ;451out_data[i++] = 0; // primary address when ARF_NO_ADDR is not set452out_data[i++] = 0; // secondary address when ARF_NO_ADDR is not set453out_data[i] = ARF_NO_ADDRESS | ARF_END_ON_EOI;454if (a_priv->eos_mode & REOS)455out_data[i] |= ARF_END_ON_EOS_CHAR;456++i;457out_data[i++] = length & 0xff;458out_data[i++] = (length >> 8) & 0xff;459out_data[i++] = (length >> 16) & 0xff;460out_data[i++] = (length >> 24) & 0xff;461out_data[i++] = a_priv->eos_char;462msec_timeout = (board->usec_timeout + 999) / 1000;463retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);464if (retval) {465kfree(out_data);466return retval;467}468retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, msec_timeout);469kfree(out_data);470if (retval || bytes_written != i) {471dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",472retval, bytes_written, i);473mutex_unlock(&a_priv->bulk_transfer_lock);474if (retval < 0)475return retval;476return -EIO;477}478in_data_length = length + 1;479in_data = kmalloc(in_data_length, GFP_KERNEL);480if (!in_data) {481mutex_unlock(&a_priv->bulk_transfer_lock);482return -ENOMEM;483}484if (board->usec_timeout != 0)485msec_timeout -= jiffies_to_msecs(jiffies - start_jiffies) - 1;486if (msec_timeout >= 0) {487retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,488&bytes_read, msec_timeout);489} else {490retval = -ETIMEDOUT;491bytes_read = 0;492}493if (retval == -ETIMEDOUT) {494int extra_bytes_read;495int extra_bytes_retval;496497agilent_82357a_abort(a_priv, 1);498extra_bytes_retval = agilent_82357a_receive_bulk_msg(a_priv, in_data + bytes_read,499in_data_length - bytes_read,500&extra_bytes_read, 100);501bytes_read += extra_bytes_read;502if (extra_bytes_retval) {503dev_err(&usb_dev->dev, "extra_bytes_retval=%i, bytes_read=%i\n",504extra_bytes_retval, bytes_read);505agilent_82357a_abort(a_priv, 0);506}507} else if (retval) {508dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",509retval, bytes_read);510agilent_82357a_abort(a_priv, 0);511}512mutex_unlock(&a_priv->bulk_transfer_lock);513if (bytes_read > length + 1) {514bytes_read = length + 1;515dev_warn(&usb_dev->dev, "bytes_read > length? truncating");516}517518if (bytes_read >= 1) {519memcpy(buffer, in_data, bytes_read - 1);520trailing_flags = in_data[bytes_read - 1];521*nbytes = bytes_read - 1;522if (trailing_flags & (ATRF_EOI | ATRF_EOS))523*end = 1;524}525kfree(in_data);526527/*528* Fix for a bug in 9914A that does not return the contents of ADSR529* when the board is in listener active state and ATN is not asserted.530* Set ATN here to obtain a valid board level ibsta531*/532agilent_82357a_take_control_internal(board, 0);533534// FIXME check trailing flags for error535return retval;536}537538static ssize_t agilent_82357a_generic_write(struct gpib_board *board,539u8 *buffer, size_t length,540int send_commands, int send_eoi,541size_t *bytes_written)542{543int retval;544struct agilent_82357a_priv *a_priv = board->private_data;545struct usb_device *usb_dev;546u8 *out_data = NULL;547u8 *status_data = NULL;548int out_data_length;549int raw_bytes_written;550int i = 0, j;551int msec_timeout;552unsigned short bsr, adsr;553struct agilent_82357a_register_pairlet read_reg;554555*bytes_written = 0;556if (!a_priv->bus_interface)557return -ENODEV;558559usb_dev = interface_to_usbdev(a_priv->bus_interface);560out_data_length = length + 0x8;561out_data = kmalloc(out_data_length, GFP_KERNEL);562if (!out_data)563return -ENOMEM;564out_data[i++] = DATA_PIPE_CMD_WRITE;565out_data[i++] = 0; // primary address when AWF_NO_ADDRESS is not set566out_data[i++] = 0; // secondary address when AWF_NO_ADDRESS is not set567out_data[i] = AWF_NO_ADDRESS | AWF_NO_FAST_TALKER_FIRST_BYTE;568if (send_commands)569out_data[i] |= AWF_ATN | AWF_NO_FAST_TALKER;570if (send_eoi)571out_data[i] |= AWF_SEND_EOI;572++i;573out_data[i++] = length & 0xff;574out_data[i++] = (length >> 8) & 0xff;575out_data[i++] = (length >> 16) & 0xff;576out_data[i++] = (length >> 24) & 0xff;577for (j = 0; j < length; j++)578out_data[i++] = buffer[j];579580clear_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags);581582msec_timeout = (board->usec_timeout + 999) / 1000;583retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);584if (retval) {585kfree(out_data);586return retval;587}588retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &raw_bytes_written,589msec_timeout);590kfree(out_data);591if (retval || raw_bytes_written != i) {592agilent_82357a_abort(a_priv, 0);593dev_err(&usb_dev->dev, "send_bulk_msg returned %i, raw_bytes_written=%i, i=%i\n",594retval, raw_bytes_written, i);595mutex_unlock(&a_priv->bulk_transfer_lock);596if (retval < 0)597return retval;598return -EIO;599}600601retval = wait_event_interruptible(board->wait,602test_bit(AIF_WRITE_COMPLETE_BN,603&a_priv->interrupt_flags) ||604test_bit(TIMO_NUM, &board->status));605if (retval) {606dev_dbg(&usb_dev->dev, "wait write complete interrupted\n");607agilent_82357a_abort(a_priv, 0);608mutex_unlock(&a_priv->bulk_transfer_lock);609return -ERESTARTSYS;610}611612if (test_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags) == 0) {613dev_dbg(&usb_dev->dev, "write timed out ibs %i, tmo %i\n",614test_bit(TIMO_NUM, &board->status), msec_timeout);615616agilent_82357a_abort(a_priv, 0);617618mutex_unlock(&a_priv->bulk_transfer_lock);619620read_reg.address = BSR;621retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);622if (retval) {623dev_err(&usb_dev->dev, "read_registers() returned error\n");624return -ETIMEDOUT;625}626627bsr = read_reg.value;628dev_dbg(&usb_dev->dev, "write aborted bsr 0x%x\n", bsr);629630if (send_commands) {/* check for no listeners */631if ((bsr & BSR_ATN_BIT) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) {632dev_dbg(&usb_dev->dev, "No listener on command\n");633clear_bit(TIMO_NUM, &board->status);634return -ENOTCONN; // no listener on bus635}636} else {637read_reg.address = ADSR;638retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);639if (retval) {640dev_err(&usb_dev->dev, "read_registers() returned error\n");641return -ETIMEDOUT;642}643adsr = read_reg.value;644if ((adsr & HR_TA) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) {645dev_dbg(&usb_dev->dev, "No listener on write\n");646clear_bit(TIMO_NUM, &board->status);647return -ECOMM;648}649}650651return -ETIMEDOUT;652}653654status_data = kmalloc(STATUS_DATA_LEN, GFP_KERNEL);655if (!status_data) {656mutex_unlock(&a_priv->bulk_transfer_lock);657return -ENOMEM;658}659660retval = agilent_82357a_receive_control_msg(a_priv, agilent_82357a_control_request,661USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,662XFER_STATUS, 0, status_data, STATUS_DATA_LEN,663100);664mutex_unlock(&a_priv->bulk_transfer_lock);665if (retval < 0) {666dev_err(&usb_dev->dev, "receive_control_msg() returned %i\n", retval);667kfree(status_data);668return -EIO;669}670*bytes_written = (u32)status_data[2];671*bytes_written |= (u32)status_data[3] << 8;672*bytes_written |= (u32)status_data[4] << 16;673*bytes_written |= (u32)status_data[5] << 24;674675kfree(status_data);676return 0;677}678679static int agilent_82357a_write(struct gpib_board *board, u8 *buffer,680size_t length, int send_eoi, size_t *bytes_written)681{682return agilent_82357a_generic_write(board, buffer, length, 0, send_eoi, bytes_written);683}684685int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length,686size_t *bytes_written)687{688return agilent_82357a_generic_write(board, buffer, length, 1, 0, bytes_written);689}690691int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous)692{693struct agilent_82357a_priv *a_priv = board->private_data;694struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);695struct agilent_82357a_register_pairlet write;696int retval;697698write.address = AUXCR;699if (synchronous)700write.value = AUX_TCS;701else702write.value = AUX_TCA;703retval = agilent_82357a_write_registers(a_priv, &write, 1);704if (retval)705dev_err(&usb_dev->dev, "write_registers() returned error\n");706707return retval;708}709710static int agilent_82357a_take_control(struct gpib_board *board, int synchronous)711{712struct agilent_82357a_priv *a_priv = board->private_data;713const int timeout = 10;714int i;715716if (!a_priv->bus_interface)717return -ENODEV;718719/*720* It looks like the 9914 does not handle tcs properly.721* See comment above tms9914_take_control_workaround() in722* drivers/gpib/tms9914/tms9914_aux.c723*/724if (synchronous)725return -ETIMEDOUT;726727agilent_82357a_take_control_internal(board, synchronous);728// busy wait until ATN is asserted729for (i = 0; i < timeout; ++i) {730agilent_82357a_update_status(board, 0);731if (test_bit(ATN_NUM, &board->status))732break;733udelay(1);734}735if (i == timeout)736return -ETIMEDOUT;737return 0;738}739740static int agilent_82357a_go_to_standby(struct gpib_board *board)741{742struct agilent_82357a_priv *a_priv = board->private_data;743struct usb_device *usb_dev;744struct agilent_82357a_register_pairlet write;745int retval;746747if (!a_priv->bus_interface)748return -ENODEV;749750usb_dev = interface_to_usbdev(a_priv->bus_interface);751write.address = AUXCR;752write.value = AUX_GTS;753retval = agilent_82357a_write_registers(a_priv, &write, 1);754if (retval)755dev_err(&usb_dev->dev, "write_registers() returned error\n");756return 0;757}758759static int agilent_82357a_request_system_control(struct gpib_board *board, int request_control)760{761struct agilent_82357a_priv *a_priv = board->private_data;762struct usb_device *usb_dev;763struct agilent_82357a_register_pairlet writes[2];764int retval;765int i = 0;766767if (!a_priv->bus_interface)768return -ENODEV;769770usb_dev = interface_to_usbdev(a_priv->bus_interface);771/* 82357B needs bit to be set in 9914 AUXCR register */772writes[i].address = AUXCR;773if (request_control) {774writes[i].value = AUX_RQC;775a_priv->hw_control_bits |= SYSTEM_CONTROLLER;776} else {777return -EINVAL;778}779++i;780writes[i].address = HW_CONTROL;781writes[i].value = a_priv->hw_control_bits;782++i;783retval = agilent_82357a_write_registers(a_priv, writes, i);784if (retval)785dev_err(&usb_dev->dev, "write_registers() returned error\n");786return retval;787}788789static void agilent_82357a_interface_clear(struct gpib_board *board, int assert)790{791struct agilent_82357a_priv *a_priv = board->private_data;792struct usb_device *usb_dev;793struct agilent_82357a_register_pairlet write;794int retval;795796if (!a_priv->bus_interface)797return; // -ENODEV;798799usb_dev = interface_to_usbdev(a_priv->bus_interface);800write.address = AUXCR;801write.value = AUX_SIC;802if (assert) {803write.value |= AUX_CS;804a_priv->is_cic = 1;805}806retval = agilent_82357a_write_registers(a_priv, &write, 1);807if (retval)808dev_err(&usb_dev->dev, "write_registers() returned error\n");809}810811static void agilent_82357a_remote_enable(struct gpib_board *board, int enable)812{813struct agilent_82357a_priv *a_priv = board->private_data;814struct usb_device *usb_dev;815struct agilent_82357a_register_pairlet write;816int retval;817818if (!a_priv->bus_interface)819return; //-ENODEV;820821usb_dev = interface_to_usbdev(a_priv->bus_interface);822write.address = AUXCR;823write.value = AUX_SRE;824if (enable)825write.value |= AUX_CS;826retval = agilent_82357a_write_registers(a_priv, &write, 1);827if (retval)828dev_err(&usb_dev->dev, "write_registers() returned error\n");829a_priv->ren_state = enable;830return;// 0;831}832833static int agilent_82357a_enable_eos(struct gpib_board *board, u8 eos_byte,834int compare_8_bits)835{836struct agilent_82357a_priv *a_priv = board->private_data;837838if (!a_priv->bus_interface)839return -ENODEV;840if (compare_8_bits == 0)841return -EOPNOTSUPP;842843a_priv->eos_char = eos_byte;844a_priv->eos_mode = REOS | BIN;845return 0;846}847848static void agilent_82357a_disable_eos(struct gpib_board *board)849{850struct agilent_82357a_priv *a_priv = board->private_data;851852a_priv->eos_mode &= ~REOS;853}854855static unsigned int agilent_82357a_update_status(struct gpib_board *board,856unsigned int clear_mask)857{858struct agilent_82357a_priv *a_priv = board->private_data;859struct usb_device *usb_dev;860struct agilent_82357a_register_pairlet address_status, bus_status;861int retval;862863if (!a_priv->bus_interface)864return -ENODEV;865usb_dev = interface_to_usbdev(a_priv->bus_interface);866board->status &= ~clear_mask;867if (a_priv->is_cic)868set_bit(CIC_NUM, &board->status);869else870clear_bit(CIC_NUM, &board->status);871address_status.address = ADSR;872retval = agilent_82357a_read_registers(a_priv, &address_status, 1, 0);873if (retval) {874if (retval != -EAGAIN)875dev_err(&usb_dev->dev, "read_registers() returned error\n");876return board->status;877}878// check for remote/local879if (address_status.value & HR_REM)880set_bit(REM_NUM, &board->status);881else882clear_bit(REM_NUM, &board->status);883// check for lockout884if (address_status.value & HR_LLO)885set_bit(LOK_NUM, &board->status);886else887clear_bit(LOK_NUM, &board->status);888// check for ATN889if (address_status.value & HR_ATN)890set_bit(ATN_NUM, &board->status);891else892clear_bit(ATN_NUM, &board->status);893// check for talker/listener addressed894if (address_status.value & HR_TA)895set_bit(TACS_NUM, &board->status);896else897clear_bit(TACS_NUM, &board->status);898if (address_status.value & HR_LA)899set_bit(LACS_NUM, &board->status);900else901clear_bit(LACS_NUM, &board->status);902903bus_status.address = BSR;904retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);905if (retval) {906if (retval != -EAGAIN)907dev_err(&usb_dev->dev, "read_registers() returned error\n");908return board->status;909}910if (bus_status.value & BSR_SRQ_BIT)911set_bit(SRQI_NUM, &board->status);912else913clear_bit(SRQI_NUM, &board->status);914915return board->status;916}917918static int agilent_82357a_primary_address(struct gpib_board *board, unsigned int address)919{920struct agilent_82357a_priv *a_priv = board->private_data;921struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);922struct agilent_82357a_register_pairlet write;923int retval;924925if (!a_priv->bus_interface)926return -ENODEV;927usb_dev = interface_to_usbdev(a_priv->bus_interface);928// put primary address in address0929write.address = ADR;930write.value = address & ADDRESS_MASK;931retval = agilent_82357a_write_registers(a_priv, &write, 1);932if (retval) {933dev_err(&usb_dev->dev, "write_registers() returned error\n");934return retval;935}936return retval;937}938939static int agilent_82357a_secondary_address(struct gpib_board *board,940unsigned int address, int enable)941{942if (enable)943return -EOPNOTSUPP;944return 0;945}946947static int agilent_82357a_parallel_poll(struct gpib_board *board, u8 *result)948{949struct agilent_82357a_priv *a_priv = board->private_data;950struct usb_device *usb_dev;951struct agilent_82357a_register_pairlet writes[2];952struct agilent_82357a_register_pairlet read;953int retval;954955if (!a_priv->bus_interface)956return -ENODEV;957usb_dev = interface_to_usbdev(a_priv->bus_interface);958// execute parallel poll959writes[0].address = AUXCR;960writes[0].value = AUX_CS | AUX_RPP;961writes[1].address = HW_CONTROL;962writes[1].value = a_priv->hw_control_bits & ~NOT_PARALLEL_POLL;963retval = agilent_82357a_write_registers(a_priv, writes, 2);964if (retval) {965dev_err(&usb_dev->dev, "write_registers() returned error\n");966return retval;967}968udelay(2); // silly, since usb write will take way longer969read.address = CPTR;970retval = agilent_82357a_read_registers(a_priv, &read, 1, 1);971if (retval) {972dev_err(&usb_dev->dev, "read_registers() returned error\n");973return retval;974}975*result = read.value;976// clear parallel poll state977writes[0].address = HW_CONTROL;978writes[0].value = a_priv->hw_control_bits | NOT_PARALLEL_POLL;979writes[1].address = AUXCR;980writes[1].value = AUX_RPP;981retval = agilent_82357a_write_registers(a_priv, writes, 2);982if (retval) {983dev_err(&usb_dev->dev, "write_registers() returned error\n");984return retval;985}986return 0;987}988989static void agilent_82357a_parallel_poll_configure(struct gpib_board *board, u8 config)990{991// board can only be system controller992return;// 0;993}994995static void agilent_82357a_parallel_poll_response(struct gpib_board *board, int ist)996{997// board can only be system controller998return;// 0;999}10001001static void agilent_82357a_serial_poll_response(struct gpib_board *board, u8 status)1002{1003// board can only be system controller1004return;// 0;1005}10061007static u8 agilent_82357a_serial_poll_status(struct gpib_board *board)1008{1009// board can only be system controller1010return 0;1011}10121013static void agilent_82357a_return_to_local(struct gpib_board *board)1014{1015// board can only be system controller1016return;// 0;1017}10181019static int agilent_82357a_line_status(const struct gpib_board *board)1020{1021struct agilent_82357a_priv *a_priv = board->private_data;1022struct usb_device *usb_dev;1023struct agilent_82357a_register_pairlet bus_status;1024int retval;1025int status = VALID_ALL;10261027if (!a_priv->bus_interface)1028return -ENODEV;1029usb_dev = interface_to_usbdev(a_priv->bus_interface);1030bus_status.address = BSR;1031retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);1032if (retval) {1033if (retval != -EAGAIN)1034dev_err(&usb_dev->dev, "read_registers() returned error\n");1035return retval;1036}1037if (bus_status.value & BSR_REN_BIT)1038status |= BUS_REN;1039if (bus_status.value & BSR_IFC_BIT)1040status |= BUS_IFC;1041if (bus_status.value & BSR_SRQ_BIT)1042status |= BUS_SRQ;1043if (bus_status.value & BSR_EOI_BIT)1044status |= BUS_EOI;1045if (bus_status.value & BSR_NRFD_BIT)1046status |= BUS_NRFD;1047if (bus_status.value & BSR_NDAC_BIT)1048status |= BUS_NDAC;1049if (bus_status.value & BSR_DAV_BIT)1050status |= BUS_DAV;1051if (bus_status.value & BSR_ATN_BIT)1052status |= BUS_ATN;1053return status;1054}10551056static unsigned short nanosec_to_fast_talker_bits(unsigned int *nanosec)1057{1058static const int nanosec_per_bit = 21;1059static const int max_value = 0x72;1060static const int min_value = 0x11;1061unsigned short bits;10621063bits = (*nanosec + nanosec_per_bit / 2) / nanosec_per_bit;1064if (bits < min_value)1065bits = min_value;1066if (bits > max_value)1067bits = max_value;1068*nanosec = bits * nanosec_per_bit;1069return bits;1070}10711072static int agilent_82357a_t1_delay(struct gpib_board *board, unsigned int nanosec)1073{1074struct agilent_82357a_priv *a_priv = board->private_data;1075struct usb_device *usb_dev;1076struct agilent_82357a_register_pairlet write;1077int retval;10781079if (!a_priv->bus_interface)1080return -ENODEV;1081usb_dev = interface_to_usbdev(a_priv->bus_interface);1082write.address = FAST_TALKER_T1;1083write.value = nanosec_to_fast_talker_bits(&nanosec);1084retval = agilent_82357a_write_registers(a_priv, &write, 1);1085if (retval)1086dev_err(&usb_dev->dev, "write_registers() returned error\n");1087return nanosec;1088}10891090static void agilent_82357a_interrupt_complete(struct urb *urb)1091{1092struct gpib_board *board = urb->context;1093struct agilent_82357a_priv *a_priv = board->private_data;1094struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);1095int retval;1096u8 *transfer_buffer = urb->transfer_buffer;1097unsigned long interrupt_flags;10981099switch (urb->status) {1100/* success */1101case 0:1102break;1103/* unlinked, don't resubmit */1104case -ECONNRESET:1105case -ENOENT:1106case -ESHUTDOWN:1107return;1108default: /* other error, resubmit */1109retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);1110if (retval)1111dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");1112return;1113}11141115interrupt_flags = transfer_buffer[0];1116if (test_bit(AIF_READ_COMPLETE_BN, &interrupt_flags))1117set_bit(AIF_READ_COMPLETE_BN, &a_priv->interrupt_flags);1118if (test_bit(AIF_WRITE_COMPLETE_BN, &interrupt_flags))1119set_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags);1120if (test_bit(AIF_SRQ_BN, &interrupt_flags))1121set_bit(SRQI_NUM, &board->status);11221123wake_up_interruptible(&board->wait);11241125retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);1126if (retval)1127dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");1128}11291130static int agilent_82357a_setup_urbs(struct gpib_board *board)1131{1132struct agilent_82357a_priv *a_priv = board->private_data;1133struct usb_device *usb_dev;1134int int_pipe;1135int retval;11361137retval = mutex_lock_interruptible(&a_priv->interrupt_alloc_lock);1138if (retval)1139return retval;1140if (!a_priv->bus_interface) {1141retval = -ENODEV;1142goto setup_exit;1143}11441145a_priv->interrupt_buffer = kmalloc(INTERRUPT_BUF_LEN, GFP_KERNEL);1146if (!a_priv->interrupt_buffer) {1147retval = -ENOMEM;1148goto setup_exit;1149}1150a_priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL);1151if (!a_priv->interrupt_urb) {1152retval = -ENOMEM;1153goto setup_exit;1154}1155usb_dev = interface_to_usbdev(a_priv->bus_interface);1156int_pipe = usb_rcvintpipe(usb_dev, a_priv->interrupt_in_endpoint);1157usb_fill_int_urb(a_priv->interrupt_urb, usb_dev, int_pipe, a_priv->interrupt_buffer,1158INTERRUPT_BUF_LEN, &agilent_82357a_interrupt_complete, board, 1);1159retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);1160if (retval) {1161usb_free_urb(a_priv->interrupt_urb);1162a_priv->interrupt_urb = NULL;1163dev_err(&usb_dev->dev, "failed to submit first interrupt urb, retval=%i\n", retval);1164goto setup_exit;1165}1166mutex_unlock(&a_priv->interrupt_alloc_lock);1167return 0;11681169setup_exit:1170kfree(a_priv->interrupt_buffer);1171mutex_unlock(&a_priv->interrupt_alloc_lock);1172return retval;1173}11741175static void agilent_82357a_cleanup_urbs(struct agilent_82357a_priv *a_priv)1176{1177if (a_priv && a_priv->bus_interface) {1178if (a_priv->interrupt_urb)1179usb_kill_urb(a_priv->interrupt_urb);1180if (a_priv->bulk_urb)1181usb_kill_urb(a_priv->bulk_urb);1182}1183};11841185static void agilent_82357a_release_urbs(struct agilent_82357a_priv *a_priv)1186{1187if (a_priv) {1188usb_free_urb(a_priv->interrupt_urb);1189a_priv->interrupt_urb = NULL;1190kfree(a_priv->interrupt_buffer);1191}1192}11931194static int agilent_82357a_allocate_private(struct gpib_board *board)1195{1196struct agilent_82357a_priv *a_priv;11971198board->private_data = kzalloc(sizeof(struct agilent_82357a_priv), GFP_KERNEL);1199if (!board->private_data)1200return -ENOMEM;1201a_priv = board->private_data;1202mutex_init(&a_priv->bulk_transfer_lock);1203mutex_init(&a_priv->bulk_alloc_lock);1204mutex_init(&a_priv->control_alloc_lock);1205mutex_init(&a_priv->interrupt_alloc_lock);1206return 0;1207}12081209static void agilent_82357a_free_private(struct gpib_board *board)1210{1211kfree(board->private_data);1212board->private_data = NULL;1213}12141215#define INIT_NUM_REG_WRITES 181216static int agilent_82357a_init(struct gpib_board *board)1217{1218struct agilent_82357a_priv *a_priv = board->private_data;1219struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);1220struct agilent_82357a_register_pairlet hw_control;1221struct agilent_82357a_register_pairlet writes[INIT_NUM_REG_WRITES];1222int retval;1223unsigned int nanosec;12241225writes[0].address = LED_CONTROL;1226writes[0].value = FAIL_LED_ON;1227writes[1].address = RESET_TO_POWERUP;1228writes[1].value = RESET_SPACEBALL;1229retval = agilent_82357a_write_registers(a_priv, writes, 2);1230if (retval) {1231dev_err(&usb_dev->dev, "write_registers() returned error\n");1232return -EIO;1233}1234set_current_state(TASK_INTERRUPTIBLE);1235if (schedule_timeout(usec_to_jiffies(2000)))1236return -ERESTARTSYS;1237writes[0].address = AUXCR;1238writes[0].value = AUX_NBAF;1239writes[1].address = AUXCR;1240writes[1].value = AUX_HLDE;1241writes[2].address = AUXCR;1242writes[2].value = AUX_TON;1243writes[3].address = AUXCR;1244writes[3].value = AUX_LON;1245writes[4].address = AUXCR;1246writes[4].value = AUX_RSV2;1247writes[5].address = AUXCR;1248writes[5].value = AUX_INVAL;1249writes[6].address = AUXCR;1250writes[6].value = AUX_RPP;1251writes[7].address = AUXCR;1252writes[7].value = AUX_STDL;1253writes[8].address = AUXCR;1254writes[8].value = AUX_VSTDL;1255writes[9].address = FAST_TALKER_T1;1256nanosec = board->t1_nano_sec;1257writes[9].value = nanosec_to_fast_talker_bits(&nanosec);1258board->t1_nano_sec = nanosec;1259writes[10].address = ADR;1260writes[10].value = board->pad & ADDRESS_MASK;1261writes[11].address = PPR;1262writes[11].value = 0;1263writes[12].address = SPMR;1264writes[12].value = 0;1265writes[13].address = PROTOCOL_CONTROL;1266writes[13].value = WRITE_COMPLETE_INTERRUPT_EN;1267writes[14].address = IMR0;1268writes[14].value = HR_BOIE | HR_BIIE;1269writes[15].address = IMR1;1270writes[15].value = HR_SRQIE;1271// turn off reset state1272writes[16].address = AUXCR;1273writes[16].value = AUX_CHIP_RESET;1274writes[17].address = LED_CONTROL;1275writes[17].value = FIRMWARE_LED_CONTROL;1276retval = agilent_82357a_write_registers(a_priv, writes, INIT_NUM_REG_WRITES);1277if (retval) {1278dev_err(&usb_dev->dev, "write_registers() returned error\n");1279return -EIO;1280}1281hw_control.address = HW_CONTROL;1282retval = agilent_82357a_read_registers(a_priv, &hw_control, 1, 1);1283if (retval) {1284dev_err(&usb_dev->dev, "read_registers() returned error\n");1285return -EIO;1286}1287a_priv->hw_control_bits = (hw_control.value & ~0x7) | NOT_TI_RESET | NOT_PARALLEL_POLL;12881289return 0;1290}12911292static inline int agilent_82357a_device_match(struct usb_interface *interface,1293const struct gpib_board_config *config)1294{1295struct usb_device * const usbdev = interface_to_usbdev(interface);12961297if (gpib_match_device_path(&interface->dev, config->device_path) == 0)1298return 0;1299if (config->serial_number &&1300strcmp(usbdev->serial, config->serial_number) != 0)1301return 0;13021303return 1;1304}13051306static int agilent_82357a_attach(struct gpib_board *board, const struct gpib_board_config *config)1307{1308int retval;1309int i;1310unsigned int product_id;1311struct agilent_82357a_priv *a_priv;1312struct usb_device *usb_dev;13131314if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock))1315return -ERESTARTSYS;13161317retval = agilent_82357a_allocate_private(board);1318if (retval < 0) {1319mutex_unlock(&agilent_82357a_hotplug_lock);1320return retval;1321}1322a_priv = board->private_data;1323for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {1324if (agilent_82357a_driver_interfaces[i] &&1325!usb_get_intfdata(agilent_82357a_driver_interfaces[i]) &&1326agilent_82357a_device_match(agilent_82357a_driver_interfaces[i], config)) {1327a_priv->bus_interface = agilent_82357a_driver_interfaces[i];1328usb_set_intfdata(agilent_82357a_driver_interfaces[i], board);1329usb_dev = interface_to_usbdev(a_priv->bus_interface);1330break;1331}1332}1333if (i == MAX_NUM_82357A_INTERFACES) {1334dev_err(board->gpib_dev,1335"No supported adapters found, have you loaded its firmware?\n");1336retval = -ENODEV;1337goto attach_fail;1338}1339product_id = le16_to_cpu(interface_to_usbdev(a_priv->bus_interface)->descriptor.idProduct);1340switch (product_id) {1341case USB_DEVICE_ID_AGILENT_82357A:1342a_priv->bulk_out_endpoint = AGILENT_82357A_BULK_OUT_ENDPOINT;1343a_priv->interrupt_in_endpoint = AGILENT_82357A_INTERRUPT_IN_ENDPOINT;1344break;1345case USB_DEVICE_ID_AGILENT_82357B:1346a_priv->bulk_out_endpoint = AGILENT_82357B_BULK_OUT_ENDPOINT;1347a_priv->interrupt_in_endpoint = AGILENT_82357B_INTERRUPT_IN_ENDPOINT;1348break;1349default:1350dev_err(&usb_dev->dev, "bug, unhandled product_id in switch?\n");1351retval = -EIO;1352goto attach_fail;1353}13541355retval = agilent_82357a_setup_urbs(board);1356if (retval < 0)1357goto attach_fail;13581359timer_setup(&a_priv->bulk_timer, agilent_82357a_timeout_handler, 0);13601361board->t1_nano_sec = 800;13621363retval = agilent_82357a_init(board);13641365if (retval < 0) {1366agilent_82357a_cleanup_urbs(a_priv);1367agilent_82357a_release_urbs(a_priv);1368goto attach_fail;1369}13701371dev_info(&usb_dev->dev, "bus %d dev num %d attached to gpib%d, interface %i\n",1372usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);1373mutex_unlock(&agilent_82357a_hotplug_lock);1374return retval;13751376attach_fail:1377agilent_82357a_free_private(board);1378mutex_unlock(&agilent_82357a_hotplug_lock);1379return retval;1380}13811382static int agilent_82357a_go_idle(struct gpib_board *board)1383{1384struct agilent_82357a_priv *a_priv = board->private_data;1385struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);1386struct agilent_82357a_register_pairlet writes[0x20];1387int retval;13881389// turn on tms9914 reset state1390writes[0].address = AUXCR;1391writes[0].value = AUX_CS | AUX_CHIP_RESET;1392a_priv->hw_control_bits &= ~NOT_TI_RESET;1393writes[1].address = HW_CONTROL;1394writes[1].value = a_priv->hw_control_bits;1395writes[2].address = PROTOCOL_CONTROL;1396writes[2].value = 0;1397writes[3].address = IMR0;1398writes[3].value = 0;1399writes[4].address = IMR1;1400writes[4].value = 0;1401writes[5].address = LED_CONTROL;1402writes[5].value = 0;1403retval = agilent_82357a_write_registers(a_priv, writes, 6);1404if (retval) {1405dev_err(&usb_dev->dev, "write_registers() returned error\n");1406return -EIO;1407}1408return 0;1409}14101411static void agilent_82357a_detach(struct gpib_board *board)1412{1413struct agilent_82357a_priv *a_priv;14141415mutex_lock(&agilent_82357a_hotplug_lock);14161417a_priv = board->private_data;1418if (a_priv) {1419if (a_priv->bus_interface) {1420agilent_82357a_go_idle(board);1421usb_set_intfdata(a_priv->bus_interface, NULL);1422}1423mutex_lock(&a_priv->control_alloc_lock);1424mutex_lock(&a_priv->bulk_alloc_lock);1425mutex_lock(&a_priv->interrupt_alloc_lock);1426agilent_82357a_cleanup_urbs(a_priv);1427agilent_82357a_release_urbs(a_priv);1428agilent_82357a_free_private(board);1429}1430mutex_unlock(&agilent_82357a_hotplug_lock);1431}14321433static struct gpib_interface agilent_82357a_gpib_interface = {1434.name = "agilent_82357a",1435.attach = agilent_82357a_attach,1436.detach = agilent_82357a_detach,1437.read = agilent_82357a_read,1438.write = agilent_82357a_write,1439.command = agilent_82357a_command,1440.take_control = agilent_82357a_take_control,1441.go_to_standby = agilent_82357a_go_to_standby,1442.request_system_control = agilent_82357a_request_system_control,1443.interface_clear = agilent_82357a_interface_clear,1444.remote_enable = agilent_82357a_remote_enable,1445.enable_eos = agilent_82357a_enable_eos,1446.disable_eos = agilent_82357a_disable_eos,1447.parallel_poll = agilent_82357a_parallel_poll,1448.parallel_poll_configure = agilent_82357a_parallel_poll_configure,1449.parallel_poll_response = agilent_82357a_parallel_poll_response,1450.local_parallel_poll_mode = NULL, // XXX1451.line_status = agilent_82357a_line_status,1452.update_status = agilent_82357a_update_status,1453.primary_address = agilent_82357a_primary_address,1454.secondary_address = agilent_82357a_secondary_address,1455.serial_poll_response = agilent_82357a_serial_poll_response,1456.serial_poll_status = agilent_82357a_serial_poll_status,1457.t1_delay = agilent_82357a_t1_delay,1458.return_to_local = agilent_82357a_return_to_local,1459.no_7_bit_eos = 1,1460.skip_check_for_command_acceptors = 11461};14621463// Table with the USB-devices: just now only testing IDs1464static struct usb_device_id agilent_82357a_driver_device_table[] = {1465{USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357A)},1466{USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357B)},1467{} /* Terminating entry */1468};1469MODULE_DEVICE_TABLE(usb, agilent_82357a_driver_device_table);14701471static int agilent_82357a_driver_probe(struct usb_interface *interface,1472const struct usb_device_id *id)1473{1474int i;1475char *path;1476static const int path_length = 1024;1477struct usb_device *usb_dev;14781479if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock))1480return -ERESTARTSYS;1481usb_dev = usb_get_dev(interface_to_usbdev(interface));1482for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {1483if (!agilent_82357a_driver_interfaces[i]) {1484agilent_82357a_driver_interfaces[i] = interface;1485usb_set_intfdata(interface, NULL);1486dev_dbg(&usb_dev->dev, "set bus interface %i to address 0x%p\n",1487i, interface);1488break;1489}1490}1491if (i == MAX_NUM_82357A_INTERFACES) {1492usb_put_dev(usb_dev);1493mutex_unlock(&agilent_82357a_hotplug_lock);1494dev_err(&usb_dev->dev, "out of space in agilent_82357a_driver_interfaces[]\n");1495return -1;1496}1497path = kmalloc(path_length, GFP_KERNEL);1498if (!path) {1499usb_put_dev(usb_dev);1500mutex_unlock(&agilent_82357a_hotplug_lock);1501return -ENOMEM;1502}1503usb_make_path(usb_dev, path, path_length);1504dev_info(&usb_dev->dev, "probe succeeded for path: %s\n", path);1505kfree(path);1506mutex_unlock(&agilent_82357a_hotplug_lock);1507return 0;1508}15091510static void agilent_82357a_driver_disconnect(struct usb_interface *interface)1511{1512int i;1513struct usb_device *usb_dev = interface_to_usbdev(interface);15141515mutex_lock(&agilent_82357a_hotplug_lock);15161517for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {1518if (agilent_82357a_driver_interfaces[i] == interface) {1519struct gpib_board *board = usb_get_intfdata(interface);15201521if (board) {1522struct agilent_82357a_priv *a_priv = board->private_data;15231524if (a_priv) {1525mutex_lock(&a_priv->control_alloc_lock);1526mutex_lock(&a_priv->bulk_alloc_lock);1527mutex_lock(&a_priv->interrupt_alloc_lock);1528agilent_82357a_cleanup_urbs(a_priv);1529a_priv->bus_interface = NULL;1530mutex_unlock(&a_priv->interrupt_alloc_lock);1531mutex_unlock(&a_priv->bulk_alloc_lock);1532mutex_unlock(&a_priv->control_alloc_lock);1533}1534}1535agilent_82357a_driver_interfaces[i] = NULL;1536break;1537}1538}1539if (i == MAX_NUM_82357A_INTERFACES)1540dev_err(&usb_dev->dev, "unable to find interface - bug?\n");1541usb_put_dev(usb_dev);15421543mutex_unlock(&agilent_82357a_hotplug_lock);1544}15451546static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_message_t message)1547{1548int i, retval;1549struct usb_device *usb_dev = interface_to_usbdev(interface);15501551mutex_lock(&agilent_82357a_hotplug_lock);15521553for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {1554if (agilent_82357a_driver_interfaces[i] == interface) {1555struct gpib_board *board = usb_get_intfdata(interface);15561557if (board) {1558struct agilent_82357a_priv *a_priv = board->private_data;15591560if (a_priv) {1561agilent_82357a_abort(a_priv, 0);1562agilent_82357a_abort(a_priv, 0);1563retval = agilent_82357a_go_idle(board);1564if (retval) {1565dev_err(&usb_dev->dev, "failed to go idle, retval=%i\n",1566retval);1567mutex_unlock(&agilent_82357a_hotplug_lock);1568return retval;1569}1570mutex_lock(&a_priv->interrupt_alloc_lock);1571agilent_82357a_cleanup_urbs(a_priv);1572mutex_unlock(&a_priv->interrupt_alloc_lock);1573dev_dbg(&usb_dev->dev,1574"bus %d dev num %d gpib %d, interface %i suspended\n",1575usb_dev->bus->busnum, usb_dev->devnum,1576board->minor, i);1577}1578}1579break;1580}1581}15821583mutex_unlock(&agilent_82357a_hotplug_lock);15841585return 0;1586}15871588static int agilent_82357a_driver_resume(struct usb_interface *interface)1589{1590struct usb_device *usb_dev = interface_to_usbdev(interface);1591struct gpib_board *board;1592int i, retval = 0;15931594mutex_lock(&agilent_82357a_hotplug_lock);15951596for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {1597if (agilent_82357a_driver_interfaces[i] == interface) {1598board = usb_get_intfdata(interface);1599if (board)1600break;1601}1602}1603if (i == MAX_NUM_82357A_INTERFACES) {1604retval = -ENOENT;1605goto resume_exit;1606}16071608struct agilent_82357a_priv *a_priv = board->private_data;16091610if (a_priv) {1611if (a_priv->interrupt_urb) {1612mutex_lock(&a_priv->interrupt_alloc_lock);1613retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);1614if (retval) {1615dev_err(&usb_dev->dev, "failed to resubmit interrupt urb in resume, retval=%i\n",1616retval);1617mutex_unlock(&a_priv->interrupt_alloc_lock);1618mutex_unlock(&agilent_82357a_hotplug_lock);1619return retval;1620}1621mutex_unlock(&a_priv->interrupt_alloc_lock);1622}1623retval = agilent_82357a_init(board);1624if (retval < 0) {1625mutex_unlock(&agilent_82357a_hotplug_lock);1626return retval;1627}1628// set/unset system controller1629retval = agilent_82357a_request_system_control(board, board->master);1630// toggle ifc if master1631if (board->master) {1632agilent_82357a_interface_clear(board, 1);1633usleep_range(200, 250);1634agilent_82357a_interface_clear(board, 0);1635}1636// assert/unassert REN1637agilent_82357a_remote_enable(board, a_priv->ren_state);16381639dev_dbg(&usb_dev->dev,1640"bus %d dev num %d gpib%d, interface %i resumed\n",1641usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);1642}16431644resume_exit:1645mutex_unlock(&agilent_82357a_hotplug_lock);16461647return retval;1648}16491650static struct usb_driver agilent_82357a_bus_driver = {1651.name = DRV_NAME,1652.probe = agilent_82357a_driver_probe,1653.disconnect = agilent_82357a_driver_disconnect,1654.suspend = agilent_82357a_driver_suspend,1655.resume = agilent_82357a_driver_resume,1656.id_table = agilent_82357a_driver_device_table,1657};16581659static int __init agilent_82357a_init_module(void)1660{1661int i;1662int ret;16631664for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i)1665agilent_82357a_driver_interfaces[i] = NULL;16661667ret = usb_register(&agilent_82357a_bus_driver);1668if (ret) {1669pr_err("usb_register failed: error = %d\n", ret);1670return ret;1671}16721673ret = gpib_register_driver(&agilent_82357a_gpib_interface, THIS_MODULE);1674if (ret) {1675pr_err("gpib_register_driver failed: error = %d\n", ret);1676usb_deregister(&agilent_82357a_bus_driver);1677return ret;1678}16791680return 0;1681}16821683static void __exit agilent_82357a_exit_module(void)1684{1685gpib_unregister_driver(&agilent_82357a_gpib_interface);1686usb_deregister(&agilent_82357a_bus_driver);1687}16881689module_init(agilent_82357a_init_module);1690module_exit(agilent_82357a_exit_module);169116921693