📄 i2o.h
字号:
/** * 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. */static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len, gfp_t gfp_mask){ struct pci_dev *pdev = to_pci_dev(dev); int dma_64 = 0; if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) { dma_64 = 1; if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) return -ENOMEM; } addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask); if ((sizeof(dma_addr_t) > 4) && dma_64) if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)) printk(KERN_WARNING "i2o: unable to set 64-bit DMA"); if (!addr->virt) return -ENOMEM; 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; }};/** * i2o_dma_realloc - Realloc DMA memory * @dev: struct device pointer to the PCI device of the I2O controller * @addr: pointer to a i2o_dma struct DMA buffer * @len: new length of memory * @gfp_mask: GFP mask * * If there was something allocated in the addr, free it first. If len > 0 * than try to allocate it and write the addresses back to the addr * structure. If len == 0 set the virtual address to NULL. * * Returns the 0 on success or negative error code on failure. */static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len, gfp_t gfp_mask){ i2o_dma_free(dev, addr); if (len) return i2o_dma_alloc(dev, addr, len, gfp_mask); return 0;};/* * i2o_pool_alloc - Allocate an slab cache and mempool * @mempool: pointer to struct i2o_pool to write data into. * @name: name which is used to identify cache * @size: size of each object * @min_nr: minimum number of objects * * First allocates a slab cache with name and size. Then allocates a * mempool which uses the slab cache for allocation and freeing. * * Returns 0 on success or negative error code on failure. */static inline int i2o_pool_alloc(struct i2o_pool *pool, const char *name, size_t size, int min_nr){ pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL); if (!pool->name) goto exit; strcpy(pool->name, name); pool->slab = kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!pool->slab) goto free_name; pool->mempool = mempool_create_slab_pool(min_nr, pool->slab); if (!pool->mempool) goto free_slab; return 0; free_slab: kmem_cache_destroy(pool->slab); free_name: kfree(pool->name); exit: return -ENOMEM;};/* * i2o_pool_free - Free slab cache and mempool again * @mempool: pointer to struct i2o_pool which should be freed * * Note that you have to return all objects to the mempool again before * calling i2o_pool_free(). */static inline void i2o_pool_free(struct i2o_pool *pool){ mempool_destroy(pool->mempool); kmem_cache_destroy(pool->slab); kfree(pool->name);};/* 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 * @drv: I2O driver * @c: I2O controller * * 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 * @drv: I2O driver * @c: I2O controller * * Send notification of removed controller to a single registered driver. */static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv, struct i2o_controller *c){ if (drv->notify_controller_remove) drv->notify_controller_remove(c);};/** * i2o_driver_notify_device_add - Send notification of added device * @drv: I2O driver * @i2o_dev: the added i2o_device * * Send notification of added device to a single registered driver. */static inline void i2o_driver_notify_device_add(struct i2o_driver *drv, struct i2o_device *i2o_dev){ if (drv->notify_device_add) drv->notify_device_add(i2o_dev);};/** * i2o_driver_notify_device_remove - Send notification of removed device * @drv: I2O driver * @i2o_dev: the added i2o_device * * 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){ 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 *);/* device / driver / kobject conversion 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)#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))/** * i2o_out_to_virt - Turn an I2O message to a virtual address * @c: controller * @m: message engine value * * Turn a receive message from an I2O controller bus address into * a Linux virtual address. The shared page frame is a linear block * so we simply have to shift the offset. This function does not * work for sender side messages as they are ioremap objects * provided by the I2O controller. */static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c, u32 m){ BUG_ON(m < c->out_queue.phys || m >= c->out_queue.phys + c->out_queue.len); return c->out_queue.virt + (m - c->out_queue.phys);};/** * i2o_msg_in_to_virt - Turn an I2O message to a virtual address * @c: controller * @m: message engine value * * Turn a send message from an I2O controller bus address into * a Linux virtual address. The shared page frame is a linear block * so we simply have to shift the offset. This function does not * work for receive side messages as they are kmalloc objects * in a different pool. */static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct i2o_controller *c, u32 m){ return c->in_queue.virt + m;};/** * i2o_msg_get - obtain an I2O message from the IOP * @c: I2O controller * * This function tries to get a message frame. If no message frame is * available do not wait until one is availabe (see also i2o_msg_get_wait). * The returned pointer to the message frame is not in I/O memory, it is * allocated from a mempool. But because a MFA is allocated from the * controller too it is guaranteed that i2o_msg_post() will never fail. * * On a success a pointer to the message frame is returned. If the message * queue is empty -EBUSY is returned and if no memory is available -ENOMEM * is returned. */static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c){ struct i2o_msg_mfa *mmsg = mempool_alloc(c->in_msg.mempool, GFP_ATOMIC); if (!mmsg) return ERR_PTR(-ENOMEM); mmsg->mfa = readl(c->in_port); if (unlikely(mmsg->mfa >= c->in_queue.len)) { u32 mfa = mmsg->mfa; mempool_free(mmsg, c->in_msg.mempool); if (mfa == I2O_QUEUE_EMPTY) return ERR_PTR(-EBUSY); return ERR_PTR(-EFAULT); } return &mmsg->msg;};/** * i2o_msg_post - Post I2O message to I2O controller * @c: I2O controller to which the message should be send * @msg: message returned by i2o_msg_get() * * Post the message to the I2O controller and return immediately. */static inline void i2o_msg_post(struct i2o_controller *c, struct i2o_message *msg){ struct i2o_msg_mfa *mmsg; mmsg = container_of(msg, struct i2o_msg_mfa, msg); memcpy_toio(i2o_msg_in_to_virt(c, mmsg->mfa), msg, (le32_to_cpu(msg->u.head[0]) >> 16) << 2); writel(mmsg->mfa, c->in_port); mempool_free(mmsg, c->in_msg.mempool);};/** * i2o_msg_post_wait - Post and wait a message and wait until return * @c: controller * @msg: 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, struct i2o_message *msg, unsigned long timeout){ return i2o_msg_post_wait_mem(c, msg, timeout, NULL);};/** * i2o_msg_nop_mfa - Returns a fetched MFA back to the controller * @c: I2O controller from which the MFA was fetched * @mfa: MFA which should be returned * * This function must be used for preserved messages, because i2o_msg_nop() * also returns the allocated memory back to the msg_pool mempool. */static inline void i2o_msg_nop_mfa(struct i2o_controller *c, u32 mfa){ struct i2o_message __iomem *msg; u32 nop[3] = { THREE_WORD_MSG_SIZE | SGL_OFFSET_0, I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID, 0x00000000 }; msg = i2o_msg_in_to_virt(c, mfa); memcpy_toio(msg, nop, sizeof(nop)); writel(mfa, c->in_port);};/** * i2o_msg_nop - Returns a message which is not used * @c: I2O controller from which the message was created * @msg: message which should be returned * * If you fetch a message via i2o_msg_get, and can't use it, you must * return the message with this function. Otherwise the MFA is lost as well * as the allocated memory from the mempool. */static inline void i2o_msg_nop(struct i2o_controller *c, struct i2o_message *msg){ struct i2o_msg_mfa *mmsg; mmsg = container_of(msg, struct i2o_msg_mfa, msg); i2o_msg_nop_mfa(c, mmsg->mfa); mempool_free(mmsg, c->in_msg.mempool);};/** * 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. */static inline void i2o_flush_reply(struct i2o_controller *c, u32 m){ writel(m, c->out_port);};/* * 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_table_get(struct i2o_device *, int, int, int, void *, int, void *, int);/* debugging and troubleshooting/diagnostic helpers. */#define osm_printk(level, format, arg...) \ printk(level "%s: " format, OSM_NAME , ## arg)#ifdef DEBUG#define osm_debug(format, arg...) \ osm_printk(KERN_DEBUG, format , ## arg)#else#define osm_debug(format, arg...) \ do { } while (0)#endif#define osm_err(format, arg...) \ osm_printk(KERN_ERR, format , ## arg)#define osm_info(format, arg...) \ osm_printk(KERN_INFO, format , ## arg)#define osm_warn(format, arg...) \ osm_printk(KERN_WARNING, format , ## arg)/* 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);#endif /* __KERNEL__ */#endif /* _I2O_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -