📄 highlevel.c
字号:
if (retval == 0) { kfree(as); } return retval;}int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start){ int retval = 0; struct hpsb_address_serve *as; struct list_head *entry; unsigned long flags; write_lock_irqsave(&addr_space_lock, flags); entry = hl->addr_list.next; while (entry != &hl->addr_list) { as = list_entry(entry, struct hpsb_address_serve, addr_list); entry = entry->next; if (as->start == start) { list_del(&as->as_list); list_del(&as->addr_list); kfree(as); retval = 1; break; } } write_unlock_irqrestore(&addr_space_lock, flags); return retval;}int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned int channel){ if (channel > 63) { HPSB_ERR("%s called with invalid channel", __FUNCTION__); return -EINVAL; } if (host->iso_listen_count[channel]++ == 0) { return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel); } return 0;}void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned int channel){ if (channel > 63) { HPSB_ERR("%s called with invalid channel", __FUNCTION__); return; } if (--host->iso_listen_count[channel] == 0) { host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel); }}void highlevel_add_host(struct hpsb_host *host){ struct list_head *entry; struct hpsb_highlevel *hl; read_lock(&hl_drivers_lock); list_for_each(entry, &hl_drivers) { hl = list_entry(entry, struct hpsb_highlevel, hl_list); if (hl->add_host) hl->add_host(host); } read_unlock(&hl_drivers_lock);}void highlevel_remove_host(struct hpsb_host *host){ struct list_head *entry; struct hpsb_highlevel *hl; read_lock(&hl_drivers_lock); list_for_each(entry, &hl_drivers) { hl = list_entry(entry, struct hpsb_highlevel, hl_list); if (hl->remove_host) { hl->remove_host(host); hpsb_destroy_hostinfo(hl, host); } } read_unlock(&hl_drivers_lock);}void highlevel_host_reset(struct hpsb_host *host){ struct list_head *entry; struct hpsb_highlevel *hl; read_lock(&hl_drivers_lock); list_for_each(entry, &hl_drivers) { hl = list_entry(entry, struct hpsb_highlevel, hl_list); if (hl->host_reset) hl->host_reset(host); } read_unlock(&hl_drivers_lock);}void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length){ struct list_head *entry; struct hpsb_highlevel *hl; int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f; read_lock(&hl_drivers_lock); entry = hl_drivers.next; while (entry != &hl_drivers) { hl = list_entry(entry, struct hpsb_highlevel, hl_list); if (hl->iso_receive) { hl->iso_receive(host, channel, data, length); } entry = entry->next; } read_unlock(&hl_drivers_lock);}void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void *data, size_t length){ struct list_head *entry; struct hpsb_highlevel *hl; int cts = ((quadlet_t *)data)[0] >> 4; read_lock(&hl_drivers_lock); entry = hl_drivers.next; while (entry != &hl_drivers) { hl = list_entry(entry, struct hpsb_highlevel, hl_list); if (hl->fcp_request) { hl->fcp_request(host, nodeid, direction, cts, data, length); } entry = entry->next; } read_unlock(&hl_drivers_lock);}int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr, unsigned int length, u16 flags){ struct hpsb_address_serve *as; struct list_head *entry; unsigned int partlength; int rcode = RCODE_ADDRESS_ERROR; read_lock(&addr_space_lock); entry = addr_space.next; as = list_entry(entry, struct hpsb_address_serve, as_list); while (as->start <= addr) { if (as->end > addr) { partlength = min(as->end - addr, (u64) length); if (as->op->read) { rcode = as->op->read(host, nodeid, data, addr, partlength, flags); } else { rcode = RCODE_TYPE_ERROR; } (u8 *)data += partlength; length -= partlength; addr += partlength; if ((rcode != RCODE_COMPLETE) || !length) { break; } } entry = entry->next; as = list_entry(entry, struct hpsb_address_serve, as_list); } read_unlock(&addr_space_lock); if (length && (rcode == RCODE_COMPLETE)) { rcode = RCODE_ADDRESS_ERROR; } return rcode;}int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data, u64 addr, unsigned int length, u16 flags){ struct hpsb_address_serve *as; struct list_head *entry; unsigned int partlength; int rcode = RCODE_ADDRESS_ERROR; read_lock(&addr_space_lock); entry = addr_space.next; as = list_entry(entry, struct hpsb_address_serve, as_list); while (as->start <= addr) { if (as->end > addr) { partlength = min(as->end - addr, (u64) length); if (as->op->write) { rcode = as->op->write(host, nodeid, destid, data, addr, partlength, flags); } else { rcode = RCODE_TYPE_ERROR; } (u8 *)data += partlength; length -= partlength; addr += partlength; if ((rcode != RCODE_COMPLETE) || !length) { break; } } entry = entry->next; as = list_entry(entry, struct hpsb_address_serve, as_list); } read_unlock(&addr_space_lock); if (length && (rcode == RCODE_COMPLETE)) { rcode = RCODE_ADDRESS_ERROR; } return rcode;}int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags){ struct hpsb_address_serve *as; struct list_head *entry; int rcode = RCODE_ADDRESS_ERROR; read_lock(&addr_space_lock); entry = addr_space.next; as = list_entry(entry, struct hpsb_address_serve, as_list); while (as->start <= addr) { if (as->end > addr) { if (as->op->lock) { rcode = as->op->lock(host, nodeid, store, addr, data, arg, ext_tcode, flags); } else { rcode = RCODE_TYPE_ERROR; } break; } entry = entry->next; as = list_entry(entry, struct hpsb_address_serve, as_list); } read_unlock(&addr_space_lock); return rcode;}int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags){ struct hpsb_address_serve *as; struct list_head *entry; int rcode = RCODE_ADDRESS_ERROR; read_lock(&addr_space_lock); entry = addr_space.next; as = list_entry(entry, struct hpsb_address_serve, as_list); while (as->start <= addr) { if (as->end > addr) { if (as->op->lock64) { rcode = as->op->lock64(host, nodeid, store, addr, data, arg, ext_tcode, flags); } else { rcode = RCODE_TYPE_ERROR; } break; } entry = entry->next; as = list_entry(entry, struct hpsb_address_serve, as_list); } read_unlock(&addr_space_lock); return rcode;}void init_hpsb_highlevel(void){ INIT_LIST_HEAD(&dummy_zero_addr.as_list); INIT_LIST_HEAD(&dummy_zero_addr.addr_list); INIT_LIST_HEAD(&dummy_max_addr.as_list); INIT_LIST_HEAD(&dummy_max_addr.addr_list); dummy_zero_addr.op = dummy_max_addr.op = &dummy_ops; dummy_zero_addr.start = dummy_zero_addr.end = 0; dummy_max_addr.start = dummy_max_addr.end = ((u64) 1) << 48; list_add_tail(&dummy_zero_addr.as_list, &addr_space); list_add_tail(&dummy_max_addr.as_list, &addr_space);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -