#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/fs.h>
+#include <linux/dma-mapping.h>
#define TCODE_WRITE_QUADLET_REQUEST 0
#define TCODE_WRITE_BLOCK_REQUEST 1
#define RCODE_SEND_ERROR 0x10
#define RCODE_CANCELLED 0x11
#define RCODE_BUSY 0x12
+#define RCODE_GENERATION 0x13
+#define RCODE_NO_ACK 0x14
#define RETRY_1 0x00
#define RETRY_X 0x01
int current_tlabel, tlabel_mask;
struct list_head transaction_list;
struct timer_list flush_timer;
+ unsigned long reset_jiffies;
unsigned long long guid;
int max_receive;
struct list_head link;
- /* Work struct for IRM duties. */
+ /* Work struct for BM duties. */
struct delayed_work work;
- int irm_retries;
+ int bm_retries;
+ int bm_generation;
};
struct fw_card *fw_card_get(struct fw_card *card);
typedef void (*fw_iso_callback_t) (struct fw_iso_context *context,
int status, u32 cycle, void *data);
+/* An iso buffer is just a set of pages mapped for DMA in the
+ * specified direction. Since the pages are to be used for DMA, they
+ * are not mapped into the kernel virtual address space. We store the
+ * DMA address in the page private. The helper function
+ * fw_iso_buffer_map() will map the pages into a given vma. */
+
+struct fw_iso_buffer {
+ enum dma_data_direction direction;
+ struct page **pages;
+ int page_count;
+};
+
struct fw_iso_context {
struct fw_card *card;
int type;
int channel;
int speed;
+ size_t header_size;
fw_iso_callback_t callback;
void *callback_data;
-
- void *buffer;
- size_t buffer_size;
- dma_addr_t *pages;
- int page_count;
};
+int
+fw_iso_buffer_init(struct fw_iso_buffer *buffer,
+ struct fw_card *card,
+ int page_count,
+ enum dma_data_direction direction);
+int
+fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
+void
+fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
+
struct fw_iso_context *
-fw_iso_context_create(struct fw_card *card, int type,
- size_t buffer_size,
- fw_iso_callback_t callback,
- void *callback_data);
+fw_iso_context_create(struct fw_card *card, int type, size_t header_size,
+ fw_iso_callback_t callback, void *callback_data);
void
fw_iso_context_destroy(struct fw_iso_context *ctx);
-void
-fw_iso_context_start(struct fw_iso_context *ctx,
- int channel, int speed, int cycle);
-
int
fw_iso_context_queue(struct fw_iso_context *ctx,
- struct fw_iso_packet *packet, void *payload);
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload);
int
-fw_iso_context_send(struct fw_iso_context *ctx,
+fw_iso_context_start(struct fw_iso_context *ctx,
int channel, int speed, int cycle);
struct fw_card_driver {
void (*send_request) (struct fw_card *card, struct fw_packet *packet);
void (*send_response) (struct fw_card *card, struct fw_packet *packet);
+ /* Calling cancel is valid once a packet has been submitted. */
+ int (*cancel_packet) (struct fw_card *card, struct fw_packet *packet);
/* Allow the specified node ID to do direct DMA out and in of
* host memory. The card will disable this for all node when
(*allocate_iso_context)(struct fw_card *card, int type);
void (*free_iso_context)(struct fw_iso_context *ctx);
- int (*send_iso)(struct fw_iso_context *ctx, s32 cycle);
+ int (*start_iso)(struct fw_iso_context *ctx, s32 cycle);
int (*queue_iso)(struct fw_iso_context *ctx,
- struct fw_iso_packet *packet, void *payload);
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload);
};
int
void *data, size_t length,
fw_transaction_callback_t callback, void *callback_data);
+int fw_cancel_transaction(struct fw_card *card,
+ struct fw_transaction *transaction);
+
void fw_flush_transactions(struct fw_card *card);
void fw_send_phy_config(struct fw_card *card,