| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691 |
- // SPDX-License-Identifier: GPL-2.0
- /***************************************************************************
- * driver for Agilent 82357A/B usb to gpib adapters *
- * copyright : (C) 2004 by Frank Mori Hess *
- ***************************************************************************/
- #define _GNU_SOURCE
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- #define dev_fmt pr_fmt
- #define DRV_NAME KBUILD_MODNAME
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include "agilent_82357a.h"
- #include "gpibP.h"
- #include "tms9914.h"
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("GPIB driver for Agilent 82357A/B usb adapters");
- #define MAX_NUM_82357A_INTERFACES 128
- static struct usb_interface *agilent_82357a_driver_interfaces[MAX_NUM_82357A_INTERFACES];
- static DEFINE_MUTEX(agilent_82357a_hotplug_lock); // protect board insertion and removal
- static unsigned int agilent_82357a_update_status(struct gpib_board *board,
- unsigned int clear_mask);
- static int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous);
- static void agilent_82357a_bulk_complete(struct urb *urb)
- {
- struct agilent_82357a_urb_ctx *context = urb->context;
- complete(&context->complete);
- }
- static void agilent_82357a_timeout_handler(struct timer_list *t)
- {
- struct agilent_82357a_priv *a_priv = timer_container_of(a_priv, t,
- bulk_timer);
- struct agilent_82357a_urb_ctx *context = &a_priv->context;
- context->timed_out = 1;
- complete(&context->complete);
- }
- static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void *data,
- int data_length, int *actual_data_length,
- int timeout_msecs)
- {
- struct usb_device *usb_dev;
- int retval;
- unsigned int out_pipe;
- struct agilent_82357a_urb_ctx *context = &a_priv->context;
- *actual_data_length = 0;
- retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENODEV;
- }
- if (a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -EAGAIN;
- }
- a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- out_pipe = usb_sndbulkpipe(usb_dev, a_priv->bulk_out_endpoint);
- init_completion(&context->complete);
- context->timed_out = 0;
- usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, out_pipe, data, data_length,
- &agilent_82357a_bulk_complete, context);
- if (timeout_msecs)
- mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
- retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to submit bulk out urb, retval=%i\n", retval);
- mutex_unlock(&a_priv->bulk_alloc_lock);
- goto cleanup;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- if (wait_for_completion_interruptible(&context->complete)) {
- retval = -ERESTARTSYS;
- goto cleanup;
- }
- if (context->timed_out) {
- retval = -ETIMEDOUT;
- } else {
- retval = a_priv->bulk_urb->status;
- *actual_data_length = a_priv->bulk_urb->actual_length;
- }
- cleanup:
- if (timeout_msecs) {
- if (timer_pending(&a_priv->bulk_timer))
- timer_delete_sync(&a_priv->bulk_timer);
- }
- mutex_lock(&a_priv->bulk_alloc_lock);
- if (a_priv->bulk_urb) {
- usb_kill_urb(a_priv->bulk_urb);
- usb_free_urb(a_priv->bulk_urb);
- a_priv->bulk_urb = NULL;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return retval;
- }
- static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, void *data,
- int data_length, int *actual_data_length,
- int timeout_msecs)
- {
- struct usb_device *usb_dev;
- int retval;
- unsigned int in_pipe;
- struct agilent_82357a_urb_ctx *context = &a_priv->context;
- *actual_data_length = 0;
- retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENODEV;
- }
- if (a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -EAGAIN;
- }
- a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- in_pipe = usb_rcvbulkpipe(usb_dev, AGILENT_82357_BULK_IN_ENDPOINT);
- init_completion(&context->complete);
- context->timed_out = 0;
- usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, in_pipe, data, data_length,
- &agilent_82357a_bulk_complete, context);
- if (timeout_msecs)
- mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
- retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to submit bulk in urb, retval=%i\n", retval);
- mutex_unlock(&a_priv->bulk_alloc_lock);
- goto cleanup;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- if (wait_for_completion_interruptible(&context->complete)) {
- retval = -ERESTARTSYS;
- goto cleanup;
- }
- if (context->timed_out) {
- retval = -ETIMEDOUT;
- goto cleanup;
- }
- retval = a_priv->bulk_urb->status;
- *actual_data_length = a_priv->bulk_urb->actual_length;
- cleanup:
- if (timeout_msecs)
- timer_delete_sync(&a_priv->bulk_timer);
- mutex_lock(&a_priv->bulk_alloc_lock);
- if (a_priv->bulk_urb) {
- usb_kill_urb(a_priv->bulk_urb);
- usb_free_urb(a_priv->bulk_urb);
- a_priv->bulk_urb = NULL;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return retval;
- }
- static int agilent_82357a_receive_control_msg(struct agilent_82357a_priv *a_priv, __u8 request,
- __u8 requesttype, __u16 value, __u16 index,
- void *data, __u16 size, int timeout_msecs)
- {
- struct usb_device *usb_dev;
- int retval;
- unsigned int in_pipe;
- retval = mutex_lock_interruptible(&a_priv->control_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- mutex_unlock(&a_priv->control_alloc_lock);
- return -ENODEV;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- in_pipe = usb_rcvctrlpipe(usb_dev, AGILENT_82357_CONTROL_ENDPOINT);
- retval = usb_control_msg(usb_dev, in_pipe, request, requesttype, value, index, data,
- size, timeout_msecs);
- mutex_unlock(&a_priv->control_alloc_lock);
- return retval;
- }
- static void agilent_82357a_dump_raw_block(const u8 *raw_data, int length)
- {
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true);
- }
- static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,
- const struct agilent_82357a_register_pairlet *writes,
- int num_writes)
- {
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval;
- u8 *out_data, *in_data;
- int out_data_length, in_data_length;
- int bytes_written, bytes_read;
- int i = 0;
- int j;
- static const int bytes_per_write = 2;
- static const int header_length = 2;
- static const int max_writes = 31;
- if (num_writes > max_writes) {
- dev_err(&usb_dev->dev, "bug! num_writes=%i too large\n", num_writes);
- return -EIO;
- }
- out_data_length = num_writes * bytes_per_write + header_length;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = DATA_PIPE_CMD_WR_REGS;
- out_data[i++] = num_writes;
- for (j = 0; j < num_writes; j++) {
- out_data[i++] = writes[j].address;
- out_data[i++] = writes[j].value;
- }
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return retval;
- }
- in_data_length = 0x20;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,
- &bytes_read, 1000);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- agilent_82357a_dump_raw_block(in_data, bytes_read);
- kfree(in_data);
- return -EIO;
- }
- if (in_data[0] != (0xff & ~DATA_PIPE_CMD_WR_REGS)) {
- dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_WR_REGS\n", in_data[0]);
- return -EIO;
- }
- if (in_data[1]) {
- dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_WR_REGS response\n",
- in_data[1]);
- return -EIO;
- }
- kfree(in_data);
- return 0;
- }
- static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,
- struct agilent_82357a_register_pairlet *reads,
- int num_reads, int blocking)
- {
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval;
- u8 *out_data, *in_data;
- int out_data_length, in_data_length;
- int bytes_written, bytes_read;
- int i = 0;
- int j;
- static const int header_length = 2;
- static const int max_reads = 62;
- if (num_reads > max_reads) {
- dev_err(&usb_dev->dev, "bug! num_reads=%i too large\n", num_reads);
- return -EIO;
- }
- out_data_length = num_reads + header_length;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = DATA_PIPE_CMD_RD_REGS;
- out_data[i++] = num_reads;
- for (j = 0; j < num_reads; j++)
- out_data[i++] = reads[j].address;
- if (blocking) {
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- } else {
- retval = mutex_trylock(&a_priv->bulk_transfer_lock);
- if (retval == 0) {
- kfree(out_data);
- return -EAGAIN;
- }
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return retval;
- }
- in_data_length = 0x20;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,
- &bytes_read, 10000);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- agilent_82357a_dump_raw_block(in_data, bytes_read);
- kfree(in_data);
- return -EIO;
- }
- i = 0;
- if (in_data[i++] != (0xff & ~DATA_PIPE_CMD_RD_REGS)) {
- dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_RD_REGS\n", in_data[0]);
- return -EIO;
- }
- if (in_data[i++]) {
- dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_RD_REGS response\n",
- in_data[1]);
- return -EIO;
- }
- for (j = 0; j < num_reads; j++)
- reads[j].value = in_data[i++];
- kfree(in_data);
- return 0;
- }
- static int agilent_82357a_abort(struct agilent_82357a_priv *a_priv, int flush)
- {
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval = 0;
- int receive_control_retval;
- u16 wIndex = 0;
- u8 *status_data;
- static const unsigned int status_data_len = 2;
- status_data = kmalloc(status_data_len, GFP_KERNEL);
- if (!status_data)
- return -ENOMEM;
- if (flush)
- wIndex |= XA_FLUSH;
- receive_control_retval = agilent_82357a_receive_control_msg(a_priv,
- agilent_82357a_control_request,
- USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, XFER_ABORT,
- wIndex, status_data,
- status_data_len, 100);
- if (receive_control_retval < 0) {
- dev_err(&usb_dev->dev, "82357a_receive_control_msg() returned %i\n",
- receive_control_retval);
- retval = -EIO;
- goto cleanup;
- }
- if (status_data[0] != (~XFER_ABORT & 0xff)) {
- dev_err(&usb_dev->dev, "major code=0x%x != ~XFER_ABORT\n", status_data[0]);
- retval = -EIO;
- goto cleanup;
- }
- switch (status_data[1]) {
- case UGP_SUCCESS:
- retval = 0;
- break;
- case UGP_ERR_FLUSHING:
- if (flush) {
- retval = 0;
- break;
- }
- fallthrough;
- case UGP_ERR_FLUSHING_ALREADY:
- default:
- dev_err(&usb_dev->dev, "abort returned error code=0x%x\n", status_data[1]);
- retval = -EIO;
- break;
- }
- cleanup:
- kfree(status_data);
- return retval;
- }
- // interface functions
- int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written);
- static int agilent_82357a_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *nbytes)
- {
- int retval;
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- int out_data_length, in_data_length;
- int bytes_written, bytes_read;
- int i = 0;
- u8 trailing_flags;
- unsigned long start_jiffies = jiffies;
- int msec_timeout;
- *nbytes = 0;
- *end = 0;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- out_data_length = 0x9;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = DATA_PIPE_CMD_READ;
- out_data[i++] = 0; // primary address when ARF_NO_ADDR is not set
- out_data[i++] = 0; // secondary address when ARF_NO_ADDR is not set
- out_data[i] = ARF_NO_ADDRESS | ARF_END_ON_EOI;
- if (a_priv->eos_mode & REOS)
- out_data[i] |= ARF_END_ON_EOS_CHAR;
- ++i;
- out_data[i++] = length & 0xff;
- out_data[i++] = (length >> 8) & 0xff;
- out_data[i++] = (length >> 16) & 0xff;
- out_data[i++] = (length >> 24) & 0xff;
- out_data[i++] = a_priv->eos_char;
- msec_timeout = (board->usec_timeout + 999) / 1000;
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, msec_timeout);
- kfree(out_data);
- if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval < 0)
- return retval;
- return -EIO;
- }
- in_data_length = length + 1;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- if (board->usec_timeout != 0)
- msec_timeout -= jiffies_to_msecs(jiffies - start_jiffies) - 1;
- if (msec_timeout >= 0) {
- retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,
- &bytes_read, msec_timeout);
- } else {
- retval = -ETIMEDOUT;
- bytes_read = 0;
- }
- if (retval == -ETIMEDOUT) {
- int extra_bytes_read;
- int extra_bytes_retval;
- agilent_82357a_abort(a_priv, 1);
- extra_bytes_retval = agilent_82357a_receive_bulk_msg(a_priv, in_data + bytes_read,
- in_data_length - bytes_read,
- &extra_bytes_read, 100);
- bytes_read += extra_bytes_read;
- if (extra_bytes_retval) {
- dev_err(&usb_dev->dev, "extra_bytes_retval=%i, bytes_read=%i\n",
- extra_bytes_retval, bytes_read);
- agilent_82357a_abort(a_priv, 0);
- }
- } else if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- agilent_82357a_abort(a_priv, 0);
- }
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (bytes_read > length + 1) {
- bytes_read = length + 1;
- dev_warn(&usb_dev->dev, "bytes_read > length? truncating");
- }
- if (bytes_read >= 1) {
- memcpy(buffer, in_data, bytes_read - 1);
- trailing_flags = in_data[bytes_read - 1];
- *nbytes = bytes_read - 1;
- if (trailing_flags & (ATRF_EOI | ATRF_EOS))
- *end = 1;
- }
- kfree(in_data);
- /*
- * Fix for a bug in 9914A that does not return the contents of ADSR
- * when the board is in listener active state and ATN is not asserted.
- * Set ATN here to obtain a valid board level ibsta
- */
- agilent_82357a_take_control_internal(board, 0);
- // FIXME check trailing flags for error
- return retval;
- }
- static ssize_t agilent_82357a_generic_write(struct gpib_board *board,
- u8 *buffer, size_t length,
- int send_commands, int send_eoi,
- size_t *bytes_written)
- {
- int retval;
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data = NULL;
- u8 *status_data = NULL;
- int out_data_length;
- int raw_bytes_written;
- int i = 0, j;
- int msec_timeout;
- unsigned short bsr, adsr;
- struct agilent_82357a_register_pairlet read_reg;
- *bytes_written = 0;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- out_data_length = length + 0x8;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = DATA_PIPE_CMD_WRITE;
- out_data[i++] = 0; // primary address when AWF_NO_ADDRESS is not set
- out_data[i++] = 0; // secondary address when AWF_NO_ADDRESS is not set
- out_data[i] = AWF_NO_ADDRESS | AWF_NO_FAST_TALKER_FIRST_BYTE;
- if (send_commands)
- out_data[i] |= AWF_ATN | AWF_NO_FAST_TALKER;
- if (send_eoi)
- out_data[i] |= AWF_SEND_EOI;
- ++i;
- out_data[i++] = length & 0xff;
- out_data[i++] = (length >> 8) & 0xff;
- out_data[i++] = (length >> 16) & 0xff;
- out_data[i++] = (length >> 24) & 0xff;
- for (j = 0; j < length; j++)
- out_data[i++] = buffer[j];
- clear_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags);
- msec_timeout = (board->usec_timeout + 999) / 1000;
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &raw_bytes_written,
- msec_timeout);
- kfree(out_data);
- if (retval || raw_bytes_written != i) {
- agilent_82357a_abort(a_priv, 0);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, raw_bytes_written=%i, i=%i\n",
- retval, raw_bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval < 0)
- return retval;
- return -EIO;
- }
- retval = wait_event_interruptible(board->wait,
- test_bit(AIF_WRITE_COMPLETE_BN,
- &a_priv->interrupt_flags) ||
- test_bit(TIMO_NUM, &board->status));
- if (retval) {
- dev_dbg(&usb_dev->dev, "wait write complete interrupted\n");
- agilent_82357a_abort(a_priv, 0);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ERESTARTSYS;
- }
- if (test_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags) == 0) {
- dev_dbg(&usb_dev->dev, "write timed out ibs %i, tmo %i\n",
- test_bit(TIMO_NUM, &board->status), msec_timeout);
- agilent_82357a_abort(a_priv, 0);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- read_reg.address = BSR;
- retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return -ETIMEDOUT;
- }
- bsr = read_reg.value;
- dev_dbg(&usb_dev->dev, "write aborted bsr 0x%x\n", bsr);
- if (send_commands) {/* check for no listeners */
- if ((bsr & BSR_ATN_BIT) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) {
- dev_dbg(&usb_dev->dev, "No listener on command\n");
- clear_bit(TIMO_NUM, &board->status);
- return -ENOTCONN; // no listener on bus
- }
- } else {
- read_reg.address = ADSR;
- retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return -ETIMEDOUT;
- }
- adsr = read_reg.value;
- if ((adsr & HR_TA) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) {
- dev_dbg(&usb_dev->dev, "No listener on write\n");
- clear_bit(TIMO_NUM, &board->status);
- return -ECOMM;
- }
- }
- return -ETIMEDOUT;
- }
- status_data = kmalloc(STATUS_DATA_LEN, GFP_KERNEL);
- if (!status_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- retval = agilent_82357a_receive_control_msg(a_priv, agilent_82357a_control_request,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- XFER_STATUS, 0, status_data, STATUS_DATA_LEN,
- 100);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "receive_control_msg() returned %i\n", retval);
- kfree(status_data);
- return -EIO;
- }
- *bytes_written = (u32)status_data[2];
- *bytes_written |= (u32)status_data[3] << 8;
- *bytes_written |= (u32)status_data[4] << 16;
- *bytes_written |= (u32)status_data[5] << 24;
- kfree(status_data);
- return 0;
- }
- static int agilent_82357a_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
- {
- return agilent_82357a_generic_write(board, buffer, length, 0, send_eoi, bytes_written);
- }
- int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
- {
- return agilent_82357a_generic_write(board, buffer, length, 1, 0, bytes_written);
- }
- int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet write;
- int retval;
- write.address = AUXCR;
- if (synchronous)
- write.value = AUX_TCS;
- else
- write.value = AUX_TCA;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- static int agilent_82357a_take_control(struct gpib_board *board, int synchronous)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- const int timeout = 10;
- int i;
- if (!a_priv->bus_interface)
- return -ENODEV;
- /*
- * It looks like the 9914 does not handle tcs properly.
- * See comment above tms9914_take_control_workaround() in
- * drivers/gpib/tms9914/tms9914_aux.c
- */
- if (synchronous)
- return -ETIMEDOUT;
- agilent_82357a_take_control_internal(board, synchronous);
- // busy wait until ATN is asserted
- for (i = 0; i < timeout; ++i) {
- agilent_82357a_update_status(board, 0);
- if (test_bit(ATN_NUM, &board->status))
- break;
- udelay(1);
- }
- if (i == timeout)
- return -ETIMEDOUT;
- return 0;
- }
- static int agilent_82357a_go_to_standby(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = AUXCR;
- write.value = AUX_GTS;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return 0;
- }
- static int agilent_82357a_request_system_control(struct gpib_board *board, int request_control)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet writes[2];
- int retval;
- int i = 0;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- /* 82357B needs bit to be set in 9914 AUXCR register */
- writes[i].address = AUXCR;
- if (request_control) {
- writes[i].value = AUX_RQC;
- a_priv->hw_control_bits |= SYSTEM_CONTROLLER;
- } else {
- return -EINVAL;
- }
- ++i;
- writes[i].address = HW_CONTROL;
- writes[i].value = a_priv->hw_control_bits;
- ++i;
- retval = agilent_82357a_write_registers(a_priv, writes, i);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- static void agilent_82357a_interface_clear(struct gpib_board *board, int assert)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
- if (!a_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = AUXCR;
- write.value = AUX_SIC;
- if (assert) {
- write.value |= AUX_CS;
- a_priv->is_cic = 1;
- }
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- }
- static void agilent_82357a_remote_enable(struct gpib_board *board, int enable)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
- if (!a_priv->bus_interface)
- return; //-ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = AUXCR;
- write.value = AUX_SRE;
- if (enable)
- write.value |= AUX_CS;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- a_priv->ren_state = enable;
- return;// 0;
- }
- static int agilent_82357a_enable_eos(struct gpib_board *board, u8 eos_byte,
- int compare_8_bits)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- if (!a_priv->bus_interface)
- return -ENODEV;
- if (compare_8_bits == 0)
- return -EOPNOTSUPP;
- a_priv->eos_char = eos_byte;
- a_priv->eos_mode = REOS | BIN;
- return 0;
- }
- static void agilent_82357a_disable_eos(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- a_priv->eos_mode &= ~REOS;
- }
- static unsigned int agilent_82357a_update_status(struct gpib_board *board,
- unsigned int clear_mask)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet address_status, bus_status;
- int retval;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- board->status &= ~clear_mask;
- if (a_priv->is_cic)
- set_bit(CIC_NUM, &board->status);
- else
- clear_bit(CIC_NUM, &board->status);
- address_status.address = ADSR;
- retval = agilent_82357a_read_registers(a_priv, &address_status, 1, 0);
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return board->status;
- }
- // check for remote/local
- if (address_status.value & HR_REM)
- set_bit(REM_NUM, &board->status);
- else
- clear_bit(REM_NUM, &board->status);
- // check for lockout
- if (address_status.value & HR_LLO)
- set_bit(LOK_NUM, &board->status);
- else
- clear_bit(LOK_NUM, &board->status);
- // check for ATN
- if (address_status.value & HR_ATN)
- set_bit(ATN_NUM, &board->status);
- else
- clear_bit(ATN_NUM, &board->status);
- // check for talker/listener addressed
- if (address_status.value & HR_TA)
- set_bit(TACS_NUM, &board->status);
- else
- clear_bit(TACS_NUM, &board->status);
- if (address_status.value & HR_LA)
- set_bit(LACS_NUM, &board->status);
- else
- clear_bit(LACS_NUM, &board->status);
- bus_status.address = BSR;
- retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return board->status;
- }
- if (bus_status.value & BSR_SRQ_BIT)
- set_bit(SRQI_NUM, &board->status);
- else
- clear_bit(SRQI_NUM, &board->status);
- return board->status;
- }
- static int agilent_82357a_primary_address(struct gpib_board *board, unsigned int address)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet write;
- int retval;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- // put primary address in address0
- write.address = ADR;
- write.value = address & ADDRESS_MASK;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- return retval;
- }
- static int agilent_82357a_secondary_address(struct gpib_board *board,
- unsigned int address, int enable)
- {
- if (enable)
- return -EOPNOTSUPP;
- return 0;
- }
- static int agilent_82357a_parallel_poll(struct gpib_board *board, u8 *result)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet writes[2];
- struct agilent_82357a_register_pairlet read;
- int retval;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- // execute parallel poll
- writes[0].address = AUXCR;
- writes[0].value = AUX_CS | AUX_RPP;
- writes[1].address = HW_CONTROL;
- writes[1].value = a_priv->hw_control_bits & ~NOT_PARALLEL_POLL;
- retval = agilent_82357a_write_registers(a_priv, writes, 2);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- udelay(2); // silly, since usb write will take way longer
- read.address = CPTR;
- retval = agilent_82357a_read_registers(a_priv, &read, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return retval;
- }
- *result = read.value;
- // clear parallel poll state
- writes[0].address = HW_CONTROL;
- writes[0].value = a_priv->hw_control_bits | NOT_PARALLEL_POLL;
- writes[1].address = AUXCR;
- writes[1].value = AUX_RPP;
- retval = agilent_82357a_write_registers(a_priv, writes, 2);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- return 0;
- }
- static void agilent_82357a_parallel_poll_configure(struct gpib_board *board, u8 config)
- {
- // board can only be system controller
- return;// 0;
- }
- static void agilent_82357a_parallel_poll_response(struct gpib_board *board, int ist)
- {
- // board can only be system controller
- return;// 0;
- }
- static void agilent_82357a_serial_poll_response(struct gpib_board *board, u8 status)
- {
- // board can only be system controller
- return;// 0;
- }
- static u8 agilent_82357a_serial_poll_status(struct gpib_board *board)
- {
- // board can only be system controller
- return 0;
- }
- static void agilent_82357a_return_to_local(struct gpib_board *board)
- {
- // board can only be system controller
- return;// 0;
- }
- static int agilent_82357a_line_status(const struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet bus_status;
- int retval;
- int status = VALID_ALL;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- bus_status.address = BSR;
- retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return retval;
- }
- if (bus_status.value & BSR_REN_BIT)
- status |= BUS_REN;
- if (bus_status.value & BSR_IFC_BIT)
- status |= BUS_IFC;
- if (bus_status.value & BSR_SRQ_BIT)
- status |= BUS_SRQ;
- if (bus_status.value & BSR_EOI_BIT)
- status |= BUS_EOI;
- if (bus_status.value & BSR_NRFD_BIT)
- status |= BUS_NRFD;
- if (bus_status.value & BSR_NDAC_BIT)
- status |= BUS_NDAC;
- if (bus_status.value & BSR_DAV_BIT)
- status |= BUS_DAV;
- if (bus_status.value & BSR_ATN_BIT)
- status |= BUS_ATN;
- return status;
- }
- static unsigned short nanosec_to_fast_talker_bits(unsigned int *nanosec)
- {
- static const int nanosec_per_bit = 21;
- static const int max_value = 0x72;
- static const int min_value = 0x11;
- unsigned short bits;
- bits = (*nanosec + nanosec_per_bit / 2) / nanosec_per_bit;
- if (bits < min_value)
- bits = min_value;
- if (bits > max_value)
- bits = max_value;
- *nanosec = bits * nanosec_per_bit;
- return bits;
- }
- static int agilent_82357a_t1_delay(struct gpib_board *board, unsigned int nanosec)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = FAST_TALKER_T1;
- write.value = nanosec_to_fast_talker_bits(&nanosec);
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return nanosec;
- }
- static void agilent_82357a_interrupt_complete(struct urb *urb)
- {
- struct gpib_board *board = urb->context;
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval;
- u8 *transfer_buffer = urb->transfer_buffer;
- unsigned long interrupt_flags;
- switch (urb->status) {
- /* success */
- case 0:
- break;
- /* unlinked, don't resubmit */
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* other error, resubmit */
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
- return;
- }
- interrupt_flags = transfer_buffer[0];
- if (test_bit(AIF_READ_COMPLETE_BN, &interrupt_flags))
- set_bit(AIF_READ_COMPLETE_BN, &a_priv->interrupt_flags);
- if (test_bit(AIF_WRITE_COMPLETE_BN, &interrupt_flags))
- set_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags);
- if (test_bit(AIF_SRQ_BN, &interrupt_flags))
- set_bit(SRQI_NUM, &board->status);
- wake_up_interruptible(&board->wait);
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
- }
- static int agilent_82357a_setup_urbs(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- int int_pipe;
- int retval;
- retval = mutex_lock_interruptible(&a_priv->interrupt_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- retval = -ENODEV;
- goto setup_exit;
- }
- a_priv->interrupt_buffer = kmalloc(INTERRUPT_BUF_LEN, GFP_KERNEL);
- if (!a_priv->interrupt_buffer) {
- retval = -ENOMEM;
- goto setup_exit;
- }
- a_priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!a_priv->interrupt_urb) {
- retval = -ENOMEM;
- goto setup_exit;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int_pipe = usb_rcvintpipe(usb_dev, a_priv->interrupt_in_endpoint);
- usb_fill_int_urb(a_priv->interrupt_urb, usb_dev, int_pipe, a_priv->interrupt_buffer,
- INTERRUPT_BUF_LEN, &agilent_82357a_interrupt_complete, board, 1);
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);
- if (retval) {
- usb_free_urb(a_priv->interrupt_urb);
- a_priv->interrupt_urb = NULL;
- dev_err(&usb_dev->dev, "failed to submit first interrupt urb, retval=%i\n", retval);
- goto setup_exit;
- }
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- return 0;
- setup_exit:
- kfree(a_priv->interrupt_buffer);
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- return retval;
- }
- static void agilent_82357a_cleanup_urbs(struct agilent_82357a_priv *a_priv)
- {
- if (a_priv && a_priv->bus_interface) {
- if (a_priv->interrupt_urb)
- usb_kill_urb(a_priv->interrupt_urb);
- if (a_priv->bulk_urb)
- usb_kill_urb(a_priv->bulk_urb);
- }
- };
- static void agilent_82357a_release_urbs(struct agilent_82357a_priv *a_priv)
- {
- if (a_priv) {
- usb_free_urb(a_priv->interrupt_urb);
- a_priv->interrupt_urb = NULL;
- kfree(a_priv->interrupt_buffer);
- }
- }
- static int agilent_82357a_allocate_private(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv;
- board->private_data = kzalloc_obj(struct agilent_82357a_priv);
- if (!board->private_data)
- return -ENOMEM;
- a_priv = board->private_data;
- mutex_init(&a_priv->bulk_transfer_lock);
- mutex_init(&a_priv->bulk_alloc_lock);
- mutex_init(&a_priv->control_alloc_lock);
- mutex_init(&a_priv->interrupt_alloc_lock);
- return 0;
- }
- static void agilent_82357a_free_private(struct gpib_board *board)
- {
- kfree(board->private_data);
- board->private_data = NULL;
- }
- #define INIT_NUM_REG_WRITES 18
- static int agilent_82357a_init(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet hw_control;
- struct agilent_82357a_register_pairlet writes[INIT_NUM_REG_WRITES];
- int retval;
- unsigned int nanosec;
- writes[0].address = LED_CONTROL;
- writes[0].value = FAIL_LED_ON;
- writes[1].address = RESET_TO_POWERUP;
- writes[1].value = RESET_SPACEBALL;
- retval = agilent_82357a_write_registers(a_priv, writes, 2);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return -EIO;
- }
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(usec_to_jiffies(2000)))
- return -ERESTARTSYS;
- writes[0].address = AUXCR;
- writes[0].value = AUX_NBAF;
- writes[1].address = AUXCR;
- writes[1].value = AUX_HLDE;
- writes[2].address = AUXCR;
- writes[2].value = AUX_TON;
- writes[3].address = AUXCR;
- writes[3].value = AUX_LON;
- writes[4].address = AUXCR;
- writes[4].value = AUX_RSV2;
- writes[5].address = AUXCR;
- writes[5].value = AUX_INVAL;
- writes[6].address = AUXCR;
- writes[6].value = AUX_RPP;
- writes[7].address = AUXCR;
- writes[7].value = AUX_STDL;
- writes[8].address = AUXCR;
- writes[8].value = AUX_VSTDL;
- writes[9].address = FAST_TALKER_T1;
- nanosec = board->t1_nano_sec;
- writes[9].value = nanosec_to_fast_talker_bits(&nanosec);
- board->t1_nano_sec = nanosec;
- writes[10].address = ADR;
- writes[10].value = board->pad & ADDRESS_MASK;
- writes[11].address = PPR;
- writes[11].value = 0;
- writes[12].address = SPMR;
- writes[12].value = 0;
- writes[13].address = PROTOCOL_CONTROL;
- writes[13].value = WRITE_COMPLETE_INTERRUPT_EN;
- writes[14].address = IMR0;
- writes[14].value = HR_BOIE | HR_BIIE;
- writes[15].address = IMR1;
- writes[15].value = HR_SRQIE;
- // turn off reset state
- writes[16].address = AUXCR;
- writes[16].value = AUX_CHIP_RESET;
- writes[17].address = LED_CONTROL;
- writes[17].value = FIRMWARE_LED_CONTROL;
- retval = agilent_82357a_write_registers(a_priv, writes, INIT_NUM_REG_WRITES);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return -EIO;
- }
- hw_control.address = HW_CONTROL;
- retval = agilent_82357a_read_registers(a_priv, &hw_control, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return -EIO;
- }
- a_priv->hw_control_bits = (hw_control.value & ~0x7) | NOT_TI_RESET | NOT_PARALLEL_POLL;
- return 0;
- }
- static inline int agilent_82357a_device_match(struct usb_interface *interface,
- const struct gpib_board_config *config)
- {
- struct usb_device * const usbdev = interface_to_usbdev(interface);
- if (gpib_match_device_path(&interface->dev, config->device_path) == 0)
- return 0;
- if (config->serial_number &&
- strcmp(usbdev->serial, config->serial_number) != 0)
- return 0;
- return 1;
- }
- static int agilent_82357a_attach(struct gpib_board *board, const struct gpib_board_config *config)
- {
- int retval;
- int i;
- unsigned int product_id;
- struct agilent_82357a_priv *a_priv;
- struct usb_device *usb_dev;
- if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock))
- return -ERESTARTSYS;
- retval = agilent_82357a_allocate_private(board);
- if (retval) {
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- a_priv = board->private_data;
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] &&
- !usb_get_intfdata(agilent_82357a_driver_interfaces[i]) &&
- agilent_82357a_device_match(agilent_82357a_driver_interfaces[i], config)) {
- a_priv->bus_interface = agilent_82357a_driver_interfaces[i];
- usb_set_intfdata(agilent_82357a_driver_interfaces[i], board);
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES) {
- dev_err(board->gpib_dev,
- "No supported adapters found, have you loaded its firmware?\n");
- retval = -ENODEV;
- goto attach_fail;
- }
- product_id = le16_to_cpu(interface_to_usbdev(a_priv->bus_interface)->descriptor.idProduct);
- switch (product_id) {
- case USB_DEVICE_ID_AGILENT_82357A:
- a_priv->bulk_out_endpoint = AGILENT_82357A_BULK_OUT_ENDPOINT;
- a_priv->interrupt_in_endpoint = AGILENT_82357A_INTERRUPT_IN_ENDPOINT;
- break;
- case USB_DEVICE_ID_AGILENT_82357B:
- a_priv->bulk_out_endpoint = AGILENT_82357B_BULK_OUT_ENDPOINT;
- a_priv->interrupt_in_endpoint = AGILENT_82357B_INTERRUPT_IN_ENDPOINT;
- break;
- default:
- dev_err(&usb_dev->dev, "bug, unhandled product_id in switch?\n");
- retval = -EIO;
- goto attach_fail;
- }
- retval = agilent_82357a_setup_urbs(board);
- if (retval < 0)
- goto attach_fail;
- timer_setup(&a_priv->bulk_timer, agilent_82357a_timeout_handler, 0);
- board->t1_nano_sec = 800;
- retval = agilent_82357a_init(board);
- if (retval < 0) {
- agilent_82357a_cleanup_urbs(a_priv);
- agilent_82357a_release_urbs(a_priv);
- goto attach_fail;
- }
- dev_info(&usb_dev->dev, "bus %d dev num %d attached to gpib%d, interface %i\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- attach_fail:
- agilent_82357a_free_private(board);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- static int agilent_82357a_go_idle(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet writes[0x20];
- int retval;
- // turn on tms9914 reset state
- writes[0].address = AUXCR;
- writes[0].value = AUX_CS | AUX_CHIP_RESET;
- a_priv->hw_control_bits &= ~NOT_TI_RESET;
- writes[1].address = HW_CONTROL;
- writes[1].value = a_priv->hw_control_bits;
- writes[2].address = PROTOCOL_CONTROL;
- writes[2].value = 0;
- writes[3].address = IMR0;
- writes[3].value = 0;
- writes[4].address = IMR1;
- writes[4].value = 0;
- writes[5].address = LED_CONTROL;
- writes[5].value = 0;
- retval = agilent_82357a_write_registers(a_priv, writes, 6);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return -EIO;
- }
- return 0;
- }
- static void agilent_82357a_detach(struct gpib_board *board)
- {
- struct agilent_82357a_priv *a_priv;
- mutex_lock(&agilent_82357a_hotplug_lock);
- a_priv = board->private_data;
- if (a_priv) {
- if (a_priv->bus_interface) {
- agilent_82357a_go_idle(board);
- usb_set_intfdata(a_priv->bus_interface, NULL);
- }
- mutex_lock(&a_priv->control_alloc_lock);
- mutex_lock(&a_priv->bulk_alloc_lock);
- mutex_lock(&a_priv->interrupt_alloc_lock);
- agilent_82357a_cleanup_urbs(a_priv);
- agilent_82357a_release_urbs(a_priv);
- agilent_82357a_free_private(board);
- }
- mutex_unlock(&agilent_82357a_hotplug_lock);
- }
- static struct gpib_interface agilent_82357a_gpib_interface = {
- .name = "agilent_82357a",
- .attach = agilent_82357a_attach,
- .detach = agilent_82357a_detach,
- .read = agilent_82357a_read,
- .write = agilent_82357a_write,
- .command = agilent_82357a_command,
- .take_control = agilent_82357a_take_control,
- .go_to_standby = agilent_82357a_go_to_standby,
- .request_system_control = agilent_82357a_request_system_control,
- .interface_clear = agilent_82357a_interface_clear,
- .remote_enable = agilent_82357a_remote_enable,
- .enable_eos = agilent_82357a_enable_eos,
- .disable_eos = agilent_82357a_disable_eos,
- .parallel_poll = agilent_82357a_parallel_poll,
- .parallel_poll_configure = agilent_82357a_parallel_poll_configure,
- .parallel_poll_response = agilent_82357a_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = agilent_82357a_line_status,
- .update_status = agilent_82357a_update_status,
- .primary_address = agilent_82357a_primary_address,
- .secondary_address = agilent_82357a_secondary_address,
- .serial_poll_response = agilent_82357a_serial_poll_response,
- .serial_poll_status = agilent_82357a_serial_poll_status,
- .t1_delay = agilent_82357a_t1_delay,
- .return_to_local = agilent_82357a_return_to_local,
- .no_7_bit_eos = 1,
- .skip_check_for_command_acceptors = 1
- };
- // Table with the USB-devices: just now only testing IDs
- static struct usb_device_id agilent_82357a_driver_device_table[] = {
- {USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357A)},
- {USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357B)},
- {} /* Terminating entry */
- };
- MODULE_DEVICE_TABLE(usb, agilent_82357a_driver_device_table);
- static int agilent_82357a_driver_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
- {
- int i;
- char *path;
- static const int path_length = 1024;
- struct usb_device *usb_dev;
- if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock))
- return -ERESTARTSYS;
- usb_dev = usb_get_dev(interface_to_usbdev(interface));
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (!agilent_82357a_driver_interfaces[i]) {
- agilent_82357a_driver_interfaces[i] = interface;
- usb_set_intfdata(interface, NULL);
- dev_dbg(&usb_dev->dev, "set bus interface %i to address 0x%p\n",
- i, interface);
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES) {
- usb_put_dev(usb_dev);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- dev_err(&usb_dev->dev, "out of space in agilent_82357a_driver_interfaces[]\n");
- return -1;
- }
- path = kmalloc(path_length, GFP_KERNEL);
- if (!path) {
- usb_put_dev(usb_dev);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return -ENOMEM;
- }
- usb_make_path(usb_dev, path, path_length);
- dev_info(&usb_dev->dev, "probe succeeded for path: %s\n", path);
- kfree(path);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return 0;
- }
- static void agilent_82357a_driver_disconnect(struct usb_interface *interface)
- {
- int i;
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- mutex_lock(&agilent_82357a_hotplug_lock);
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] == interface) {
- struct gpib_board *board = usb_get_intfdata(interface);
- if (board) {
- struct agilent_82357a_priv *a_priv = board->private_data;
- if (a_priv) {
- mutex_lock(&a_priv->control_alloc_lock);
- mutex_lock(&a_priv->bulk_alloc_lock);
- mutex_lock(&a_priv->interrupt_alloc_lock);
- agilent_82357a_cleanup_urbs(a_priv);
- a_priv->bus_interface = NULL;
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- mutex_unlock(&a_priv->bulk_alloc_lock);
- mutex_unlock(&a_priv->control_alloc_lock);
- }
- }
- agilent_82357a_driver_interfaces[i] = NULL;
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES)
- dev_err(&usb_dev->dev, "unable to find interface - bug?\n");
- usb_put_dev(usb_dev);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- }
- static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_message_t message)
- {
- int i, retval;
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- mutex_lock(&agilent_82357a_hotplug_lock);
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] == interface) {
- struct gpib_board *board = usb_get_intfdata(interface);
- if (board) {
- struct agilent_82357a_priv *a_priv = board->private_data;
- if (a_priv) {
- agilent_82357a_abort(a_priv, 0);
- agilent_82357a_abort(a_priv, 0);
- retval = agilent_82357a_go_idle(board);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to go idle, retval=%i\n",
- retval);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- mutex_lock(&a_priv->interrupt_alloc_lock);
- agilent_82357a_cleanup_urbs(a_priv);
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- dev_dbg(&usb_dev->dev,
- "bus %d dev num %d gpib %d, interface %i suspended\n",
- usb_dev->bus->busnum, usb_dev->devnum,
- board->minor, i);
- }
- }
- break;
- }
- }
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return 0;
- }
- static int agilent_82357a_driver_resume(struct usb_interface *interface)
- {
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- struct gpib_board *board;
- int i, retval = 0;
- mutex_lock(&agilent_82357a_hotplug_lock);
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] == interface) {
- board = usb_get_intfdata(interface);
- if (board)
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES) {
- retval = -ENOENT;
- goto resume_exit;
- }
- struct agilent_82357a_priv *a_priv = board->private_data;
- if (a_priv) {
- if (a_priv->interrupt_urb) {
- mutex_lock(&a_priv->interrupt_alloc_lock);
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb in resume, retval=%i\n",
- retval);
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- }
- retval = agilent_82357a_init(board);
- if (retval < 0) {
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- // set/unset system controller
- retval = agilent_82357a_request_system_control(board, board->master);
- // toggle ifc if master
- if (board->master) {
- agilent_82357a_interface_clear(board, 1);
- usleep_range(200, 250);
- agilent_82357a_interface_clear(board, 0);
- }
- // assert/unassert REN
- agilent_82357a_remote_enable(board, a_priv->ren_state);
- dev_dbg(&usb_dev->dev,
- "bus %d dev num %d gpib%d, interface %i resumed\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
- }
- resume_exit:
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- static struct usb_driver agilent_82357a_bus_driver = {
- .name = DRV_NAME,
- .probe = agilent_82357a_driver_probe,
- .disconnect = agilent_82357a_driver_disconnect,
- .suspend = agilent_82357a_driver_suspend,
- .resume = agilent_82357a_driver_resume,
- .id_table = agilent_82357a_driver_device_table,
- };
- static int __init agilent_82357a_init_module(void)
- {
- int i;
- int ret;
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i)
- agilent_82357a_driver_interfaces[i] = NULL;
- ret = usb_register(&agilent_82357a_bus_driver);
- if (ret) {
- pr_err("usb_register failed: error = %d\n", ret);
- return ret;
- }
- ret = gpib_register_driver(&agilent_82357a_gpib_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- usb_deregister(&agilent_82357a_bus_driver);
- return ret;
- }
- return 0;
- }
- static void __exit agilent_82357a_exit_module(void)
- {
- gpib_unregister_driver(&agilent_82357a_gpib_interface);
- usb_deregister(&agilent_82357a_bus_driver);
- }
- module_init(agilent_82357a_init_module);
- module_exit(agilent_82357a_exit_module);
|