From 915a20a96f6fb81249f140a114b94f2b1502149d Mon Sep 17 00:00:00 2001 From: ddennedy Date: Wed, 23 Oct 2002 21:18:49 +0000 Subject: [PATCH] merged weihs branch git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@84 53a565d1-3bb7-0310-b661-cf11e63c67ab --- AUTHORS | 4 + ChangeLog | 4 + NEWS | 4 + configure.ac | 4 +- src/Makefile.am | 3 +- src/eventloop.c | 33 +++++++ src/kernel-raw1394.h | 80 +++++++++++++++-- src/main.c | 98 ++++++++++++++++++++- src/raw1394.h | 199 ++++++++++++++++++++++++++++++++++++++++++ src/raw1394_private.h | 13 +-- src/readwrite.c | 145 ++++++++++++++++++++++++++++++ tools/testlibraw.c | 22 +++++ 12 files changed, 591 insertions(+), 18 deletions(-) diff --git a/AUTHORS b/AUTHORS index ad9f046..f991bbb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,6 @@ Andreas Bombe or: + +Contributors: +Manfred Weihs +Christian Toegel diff --git a/ChangeLog b/ChangeLog index e69de29..140baf4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -0,0 +1,4 @@ +2002-10-23 17:18:00 Dan Dennedy + * started this ChangeLog + * merged in weihs branch + * added Manfred Weihs and Christian Toegel to AUTHORS diff --git a/NEWS b/NEWS index 9b33344..2ce84a1 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ - add sendiso and dumpiso tools with man files - fix wrong error mapping on local transactions in raw1394_errcode_to_errno(). +- added comment headers for most exported functions +- merged in weihs branch which brings new functionality including address + range mapping, reading and writing configROM images, additional bus reset + handling, and others. Version 0.9: diff --git a/configure.ac b/configure.ac index 9f06735..2145cd9 100644 --- a/configure.ac +++ b/configure.ac @@ -13,9 +13,9 @@ AC_C_CONST AC_C_BIGENDIAN # set the libtool so version numbers -lt_major=5 +lt_major=6 lt_revision=0 -lt_age=0 +lt_age=1 AC_SUBST(lt_major) AC_SUBST(lt_revision) diff --git a/src/Makefile.am b/src/Makefile.am index 328a4d6..b6a0140 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,9 +12,10 @@ libraw1394_la_SOURCES = \ readwrite.c \ iso.c \ fcp.c \ + arm.c \ version.c \ kernel-raw1394.h \ raw1394_private.h # headers to be installed -pkginclude_HEADERS = raw1394.h csr.h ieee1394.h +pkginclude_HEADERS = raw1394.h csr.h ieee1394.h kernel-raw1394.h diff --git a/src/eventloop.c b/src/eventloop.c index 1f19613..4eb83b6 100644 --- a/src/eventloop.c +++ b/src/eventloop.c @@ -2,10 +2,20 @@ * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. * * Copyright (C) 1999,2000,2001,2002 Andreas Bombe + * 2002 Manfred Weihs + * 2002 Christian Toegel * * This library is licensed under the GNU Lesser General Public License (LGPL), * version 2.1 or later. See the file COPYING.LIB in the distribution for * details. + * + * + * Contributions: + * + * Manfred Weihs + * address range mapping + * Christian Toegel + * address range mapping */ #include @@ -76,6 +86,17 @@ int raw1394_loop_iterate(struct raw1394_handle *handle) } break; + case RAW1394_REQ_ARM: + if (handle->arm_tag_handler) { + retval = handle->arm_tag_handler(handle, req->tag, + (req->misc & (0xFF)), + ((req->misc >> 16) & (0xFFFF)), + int2ptr(req->recvb)); + } + break; + case RAW1394_REQ_ECHO: + retval=req->misc; + break; default: if (handle->tag_handler) { retval = handle->tag_handler(handle, req->tag, @@ -130,6 +151,18 @@ tag_handler_t raw1394_set_tag_handler(struct raw1394_handle *handle, return old; } +arm_tag_handler_t raw1394_set_arm_tag_handler(struct raw1394_handle *handle, + arm_tag_handler_t new) +{ + arm_tag_handler_t old; + + old = handle->arm_tag_handler; + handle->arm_tag_handler = new; + + return old; +} + + /** * raw1394_set_iso_handler - set isochronous packet handler * @new_h: pointer to new handler diff --git a/src/kernel-raw1394.h b/src/kernel-raw1394.h index 98c6298..1fe55d0 100644 --- a/src/kernel-raw1394.h +++ b/src/kernel-raw1394.h @@ -14,20 +14,32 @@ #define RAW1394_REQ_SET_CARD 3 /* state: connected */ -#define RAW1394_REQ_ASYNC_READ 100 -#define RAW1394_REQ_ASYNC_WRITE 101 -#define RAW1394_REQ_LOCK 102 -#define RAW1394_REQ_LOCK64 103 -#define RAW1394_REQ_ISO_SEND 104 +#define RAW1394_REQ_ASYNC_READ 100 +#define RAW1394_REQ_ASYNC_WRITE 101 +#define RAW1394_REQ_LOCK 102 +#define RAW1394_REQ_LOCK64 103 +#define RAW1394_REQ_ISO_SEND 104 +#define RAW1394_REQ_ASYNC_SEND 105 -#define RAW1394_REQ_ISO_LISTEN 200 -#define RAW1394_REQ_FCP_LISTEN 201 -#define RAW1394_REQ_RESET_BUS 202 +#define RAW1394_REQ_ISO_LISTEN 200 +#define RAW1394_REQ_FCP_LISTEN 201 +#define RAW1394_REQ_RESET_BUS 202 +#define RAW1394_REQ_GET_ROM 203 +#define RAW1394_REQ_UPDATE_ROM 204 +#define RAW1394_REQ_ECHO 205 + +#define RAW1394_REQ_ARM_REGISTER 300 +#define RAW1394_REQ_ARM_UNREGISTER 301 + +#define RAW1394_REQ_RESET_NOTIFY 400 + +#define RAW1394_REQ_PHYPACKET 500 /* kernel to user */ #define RAW1394_REQ_BUS_RESET 10000 #define RAW1394_REQ_ISO_RECEIVE 10001 #define RAW1394_REQ_FCP_REQUEST 10002 +#define RAW1394_REQ_ARM 10003 /* error codes */ #define RAW1394_ERROR_NONE 0 @@ -45,6 +57,17 @@ #define RAW1394_ERROR_ABORTED (-1101) #define RAW1394_ERROR_TIMEOUT (-1102) +/* arm_codes */ +#define ARM_READ 1 +#define ARM_WRITE 2 +#define ARM_LOCK 4 + +#define RAW1394_LONG_RESET 0 +#define RAW1394_SHORT_RESET 1 + +/* busresetnotify ... */ +#define RAW1394_NOTIFY_OFF 0 +#define RAW1394_NOTIFY_ON 1 #include @@ -69,6 +92,32 @@ struct raw1394_khost_list { __u8 name[32]; }; +/* moved to raw1394.h to make it available to applications +typedef struct arm_request { + nodeid_t destination_nodeid; + nodeid_t source_nodeid; + nodeaddr_t destination_offset; + u8 tlabel; + u8 tcode; + u_int8_t extended_transaction_code; + u_int32_t generation; + arm_length_t buffer_length; + byte_t *buffer; +} *arm_request_t; + +typedef struct arm_response { + int response_code; + arm_length_t buffer_length; + byte_t *buffer; +} *arm_response_t; + +typedef struct arm_request_response { + struct arm_request *request; + struct arm_response *response; +} *arm_request_response_t; + +*/ + #ifdef __KERNEL__ struct iso_block_store { @@ -91,11 +140,26 @@ struct file_info { spinlock_t reqlists_lock; wait_queue_head_t poll_wait_complete; + struct list_head addr_list; + u8 *fcp_buffer; u64 listen_channels; quadlet_t *iso_buffer; size_t iso_buffer_length; + + u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ +}; + +struct arm_addr { + struct list_head addr_list; /* file_info list */ + u64 start, end; + u64 arm_tag; + u8 notification_options; + u8 access_rights; + u64 recvb; + u16 rec_length; + u8 *addr_space_buffer; /* accessed by read/write/lock */ }; struct pending_request { diff --git a/src/main.c b/src/main.c index e8864de..7bb847a 100644 --- a/src/main.c +++ b/src/main.c @@ -2,10 +2,23 @@ * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. * * Copyright (C) 1999,2000,2001,2002 Andreas Bombe + * 2001, 2002 Manfred Weihs + * 2002 Christian Toegel * * This library is licensed under the GNU Lesser General Public License (LGPL), * version 2.1 or later. See the file COPYING.LIB in the distribution for * details. + * + * + * Contributions: + * + * Manfred Weihs + * configuration ROM manipulation + * address range mapping + * Christian Toegel + * address range mapping + * reset notification control (switch on/off) + * reset with selection of type (short/long) */ #include @@ -39,6 +52,25 @@ static int tag_handler_default(struct raw1394_handle *handle, unsigned long tag, } } +static int arm_tag_handler_default(struct raw1394_handle *handle, unsigned long tag, + byte_t request_type, unsigned int requested_length, + void *data) +{ + struct raw1394_arm_reqhandle *rh; + struct arm_request_response *arm_req_resp; + + if (tag) { + rh = (struct raw1394_arm_reqhandle *)tag; + arm_req_resp = (struct arm_request_response *) data; + return rh->arm_callback(handle, arm_req_resp, + requested_length, rh->pcontext, + request_type); + } else { + /* error ... */ + return -1; + } +} + int _raw1394_sync_cb(struct raw1394_handle *unused, struct sync_cb_data *data, int error) { @@ -115,6 +147,7 @@ struct raw1394_handle *raw1394_new_handle(void) handle->err = 0; handle->bus_reset_handler = bus_reset_default; handle->tag_handler = tag_handler_default; + handle->arm_tag_handler = arm_tag_handler_default; memset(handle->iso_handler, 0, sizeof(handle->iso_handler)); return handle; } @@ -356,6 +389,21 @@ int raw1394_set_port(struct raw1394_handle *handle, int port) } } +int raw1394_reset_bus_new(struct raw1394_handle *handle, int type) +{ + struct raw1394_request *req = &handle->req; + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_RESET_BUS; + req->generation = handle->generation; + req->misc = type; + + if (write(handle->fd, req, sizeof(*req)) < 0) return -1; + + return 0; /* success */ +} + /** * raw1394_reset_bus - initiate bus reset @@ -367,15 +415,61 @@ int raw1394_set_port(struct raw1394_handle *handle, int port) * Returns %0 for success and -1 for failure with errno set appropriately. **/ int raw1394_reset_bus(struct raw1394_handle *handle) +{ + return raw1394_reset_bus_new (handle, RAW1394_LONG_RESET); +} + +int raw1394_busreset_notify (struct raw1394_handle *handle, + int off_on_switch) { struct raw1394_request *req = &handle->req; CLEAR_REQ(req); - req->type = RAW1394_REQ_RESET_BUS; + req->type = RAW1394_REQ_RESET_NOTIFY; req->generation = handle->generation; + req->misc = off_on_switch; if (write(handle->fd, req, sizeof(*req)) < 0) return -1; - return 0; + return 0; /* success */ +} + +int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t + *new_rom, size_t size, unsigned char rom_version) +{ + struct raw1394_request *req = &handle->req; + int status; + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_UPDATE_ROM; + req->sendb = (unsigned long) new_rom; + req->length = size; + req->misc = rom_version; + req->recvb = (unsigned long) &status; + + if (write(handle->fd, req, sizeof(*req)) < 0) return -8; + + return status; +} + +int raw1394_get_config_rom(raw1394handle_t handle, quadlet_t *buffer, + size_t buffersize, size_t *rom_size, unsigned char *rom_version) +{ + struct raw1394_request *req = &handle->req; + int status; + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_GET_ROM; + req->recvb = (unsigned long) buffer; + req->length = buffersize; + req->tag = (unsigned long) rom_size; + req->address = (unsigned long) rom_version; + req->sendb = (unsigned long) &status; + + if (write(handle->fd, req, sizeof(*req)) < 0) return -8; + + return status; } diff --git a/src/raw1394.h b/src/raw1394.h index 8d14264..c1f7b16 100644 --- a/src/raw1394.h +++ b/src/raw1394.h @@ -1,14 +1,52 @@ #ifndef _LIBRAW1394_RAW1394_H #define _LIBRAW1394_RAW1394_H +#define ARM_READ 1 +#define ARM_WRITE 2 +#define ARM_LOCK 4 + +#define RAW1394_LONG_RESET 0 +#define RAW1394_SHORT_RESET 1 + +/* busresetnotify ... */ +#define RAW1394_NOTIFY_OFF 0 +#define RAW1394_NOTIFY_ON 1 + #include +typedef u_int8_t byte_t; typedef u_int32_t quadlet_t; typedef u_int64_t octlet_t; typedef u_int64_t nodeaddr_t; typedef u_int16_t nodeid_t; +typedef u_int8_t phyid_t; +typedef u_int8_t arm_options_t; +typedef u_int16_t arm_length_t; typedef struct raw1394_handle *raw1394handle_t; +typedef struct arm_request { + nodeid_t destination_nodeid; + nodeid_t source_nodeid; + nodeaddr_t destination_offset; + u_int8_t tlabel; + u_int8_t tcode; + u_int8_t extended_transaction_code; + u_int32_t generation; + arm_length_t buffer_length; + byte_t *buffer; +} *arm_request_t; + +typedef struct arm_response { + int response_code; + arm_length_t buffer_length; + byte_t *buffer; +} *arm_response_t; + +typedef struct arm_request_response { + struct arm_request *request; + struct arm_response *response; +} *arm_request_response_t; + #ifdef __cplusplus extern "C" { #endif @@ -31,6 +69,15 @@ int raw1394_errcode_to_errno(raw1394_errcode_t); raw1394handle_t raw1394_new_handle(void); void raw1394_destroy_handle(raw1394handle_t handle); +/* + * Switch off/on busreset-notification for handle + * return-value: + * ==0 success + * !=0 failure + * off_on_switch .... RAW1394_NOTIFY_OFF or RAW1394_NOTIFY_ON + */ +int raw1394_busreset_notify (raw1394handle_t handle, int off_on_switch); + /* * Get the fd of this handle to select()/poll() on it. Don't try to mess around * with it any other way. Valid only after the handle got attached to a port. @@ -76,6 +123,15 @@ int raw1394_set_port(raw1394handle_t handle, int port); */ int raw1394_reset_bus(raw1394handle_t handle); +/* + * Reset the connected bus (with certain type). + * return-value: + * -1 failure + * 0 success + * type .... RAW1394_SHORT_RESET or RAW1394_LONG_RESET + */ +int raw1394_reset_bus_new(raw1394handle_t handle, int type); + /* * Get one new message through handle and process it. See below for handler * registering functions. This function will return -1 for an error or the @@ -119,6 +175,17 @@ typedef int (*tag_handler_t)(raw1394handle_t, unsigned long tag, tag_handler_t raw1394_set_tag_handler(raw1394handle_t handle, tag_handler_t new_h); +/* + * Set the handler that will be called when an async read/write/lock arm_request + * arrived. The default action is to call the arm_callback in the + * raw1394_arm_reqhandle pointed to by arm_tag. Returns old handler. + */ +typedef int (*arm_tag_handler_t)(raw1394handle_t handle, unsigned long arm_tag, + byte_t request_type, unsigned int requested_length, + void *data); +arm_tag_handler_t raw1394_set_arm_tag_handler(raw1394handle_t handle, + arm_tag_handler_t new_h); + /* * Set the handler that will be called when an iso packet arrives (data points * to the iso packet header). The default action is to do nothing. @@ -158,6 +225,91 @@ struct raw1394_reqhandle { void *data; }; +/* + * This is the genereal arm-request handle. (arm...address range mapping) + * It is used by the default arm-tag handler when a request has been + * received, it calls the arm_callback. + */ +typedef int (*arm_req_callback_t) (raw1394handle_t, + struct arm_request_response *arm_req_resp, + unsigned int requested_length, + void *pcontext, byte_t request_type); + +struct raw1394_arm_reqhandle { + arm_req_callback_t arm_callback; + void *pcontext; +}; + +/* + * AdressRangeMapping REGISTERING: + * start, length .... identifies addressrange + * *initial_value ... pointer to buffer containing (if necessary) initial value + * NULL means undefined + * arm_tag .......... identifier for arm_tag_handler + * (usually pointer to raw1394_arm_reqhandle) + * access_rights .... access-rights for registered addressrange handled + * by kernel-part. Value is one or more binary or of the + * following flags: ARM_READ, ARM_WRITE, ARM_LOCK + * notification_options ... identifies for which type of request you want + * to be notified. Value is one or more binary or of the + * following flags: ARM_READ, ARM_WRITE, ARM_LOCK + * client_transactions ... identifies for which type of request you want + * to handle the request by the client application. + * for those requests no response will be generated, but + * has to be generated by the application. + * Value is one or more binary or of the + * following flags: ARM_READ, ARM_WRITE, ARM_LOCK + * For each bit set here, notification_options and + * access_rights will be ignored. + * returnvalue: 0 ... success + * <0 ... failure + */ +int raw1394_arm_register(struct raw1394_handle *handle, nodeaddr_t start, + size_t length, byte_t *initial_value, + octlet_t arm_tag, arm_options_t access_rights, + arm_options_t notification_options, + arm_options_t client_transactions); +/* + * AdressRangeMapping UNREGISTERING: + * start ............ identifies addressrange for unregistering + * (value of start have to be the same value + * used for registering this adressrange) + * returnvalue: 0 ... success + * <0 ... failure + */ +int raw1394_arm_unregister(raw1394handle_t handle, nodeaddr_t start); + +/* + * send an echo request to the driver. the driver then send back the + * same request. raw1394_loop_iterate will return data as return value, + * when it processes the echo. + * + * data: arbitrary data; raw1394_loop_iterate will return it + * returnvalue: 0 .... success + * <0 ... failure + */ +int raw1394_echo_request(struct raw1394_handle *handle, quadlet_t data); + +/* + * wake up raw1394_loop_iterate (or a blocking read from the device + * file). actually this calls raw1394_echo_request with 0 as data. + * + * returnvalue: 0 .... success + * <0 ... failure + */ +int raw1394_wake_up(raw1394handle_t handle); + + +/* + * send physical request such as linkon, physicalconfigurationpacket ... etc. + * + * returnvalue: 0 .... success + * <0 ... failure + */ +int raw1394_phy_packet_write (raw1394handle_t handle, quadlet_t data); +int raw1394_start_phy_packet_write(raw1394handle_t handle, + quadlet_t data, unsigned long tag); + /* * Passes custom tag. Use pointer to raw1394_reqhandle if you use the standard * tag handler. @@ -169,11 +321,30 @@ int raw1394_start_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, int raw1394_start_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, unsigned int extcode, quadlet_t data, quadlet_t arg, quadlet_t *result, unsigned long tag); +int raw1394_start_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, + unsigned int extcode, octlet_t data, octlet_t arg, + octlet_t *result, unsigned long tag); int raw1394_start_iso_write(raw1394handle_t handle, unsigned int channel, unsigned int tag, unsigned int sy, unsigned int speed, size_t length, quadlet_t *data, unsigned long rawtag); + +/* This starts sending an arbitrary async packet. It gets an array of quadlets consisting of + header and data (without CRC in between). Header information is always in machine byte order, + data (data block as well as quadlet data in a read response for data quadlet) shall be in + big endian byte order. expect_response indicates, if we expect a response (i.e. if we will + get the tag back after the packet was sent or after a response arrived). length is the length + of the complete packet (header_length + length of the data block). + The main purpose of this function is to send responses for incoming transactions, that + are handled by the application. + Do not use that function, unless you really know, what you do! Sending corrupt packet may + lead to weird results. +*/ +int raw1394_start_async_send(raw1394handle_t handle, + size_t length, size_t header_length, unsigned int expect_response, + quadlet_t *data, unsigned long rawtag); + /* * This does the complete transaction and will return when it's finished. It * will call raw1394_loop_iterate() as often as necessary, return values of @@ -186,9 +357,15 @@ int raw1394_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, int raw1394_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, unsigned int extcode, quadlet_t data, quadlet_t arg, quadlet_t *result); +int raw1394_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, + unsigned int extcode, octlet_t data, octlet_t arg, + octlet_t *result); int raw1394_iso_write(raw1394handle_t handle, unsigned int channel, unsigned int tag, unsigned int sy, unsigned int speed, size_t length, quadlet_t *data); +int raw1394_async_send(raw1394handle_t handle, + size_t length, size_t header_length, unsigned int expect_response, + quadlet_t *data); /* * Start and stop receiving a certain isochronous channel. You have to set an @@ -211,6 +388,28 @@ int raw1394_stop_fcp_listen(raw1394handle_t handle); */ const char *raw1394_get_libversion(void); + +/* updates the configuration rom of a host. rom_version must be the current + * version, otherwise it will fail with return value -1. + * Return value -2 indicates that the new rom version is too big. + * Return value 0 indicates success +*/ + +int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t + *new_rom, size_t size, unsigned char rom_version); + + +/* reads the current version of the configuration rom of a host. + * buffersize is the size of the buffer, rom_size + * returns the size of the current rom image.. rom_version is the + * version number of the fetched rom. + * return value -1 indicates, that the buffer was too small, + * 0 indicates success. + */ + +int raw1394_get_config_rom(raw1394handle_t handle, quadlet_t *buffer, + size_t buffersize, size_t *rom_size, unsigned char *rom_version); + #ifdef __cplusplus } #endif diff --git a/src/raw1394_private.h b/src/raw1394_private.h index 7b414c8..733feae 100644 --- a/src/raw1394_private.h +++ b/src/raw1394_private.h @@ -2,6 +2,9 @@ #ifndef _RAW1394_PRIVATE_H #define _RAW1394_PRIVATE_H +#define HBUF_SIZE 8192 +#define ARM_REC_LENGTH 4096 + struct raw1394_handle { int fd; int protocol_version; @@ -15,12 +18,13 @@ struct raw1394_handle { void *userdata; bus_reset_handler_t bus_reset_handler; - tag_handler_t tag_handler; - fcp_handler_t fcp_handler; - iso_handler_t iso_handler[64]; + tag_handler_t tag_handler; + arm_tag_handler_t arm_tag_handler; + fcp_handler_t fcp_handler; + iso_handler_t iso_handler[64]; struct raw1394_request req; - quadlet_t buffer[2048]; + quadlet_t buffer[HBUF_SIZE/4]; /* 2048 */ }; struct sync_cb_data { @@ -30,7 +34,6 @@ struct sync_cb_data { int _raw1394_sync_cb(struct raw1394_handle*, struct sync_cb_data*, int); -#define HBUF_SIZE 8192 #define CLEAR_REQ(reqp) memset((reqp), 0, sizeof(struct raw1394_request)) #if SIZEOF_VOID_P == 4 diff --git a/src/readwrite.c b/src/readwrite.c index bb918d4..4573137 100644 --- a/src/readwrite.c +++ b/src/readwrite.c @@ -2,15 +2,29 @@ * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. * * Copyright (C) 1999,2000,2001,2002 Andreas Bombe + * 2002 Christian Toegel + * 2002 Manfred Weihs * * This library is licensed under the GNU Lesser General Public License (LGPL), * version 2.1 or later. See the file COPYING.LIB in the distribution for * details. + * + * + * Contributions: + * + * Christian Toegel + * lock64 request + * transmit physical packet + * raw1394_echo_request, raw1394_wake_up (interrupt blocking wait) + * + * Manfred Weihs + * raw1394_start_async_send, raw1394_async_send */ #include #include #include +#include #include "raw1394.h" #include "kernel-raw1394.h" @@ -150,6 +164,44 @@ int raw1394_start_lock(struct raw1394_handle *handle, nodeid_t node, req->length = 8; break; } + return (int)write(handle->fd, req, sizeof(*req)); +} + +int raw1394_start_lock64(struct raw1394_handle *handle, nodeid_t node, + nodeaddr_t addr, unsigned int extcode, octlet_t data, + octlet_t arg, octlet_t *result, unsigned long tag) +{ + struct raw1394_request *req = &handle->req; + octlet_t sendbuf[2]; + + if ((extcode > 7) || (extcode == 0)) { + errno = EINVAL; + return -1; + } + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_LOCK64; + req->generation = handle->generation; + req->tag = tag; + + req->address = ((__u64)node << 48) | addr; + req->sendb = ptr2int(sendbuf); + req->recvb = ptr2int(result); + req->misc = extcode; + + switch (extcode) { + case 3: /* EXTCODE_FETCH_ADD */ + case 4: /* EXTCODE_LITTLE_ADD */ + sendbuf[0] = data; + req->length = 8; + break; + default: + sendbuf[0] = arg; + sendbuf[1] = data; + req->length = 16; + break; + } return (int)write(handle->fd, req, sizeof(*req)); } @@ -197,6 +249,25 @@ int raw1394_start_iso_write(struct raw1394_handle *handle, unsigned int channel, return (int)write(handle->fd, req, sizeof(*req)); } +int raw1394_start_async_send(struct raw1394_handle *handle, + size_t length, size_t header_length, unsigned int expect_response, + quadlet_t *data, unsigned long rawtag) +{ + struct raw1394_request *req = &handle->req; + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_ASYNC_SEND; + req->generation = handle->generation; + req->tag = rawtag; + + req->length = length; + req->misc = (expect_response << 16) | (header_length & 0xffff); + req->sendb = ptr2int(data); + + return (int)write(handle->fd, req, sizeof(*req)); +} + #define SYNCFUNC_VARS \ struct sync_cb_data sd = { 0, 0 }; \ @@ -247,6 +318,19 @@ int raw1394_lock(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr, SYNCFUNC_BODY; } +int raw1394_lock64(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr, + unsigned int extcode, octlet_t data, octlet_t arg, + octlet_t *result) +{ + SYNCFUNC_VARS; + + err = raw1394_start_lock64(handle, node, addr, extcode, data, arg, result, + (unsigned long)&rh); + + SYNCFUNC_BODY; +} + + int raw1394_iso_write(struct raw1394_handle *handle, unsigned int channel, unsigned int tag, unsigned int sy, unsigned int speed, size_t length, quadlet_t *data) @@ -259,5 +343,66 @@ int raw1394_iso_write(struct raw1394_handle *handle, unsigned int channel, SYNCFUNC_BODY; } +int raw1394_async_send(struct raw1394_handle *handle , + size_t length, size_t header_length, unsigned int expect_response, + quadlet_t *data) +{ + SYNCFUNC_VARS; + + err = raw1394_start_async_send(handle, length, header_length, expect_response, + data, (unsigned long)&rh); + + SYNCFUNC_BODY; +} + + + +int raw1394_start_phy_packet_write(struct raw1394_handle *handle, + quadlet_t data, unsigned long tag) +{ + struct raw1394_request *req = &handle->req; + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_PHYPACKET; + req->generation = handle->generation; + req->tag = tag; + + req->sendb = data; + + return (int)write(handle->fd, req, sizeof(*req)); +} + +int raw1394_phy_packet_write (struct raw1394_handle *handle, quadlet_t data) +{ + SYNCFUNC_VARS; + + err = raw1394_start_phy_packet_write(handle, data, (unsigned long)&rh); + + SYNCFUNC_BODY; /* return 0 on success */ +} + +int raw1394_echo_request(struct raw1394_handle *handle, quadlet_t data) +{ + struct raw1394_request *req = &handle->req; + int retval=0; + + CLEAR_REQ(req); + + req->type = RAW1394_REQ_ECHO; + req->misc = data; + + retval = (int)write(handle->fd, req, sizeof(*req)); + if (retval == sizeof(*req)) { + return 0; /* succcess */ + } + return -1; +} + +int raw1394_wake_up(raw1394handle_t handle) +{ + return raw1394_echo_request(handle, 0); +} + #undef SYNCFUNC_VARS #undef SYNCFUNC_BODY diff --git a/tools/testlibraw.c b/tools/testlibraw.c index 21c2de2..2836945 100644 --- a/tools/testlibraw.c +++ b/tools/testlibraw.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "../src/raw1394.h" #include "../src/csr.h" @@ -73,6 +74,9 @@ int main(int argc, char **argv) struct pollfd pfd; unsigned char fcp_test[] = { 0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; + quadlet_t rom[0x100]; + size_t rom_size; + unsigned char rom_version; handle = raw1394_new_handle(); @@ -156,6 +160,24 @@ int main(int argc, char **argv) CSR_REGISTER_BASE + CSR_FCP_RESPONSE, sizeof(fcp_test), (quadlet_t *)fcp_test); + + + printf("testing config rom stuff\n"); + retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version); + printf("get_config_rom returned %d, romsize %d, rom_version %d\n",retval,rom_size,rom_version); + printf("here are the first 10 quadlets:\n"); + for (i = 0; i < 10; i++) + printf("%d. quadlet: 0x%08x\n",i,rom[i]); + + /* some manipulation */ +/* printf("incrementing 2nd quadlet\n"); + rom[0x02/4]++; +*/ + retval=raw1394_update_config_rom(handle, rom, rom_size, rom_version); + printf("update_config_rom returned %d\n",retval); + + + printf("\npolling for leftover messages\n"); pfd.fd = raw1394_get_fd(handle); pfd.events = POLLIN;