/*
* I2O kernel space accessible structures/APIs
- *
+ *
* (c) Copyright 1999, 2000 Red Hat Software
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
*************************************************************************
*
- * This header file defined the I2O APIs/structures for use by
+ * This header file defined the I2O APIs/structures for use by
* the I2O kernel modules.
*
*/
#ifndef _I2O_H
#define _I2O_H
-#ifdef __KERNEL__ /* This file to be included by kernel only */
+#ifdef __KERNEL__ /* This file to be included by kernel only */
#include <linux/i2o-dev.h>
/* How many different OSM's are we allowing */
-#define MAX_I2O_MODULES 4
-
-/* How many OSMs can register themselves for device status updates? */
-#define I2O_MAX_MANAGERS 4
+#define I2O_MAX_DRIVERS 4
+#include <asm/io.h>
#include <asm/semaphore.h> /* Needed for MUTEX init macros */
-#include <linux/config.h>
-#include <linux/notifier.h>
-#include <asm/atomic.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+
+/* message queue empty */
+#define I2O_QUEUE_EMPTY 0xffffffff
/*
* Message structures
*/
-struct i2o_message
-{
- u8 version_offset;
- u8 flags;
- u16 size;
- u32 target_tid:12;
- u32 init_tid:12;
- u32 function:8;
- u32 initiator_context;
+struct i2o_message {
+ union {
+ struct {
+ u8 version_offset;
+ u8 flags;
+ u16 size;
+ u32 target_tid:12;
+ u32 init_tid:12;
+ u32 function:8;
+ u32 icntxt; /* initiator context */
+ u32 tcntxt; /* transaction context */
+ } s;
+ u32 head[4];
+ } u;
/* List follows */
+ u32 body[0];
};
/*
- * Each I2O device entity has one or more of these. There is one
- * per device.
+ * Each I2O device entity has one of these. There is one per device.
*/
-struct i2o_device
-{
- i2o_lct_entry lct_data; /* Device LCT information */
- u32 flags;
- int i2oversion; /* I2O version supported. Actually
- * there should be high and low
- * version */
+struct i2o_device {
+ i2o_lct_entry lct_data; /* Device LCT information */
- struct proc_dir_entry *proc_entry; /* /proc dir */
+ struct i2o_controller *iop; /* Controlling IOP */
+ struct list_head list; /* node in IOP devices list */
+
+ struct device device;
+
+ struct semaphore lock; /* device lock */
+
+ struct class_device classdev; /* i2o device class */
+};
+
+/*
+ * Event structure provided to the event handling function
+ */
+struct i2o_event {
+ struct work_struct work;
+ struct i2o_device *i2o_dev; /* I2O device pointer from which the
+ event reply was initiated */
+ u16 size; /* Size of data in 32-bit words */
+ u32 tcntxt; /* Transaction context used at
+ registration */
+ u32 event_indicator; /* Event indicator from reply */
+ u32 data[0]; /* Event data from reply */
+};
+
+/*
+ * I2O classes which could be handled by the OSM
+ */
+struct i2o_class_id {
+ u16 class_id:12;
+};
+
+/*
+ * I2O driver structure for OSMs
+ */
+struct i2o_driver {
+ char *name; /* OSM name */
+ int context; /* Low 8 bits of the transaction info */
+ struct i2o_class_id *classes; /* I2O classes that this OSM handles */
+
+ /* Message reply handler */
+ int (*reply) (struct i2o_controller *, u32, struct i2o_message *);
+
+ /* Event handler */
+ void (*event) (struct i2o_event *);
+
+ struct workqueue_struct *event_queue; /* Event queue */
+
+ struct device_driver driver;
- /* Primary user */
- struct i2o_handler *owner;
+ /* notification of changes */
+ void (*notify_controller_add) (struct i2o_controller *);
+ void (*notify_controller_remove) (struct i2o_controller *);
+ void (*notify_device_add) (struct i2o_device *);
+ void (*notify_device_remove) (struct i2o_device *);
- /* Management users */
- struct i2o_handler *managers[I2O_MAX_MANAGERS];
- int num_managers;
+ struct semaphore lock;
+};
- struct i2o_controller *controller; /* Controlling IOP */
- struct i2o_device *next; /* Chain */
- struct i2o_device *prev;
- char dev_name[8]; /* linux /dev name if available */
+/*
+ * Contains all information which are necessary for DMA operations
+ */
+struct i2o_dma {
+ void *virt;
+ dma_addr_t phys;
+ u32 len;
};
/*
- * context queue entry, used for 32-bit context on 64-bit systems
+ * Context queue entry, used for 32-bit context on 64-bit systems
*/
struct i2o_context_list_element {
- struct i2o_context_list_element *next;
+ struct list_head list;
u32 context;
void *ptr;
- unsigned int flags;
+ unsigned long timestamp;
};
/*
* Each I2O controller has one of these objects
*/
-struct i2o_controller
-{
+struct i2o_controller {
char name[16];
int unit;
int type;
- int enabled;
-
- struct pci_dev *pdev; /* PCI device */
- int irq;
- int short_req:1; /* Use small block sizes */
- int dpt:1; /* Don't quiesce */
- int raptor:1; /* split bar */
- int promise:1; /* Promise controller */
+
+ struct pci_dev *pdev; /* PCI device */
+
+ int short_req:1; /* use small block sizes */
+ int no_quiesce:1; /* dont quiesce before reset */
+ int raptor:1; /* split bar */
+ int promise:1; /* Promise controller */
+
#ifdef CONFIG_MTRR
- int mtrr_reg0;
- int mtrr_reg1;
+ int mtrr_reg0;
+ int mtrr_reg1;
#endif
+ struct list_head devices; /* list of I2O devices */
+
struct notifier_block *event_notifer; /* Events */
atomic_t users;
- struct i2o_device *devices; /* I2O device chain */
- struct i2o_controller *next; /* Controller chain */
- void *post_port; /* Inbout port address */
- void *reply_port; /* Outbound port address */
- void *irq_mask; /* Interrupt register address */
+ struct list_head list; /* Controller list */
+ void *post_port; /* Inbout port address */
+ void *reply_port; /* Outbound port address */
+ void *irq_mask; /* Interrupt register address */
/* Dynamic LCT related data */
- struct semaphore lct_sem;
- int lct_pid;
- int lct_running;
- i2o_status_block *status_block; /* IOP status block */
- dma_addr_t status_block_phys;
- i2o_lct *lct; /* Logical Config Table */
- dma_addr_t lct_phys;
- i2o_lct *dlct; /* Temp LCT */
- dma_addr_t dlct_phys;
- i2o_hrt *hrt; /* HW Resource Table */
- dma_addr_t hrt_phys;
- u32 hrt_len;
+ struct i2o_dma status; /* status of IOP */
- void *base_virt; /* base virtual address */
- unsigned long base_phys; /* base physical address */
+ struct i2o_dma hrt; /* HW Resource Table */
+ i2o_lct *lct; /* Logical Config Table */
+ struct i2o_dma dlct; /* Temp LCT */
+ struct semaphore lct_lock; /* Lock for LCT updates */
+ struct i2o_dma status_block; /* IOP status block */
- void *msg_virt; /* messages virtual address */
- unsigned long msg_phys; /* messages physical address */
+ struct i2o_dma base; /* controller messaging unit */
+ struct i2o_dma in_queue; /* inbound message queue Host->IOP */
+ struct i2o_dma out_queue; /* outbound message queue IOP->Host */
- int battery:1; /* Has a battery backup */
- int io_alloc:1; /* An I/O resource was allocated */
- int mem_alloc:1; /* A memory resource was allocated */
+ int battery:1; /* Has a battery backup */
+ int io_alloc:1; /* An I/O resource was allocated */
+ int mem_alloc:1; /* A memory resource was allocated */
- struct resource io_resource; /* I/O resource allocated to the IOP */
- struct resource mem_resource; /* Mem resource allocated to the IOP */
+ struct resource io_resource; /* I/O resource allocated to the IOP */
+ struct resource mem_resource; /* Mem resource allocated to the IOP */
struct proc_dir_entry *proc_entry; /* /proc dir */
-
- void *page_frame; /* Message buffers */
- dma_addr_t page_frame_map; /* Cache map */
+ struct list_head bus_list; /* list of busses on IOP */
+ struct device device;
+ struct i2o_device *exec; /* Executive */
#if BITS_PER_LONG == 64
- spinlock_t context_list_lock; /* lock for context_list */
- struct i2o_context_list_element *context_list; /* list of context id's
- and pointers */
+ spinlock_t context_list_lock; /* lock for context_list */
+ atomic_t context_list_counter; /* needed for unique contexts */
+ struct list_head context_list; /* list of context id's
+ and pointers */
#endif
+ spinlock_t lock; /* lock for controller
+ configuration */
+
+ void *driver_data[I2O_MAX_DRIVERS]; /* storage for drivers */
};
/*
- * OSM resgistration block
+ * I2O System table entry
*
- * Each OSM creates at least one of these and registers it with the
- * I2O core through i2o_register_handler. An OSM may want to
- * register more than one if it wants a fast path to a reply
- * handler by having a separate initiator context for each
- * class function.
+ * The system table contains information about all the IOPs in the
+ * system. It is sent to all IOPs so that they can create peer2peer
+ * connections between them.
*/
-struct i2o_handler
+struct i2o_sys_tbl_entry {
+ u16 org_id;
+ u16 reserved1;
+ u32 iop_id:12;
+ u32 reserved2:20;
+ u16 seg_num:12;
+ u16 i2o_version:4;
+ u8 iop_state;
+ u8 msg_type;
+ u16 frame_size;
+ u16 reserved3;
+ u32 last_changed;
+ u32 iop_capabilities;
+ u32 inbound_low;
+ u32 inbound_high;
+};
+
+struct i2o_sys_tbl {
+ u8 num_entries;
+ u8 version;
+ u16 reserved1;
+ u32 change_ind;
+ u32 reserved2;
+ u32 reserved3;
+ struct i2o_sys_tbl_entry iops[0];
+};
+
+extern struct list_head i2o_controllers;
+
+/* Message functions */
+static inline u32 i2o_msg_get(struct i2o_controller *, struct i2o_message **);
+extern u32 i2o_msg_get_wait(struct i2o_controller *, struct i2o_message **,
+ int);
+static inline void i2o_msg_post(struct i2o_controller *, u32);
+static inline int i2o_msg_post_wait(struct i2o_controller *, u32,
+ unsigned long);
+extern int i2o_msg_post_wait_mem(struct i2o_controller *, u32, unsigned long,
+ struct i2o_dma *);
+extern void i2o_msg_nop(struct i2o_controller *, u32);
+static inline void i2o_flush_reply(struct i2o_controller *, u32);
+
+/* DMA handling functions */
+static inline int i2o_dma_alloc(struct device *, struct i2o_dma *, size_t,
+ unsigned int);
+static inline void i2o_dma_free(struct device *, struct i2o_dma *);
+int i2o_dma_realloc(struct device *, struct i2o_dma *, size_t, unsigned int);
+
+static inline int i2o_dma_map(struct device *, struct i2o_dma *);
+static inline void i2o_dma_unmap(struct device *, struct i2o_dma *);
+
+/* IOP functions */
+extern int i2o_status_get(struct i2o_controller *);
+extern int i2o_hrt_get(struct i2o_controller *);
+
+extern int i2o_event_register(struct i2o_device *, struct i2o_driver *, int,
+ u32);
+extern struct i2o_device *i2o_iop_find_device(struct i2o_controller *, u16);
+extern struct i2o_controller *i2o_find_iop(int);
+
+/* Functions needed for handling 64-bit pointers in 32-bit context */
+#if BITS_PER_LONG == 64
+extern u32 i2o_cntxt_list_add(struct i2o_controller *, void *);
+extern void *i2o_cntxt_list_get(struct i2o_controller *, u32);
+extern u32 i2o_cntxt_list_remove(struct i2o_controller *, void *);
+extern u32 i2o_cntxt_list_get_ptr(struct i2o_controller *, void *);
+
+static inline u32 i2o_ptr_low(void *ptr)
{
- /* Message reply handler */
- void (*reply)(struct i2o_handler *, struct i2o_controller *,
- struct i2o_message *);
+ return (u32) (u64) ptr;
+};
- /* New device notification handler */
- void (*new_dev_notify)(struct i2o_controller *, struct i2o_device *);
+static inline u32 i2o_ptr_high(void *ptr)
+{
+ return (u32) ((u64) ptr >> 32);
+};
+#else
+static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr)
+{
+ return (u32) ptr;
+};
- /* Device deltion handler */
- void (*dev_del_notify)(struct i2o_controller *, struct i2o_device *);
+static inline void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
+{
+ return (void *)context;
+};
- /* Reboot notification handler */
- void (*reboot_notify)(void);
+static inline u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr)
+{
+ return (u32) ptr;
+};
- char *name; /* OSM name */
- int context; /* Low 8 bits of the transaction info */
- u32 class; /* I2O classes that this driver handles */
- /* User data follows */
+static inline u32 i2o_cntxt_list_get_ptr(struct i2o_controller *c, void *ptr)
+{
+ return (u32) ptr;
};
-#ifdef MODULE
-/*
- * Used by bus specific modules to communicate with the core
+static inline u32 i2o_ptr_low(void *ptr)
+{
+ return (u32) ptr;
+};
+
+static inline u32 i2o_ptr_high(void *ptr)
+{
+ return 0;
+};
+#endif
+
+/* I2O driver (OSM) functions */
+extern int i2o_driver_register(struct i2o_driver *);
+extern void i2o_driver_unregister(struct i2o_driver *);
+
+/**
+ * i2o_driver_notify_controller_add - Send notification of added controller
+ * to a single I2O driver
*
- * This is needed because the bus modules cannot make direct
- * calls to the core as this results in the i2o_bus_specific_module
- * being dependent on the core, not the otherway around.
- * In that case, a 'modprobe i2o_lan' loads i2o_core & i2o_lan,
- * but _not_ i2o_pci...which makes the whole thing pretty useless :)
+ * Send notification of added controller to a single registered driver.
+ */
+static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv,
+ struct i2o_controller *c)
+{
+ if (drv->notify_controller_add)
+ drv->notify_controller_add(c);
+};
+
+/**
+ * i2o_driver_notify_controller_remove - Send notification of removed
+ * controller to a single I2O driver
*
+ * Send notification of removed controller to a single registered driver.
*/
-struct i2o_core_func_table
+static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv,
+ struct i2o_controller *c)
{
- int (*install)(struct i2o_controller *);
- int (*activate)(struct i2o_controller *);
- struct i2o_controller *(*find)(int);
- void (*unlock)(struct i2o_controller *);
- void (*run_queue)(struct i2o_controller * c);
- int (*delete)(struct i2o_controller *);
+ if (drv->notify_controller_remove)
+ drv->notify_controller_remove(c);
};
-#endif /* MODULE */
-/*
- * I2O System table entry
+/**
+ * i2o_driver_notify_device_add - Send notification of added device to a
+ * single I2O driver
*
- * The system table contains information about all the IOPs in the
- * system. It is sent to all IOPs so that they can create peer2peer
- * connections between them.
+ * Send notification of added device to a single registered driver.
*/
-struct i2o_sys_tbl_entry
+static inline void i2o_driver_notify_device_add(struct i2o_driver *drv,
+ struct i2o_device *i2o_dev)
{
- u16 org_id;
- u16 reserved1;
- u32 iop_id:12;
- u32 reserved2:20;
- u16 seg_num:12;
- u16 i2o_version:4;
- u8 iop_state;
- u8 msg_type;
- u16 frame_size;
- u16 reserved3;
- u32 last_changed;
- u32 iop_capabilities;
- u32 inbound_low;
- u32 inbound_high;
-};
-
-struct i2o_sys_tbl
+ if (drv->notify_device_add)
+ drv->notify_device_add(i2o_dev);
+};
+
+/**
+ * i2o_driver_notify_device_remove - Send notification of removed device
+ * to a single I2O driver
+ *
+ * Send notification of removed device to a single registered driver.
+ */
+static inline void i2o_driver_notify_device_remove(struct i2o_driver *drv,
+ struct i2o_device *i2o_dev)
{
- u8 num_entries;
- u8 version;
- u16 reserved1;
- u32 change_ind;
- u32 reserved2;
- u32 reserved3;
- struct i2o_sys_tbl_entry iops[0];
+ if (drv->notify_device_remove)
+ drv->notify_device_remove(i2o_dev);
};
+extern void i2o_driver_notify_controller_add_all(struct i2o_controller *);
+extern void i2o_driver_notify_controller_remove_all(struct i2o_controller *);
+extern void i2o_driver_notify_device_add_all(struct i2o_device *);
+extern void i2o_driver_notify_device_remove_all(struct i2o_device *);
+
+/* I2O device functions */
+extern int i2o_device_claim(struct i2o_device *);
+extern int i2o_device_claim_release(struct i2o_device *);
+
+/* Exec OSM functions */
+extern int i2o_exec_lct_get(struct i2o_controller *);
+extern int i2o_exec_lct_notify(struct i2o_controller *, u32);
+
+/* device to i2o_device and driver to i2o_driver convertion functions */
+#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
+#define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
+
/*
* Messenger inlines
*/
static inline u32 I2O_POST_READ32(struct i2o_controller *c)
{
+ rmb();
return readl(c->post_port);
-}
+};
static inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 val)
{
+ wmb();
writel(val, c->post_port);
-}
-
+};
static inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
{
+ rmb();
return readl(c->reply_port);
-}
+};
static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 val)
{
+ wmb();
writel(val, c->reply_port);
-}
-
+};
static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
{
+ rmb();
return readl(c->irq_mask);
-}
+};
static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
{
+ wmb();
writel(val, c->irq_mask);
-}
+ wmb();
+};
+/**
+ * i2o_msg_get - obtain an I2O message from the IOP
+ * @c: I2O controller
+ * @msg: pointer to a I2O message pointer
+ *
+ * This function tries to get a message slot. If no message slot is
+ * available do not wait until one is availabe (see also i2o_msg_get_wait).
+ *
+ * On a success the message is returned and the pointer to the message is
+ * set in msg. The returned message is the physical page frame offset
+ * address from the read port (see the i2o spec). If no message is
+ * available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
+ */
+static inline u32 i2o_msg_get(struct i2o_controller *c,
+ struct i2o_message **msg)
+{
+ u32 m;
-static inline void i2o_post_message(struct i2o_controller *c, u32 m)
+ if ((m = I2O_POST_READ32(c)) != I2O_QUEUE_EMPTY)
+ *msg = c->in_queue.virt + m;
+
+ return m;
+};
+
+/**
+ * i2o_msg_post - Post I2O message to I2O controller
+ * @c: I2O controller to which the message should be send
+ * @m: the message identifier
+ *
+ * Post the message to the I2O controller.
+ */
+static inline void i2o_msg_post(struct i2o_controller *c, u32 m)
{
- /* The second line isnt spurious - thats forcing PCI posting */
I2O_POST_WRITE32(c, m);
- (void) I2O_IRQ_READ32(c);
-}
+};
+/**
+ * i2o_msg_post_wait - Post and wait a message and wait until return
+ * @c: controller
+ * @m: message to post
+ * @timeout: time in seconds to wait
+ *
+ * This API allows an OSM to post a message and then be told whether or
+ * not the system received a successful reply. If the message times out
+ * then the value '-ETIMEDOUT' is returned.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static inline int i2o_msg_post_wait(struct i2o_controller *c, u32 m,
+ unsigned long timeout)
+{
+ return i2o_msg_post_wait_mem(c, m, timeout, NULL);
+};
+
+/**
+ * i2o_flush_reply - Flush reply from I2O controller
+ * @c: I2O controller
+ * @m: the message identifier
+ *
+ * The I2O controller must be informed that the reply message is not needed
+ * anymore. If you forget to flush the reply, the message frame can't be
+ * used by the controller anymore and is therefore lost.
+ *
+ * FIXME: is there a timeout after which the controller reuse the message?
+ */
static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
{
I2O_REPLY_WRITE32(c, m);
-}
+};
-/*
- * Endian handling wrapped into the macro - keeps the core code
- * cleaner.
+/**
+ * i2o_dma_alloc - Allocate DMA memory
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: i2o_dma struct which should get the DMA buffer
+ * @len: length of the new DMA memory
+ * @gfp_mask: GFP mask
+ *
+ * Allocate a coherent DMA memory and write the pointers into addr.
+ *
+ * Returns 0 on success or -ENOMEM on failure.
*/
-
-#define i2o_raw_writel(val, mem) __raw_writel(cpu_to_le32(val), mem)
+static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
+ size_t len, unsigned int gfp_mask)
+{
+ addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
+ if (!addr->virt)
+ return -ENOMEM;
-extern struct i2o_controller *i2o_find_controller(int);
-extern void i2o_unlock_controller(struct i2o_controller *);
-extern struct i2o_controller *i2o_controller_chain;
-extern int i2o_num_controllers;
-extern int i2o_status_get(struct i2o_controller *);
+ memset(addr->virt, 0, len);
+ addr->len = len;
+
+ return 0;
+};
+
+/**
+ * i2o_dma_free - Free DMA memory
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: i2o_dma struct which contains the DMA buffer
+ *
+ * Free a coherent DMA memory and set virtual address of addr to NULL.
+ */
+static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
+{
+ if (addr->virt) {
+ if (addr->phys)
+ dma_free_coherent(dev, addr->len, addr->virt,
+ addr->phys);
+ else
+ kfree(addr->virt);
+ addr->virt = NULL;
+ }
+};
-extern int i2o_install_handler(struct i2o_handler *);
-extern int i2o_remove_handler(struct i2o_handler *);
+/**
+ * i2o_dma_map - Map the memory to DMA
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: i2o_dma struct which should be mapped
+ *
+ * Map the memory in addr->virt to coherent DMA memory and write the
+ * physical address into addr->phys.
+ *
+ * Returns 0 on success or -ENOMEM on failure.
+ */
+static inline int i2o_dma_map(struct device *dev, struct i2o_dma *addr)
+{
+ if (!addr->virt)
+ return -EFAULT;
-extern int i2o_claim_device(struct i2o_device *, struct i2o_handler *);
-extern int i2o_release_device(struct i2o_device *, struct i2o_handler *);
-extern int i2o_device_notify_on(struct i2o_device *, struct i2o_handler *);
-extern int i2o_device_notify_off(struct i2o_device *,
- struct i2o_handler *);
+ if (!addr->phys)
+ addr->phys = dma_map_single(dev, addr->virt, addr->len,
+ DMA_BIDIRECTIONAL);
+ if (!addr->phys)
+ return -ENOMEM;
-extern int i2o_post_this(struct i2o_controller *, u32 *, int);
-extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int);
-extern int i2o_post_wait_mem(struct i2o_controller *, u32 *, int, int,
- void *, void *, dma_addr_t, dma_addr_t, int, int);
+ return 0;
+};
-extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *,
- int);
-extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *,
- int);
+/**
+ * i2o_dma_unmap - Unmap the DMA memory
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: i2o_dma struct which should be unmapped
+ *
+ * Unmap the memory in addr->virt from DMA memory.
+ */
+static inline void i2o_dma_unmap(struct device *dev, struct i2o_dma *addr)
+{
+ if (!addr->virt)
+ return;
+
+ if (addr->phys) {
+ dma_unmap_single(dev, addr->phys, addr->len, DMA_BIDIRECTIONAL);
+ addr->phys = 0;
+ }
+};
+
+/*
+ * Endian handling wrapped into the macro - keeps the core code
+ * cleaner.
+ */
+
+#define i2o_raw_writel(val, mem) __raw_writel(cpu_to_le32(val), mem)
+
+extern int i2o_parm_field_get(struct i2o_device *, int, int, void *, int);
+extern int i2o_parm_field_set(struct i2o_device *, int, int, void *, int);
+extern int i2o_parm_table_get(struct i2o_device *, int, int, int, void *, int,
+ void *, int);
+/* FIXME: remove
extern int i2o_query_table(int, struct i2o_controller *, int, int, int,
void *, int, void *, int);
extern int i2o_clear_table(struct i2o_controller *, int, int);
void *, int);
extern int i2o_issue_params(int, struct i2o_controller *, int, void *, int,
void *, int);
+*/
-extern int i2o_event_register(struct i2o_controller *, u32, u32, u32, u32);
-extern int i2o_event_ack(struct i2o_controller *, u32 *);
-
-extern void i2o_report_status(const char *, const char *, u32 *);
-extern void i2o_dump_message(u32 *);
-extern const char *i2o_get_class_name(int);
-
-extern int i2o_install_controller(struct i2o_controller *);
-extern int i2o_activate_controller(struct i2o_controller *);
-extern void i2o_run_queue(struct i2o_controller *);
-extern int i2o_delete_controller(struct i2o_controller *);
-
-#if BITS_PER_LONG == 64
-extern u32 i2o_context_list_add(void *, struct i2o_controller *);
-extern void *i2o_context_list_get(u32, struct i2o_controller *);
-extern u32 i2o_context_list_remove(void *, struct i2o_controller *);
-#else
-static inline u32 i2o_context_list_add(void *ptr, struct i2o_controller *c)
-{
- return (u32)ptr;
-}
-
-static inline void *i2o_context_list_get(u32 context, struct i2o_controller *c)
-{
- return (void *)context;
-}
-
-static inline u32 i2o_context_list_remove(void *ptr, struct i2o_controller *c)
-{
- return (u32)ptr;
-}
-#endif
+/* debugging functions */
+extern void i2o_report_status(const char *, const char *, struct i2o_message *);
+extern void i2o_dump_message(struct i2o_message *);
+extern void i2o_dump_hrt(struct i2o_controller *c);
+extern void i2o_debug_state(struct i2o_controller *c);
/*
* Cache strategies
*/
-
-
+
/* The NULL strategy leaves everything up to the controller. This tends to be a
* pessimal but functional choice.
*/
#define CACHE_NULL 0
/* Prefetch data when reading. We continually attempt to load the next 32 sectors
- * into the controller cache.
+ * into the controller cache.
*/
#define CACHE_PREFETCH 1
/* Prefetch data when reading. We sometimes attempt to load the next 32 sectors
/*
* Ioctl structures
*/
-
-
-#define BLKI2OGRSTRAT _IOR('2', 1, int)
-#define BLKI2OGWSTRAT _IOR('2', 2, int)
-#define BLKI2OSRSTRAT _IOW('2', 3, int)
-#define BLKI2OSWSTRAT _IOW('2', 4, int)
-
-
+#define BLKI2OGRSTRAT _IOR('2', 1, int)
+#define BLKI2OGWSTRAT _IOR('2', 2, int)
+#define BLKI2OSRSTRAT _IOW('2', 3, int)
+#define BLKI2OSWSTRAT _IOW('2', 4, int)
/*
* I2O Function codes
#define TRL_SINGLE_VARIABLE_LENGTH 0x40
#define TRL_MULTIPLE_FIXED_LENGTH 0x80
-
/* msg header defines for MsgFlags */
#define MSG_STATIC 0x0100
#define MSG_64BIT_CNTXT 0x0200
#define ELEVEN_WORD_MSG_SIZE 0x000B0000
#define I2O_MESSAGE_SIZE(x) ((x)<<16)
-
/* Special TID Assignments */
#define ADAPTER_TID 0
#define HOST_TID 1
-#define MSG_FRAME_SIZE 64 /* i2o_scsi assumes >= 32 */
+#define MSG_FRAME_SIZE 128 /* i2o_scsi assumes >= 32 */
#define REPLY_FRAME_SIZE 17
#define SG_TABLESIZE 30
#define NMBR_MSG_FRAMES 128
#define I2O_CONTEXT_LIST_USED 0x01
#define I2O_CONTEXT_LIST_DELETED 0x02
-#endif /* __KERNEL__ */
-#endif /* _I2O_H */
+/* timeouts */
+#define I2O_TIMEOUT_INIT_OUTBOUND_QUEUE 15
+#define I2O_TIMEOUT_MESSAGE_GET 5
+#define I2O_TIMEOUT_RESET 30
+#define I2O_TIMEOUT_STATUS_GET 5
+#define I2O_TIMEOUT_LCT_GET 20
+#define I2O_TIMEOUT_SCSI_SCB_ABORT 240
+
+/* retries */
+#define I2O_HRT_GET_TRIES 3
+#define I2O_LCT_GET_TRIES 3
+
+/* request queue sizes */
+#define I2O_MAX_SECTORS 1024
+#define I2O_MAX_SEGMENTS 128
+
+#define I2O_REQ_MEMPOOL_SIZE 32
+
+#endif /* __KERNEL__ */
+#endif /* _I2O_H */