📄 ieee1394_transactions.c
字号:
{ struct hpsb_packet *p; p = alloc_hpsb_packet(0); if (!p) return NULL; p->host = host; p->tlabel = get_tlabel(host, node, 1); p->node_id = node; fill_async_readquad(p, addr); return p;}struct hpsb_packet *hpsb_make_readbpacket(struct hpsb_host *host, nodeid_t node, u64 addr, size_t length){ struct hpsb_packet *p; p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); if (!p) return NULL; p->host = host; p->tlabel = get_tlabel(host, node, 1); p->node_id = node; fill_async_readblock(p, addr, length); return p;}struct hpsb_packet *hpsb_make_writeqpacket(struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t data){ struct hpsb_packet *p; p = alloc_hpsb_packet(0); if (!p) return NULL; p->host = host; p->tlabel = get_tlabel(host, node, 1); p->node_id = node; fill_async_writequad(p, addr, data); return p;}struct hpsb_packet *hpsb_make_writebpacket(struct hpsb_host *host, nodeid_t node, u64 addr, size_t length){ struct hpsb_packet *p; p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); if (!p) return NULL; if (length % 4) { p->data[length / 4] = 0; } p->host = host; p->tlabel = get_tlabel(host, node, 1); p->node_id = node; fill_async_writeblock(p, addr, length); return p;}struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode){ struct hpsb_packet *p; p = alloc_hpsb_packet(8); if (!p) return NULL; p->host = host; p->tlabel = get_tlabel(host, node, 1); p->node_id = node; switch (extcode) { case EXTCODE_FETCH_ADD: case EXTCODE_LITTLE_ADD: fill_async_lock(p, addr, extcode, 4); break; default: fill_async_lock(p, addr, extcode, 8); break; } return p;}struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data) { struct hpsb_packet *p; p = alloc_hpsb_packet(0); if (!p) return NULL; p->host = host; fill_phy_packet(p, data); return p; }/* * FIXME - these functions should probably read from / write to user space to * avoid in kernel buffers for user space callers */int hpsb_read(struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length){ struct hpsb_packet *packet; int retval = 0; if (length == 0) { return -EINVAL; } if (host->node_id == node) { switch(highlevel_read(host, node, buffer, addr, length)) { case RCODE_COMPLETE: return 0; case RCODE_TYPE_ERROR: return -EACCES; case RCODE_ADDRESS_ERROR: default: return -EINVAL; } } if (length == 4) { packet = hpsb_make_readqpacket(host, node, addr); } else { packet = hpsb_make_readbpacket(host, node, addr, length); } if (!packet) { return -ENOMEM; } packet->generation = get_hpsb_generation(host); if (!hpsb_send_packet(packet)) { retval = -EINVAL; goto hpsb_read_fail; } down(&packet->state_change); down(&packet->state_change); retval = hpsb_packet_success(packet); if (retval == 0) { if (length == 4) { *buffer = packet->header[3]; } else { memcpy(buffer, packet->data, length); } }hpsb_read_fail: free_tlabel(host, node, packet->tlabel); free_hpsb_packet(packet); return retval;}struct hpsb_packet *hpsb_make_packet (struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length){ struct hpsb_packet *packet; if (length == 0) return NULL; if (length == 4) packet = hpsb_make_writeqpacket(host, node, addr, *buffer); else packet = hpsb_make_writebpacket(host, node, addr, length); if (!packet) return NULL; /* Sometimes this may be called without data, just to allocate the * packet. */ if (length != 4 && buffer) memcpy(packet->data, buffer, length); return packet;}int hpsb_write(struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length){ struct hpsb_packet *packet; int retval; if (length == 0) return -EINVAL; if (host->node_id == node) { switch(highlevel_write(host, node, node, buffer, addr, length)) { case RCODE_COMPLETE: return 0; case RCODE_TYPE_ERROR: return -EACCES; case RCODE_ADDRESS_ERROR: default: return -EINVAL; } } packet = hpsb_make_packet (host, node, addr, buffer, length); if (!packet) return -ENOMEM; packet->generation = get_hpsb_generation(host); if (!hpsb_send_packet(packet)) { retval = -EINVAL; goto hpsb_write_fail; } down(&packet->state_change); down(&packet->state_change); retval = hpsb_packet_success(packet);hpsb_write_fail: free_tlabel(host, node, packet->tlabel); free_hpsb_packet(packet); return retval;}/* We need a hpsb_lock64 function for the 64 bit equivalent. Probably. */int hpsb_lock(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode, quadlet_t *data, quadlet_t arg){ struct hpsb_packet *packet; int retval = 0, length; if (host->node_id == node) { switch(highlevel_lock(host, node, data, addr, *data, arg, extcode)) { case RCODE_COMPLETE: return 0; case RCODE_TYPE_ERROR: return -EACCES; case RCODE_ADDRESS_ERROR: default: return -EINVAL; } } packet = alloc_hpsb_packet(8); if (!packet) { return -ENOMEM; } packet->host = host; packet->tlabel = get_tlabel(host, node, 1); packet->node_id = node; switch (extcode) { case EXTCODE_MASK_SWAP: case EXTCODE_COMPARE_SWAP: case EXTCODE_BOUNDED_ADD: case EXTCODE_WRAP_ADD: length = 8; packet->data[0] = arg; packet->data[1] = *data; break; case EXTCODE_FETCH_ADD: case EXTCODE_LITTLE_ADD: length = 4; packet->data[0] = *data; break; default: return -EINVAL; } fill_async_lock(packet, addr, extcode, length); packet->generation = get_hpsb_generation(host); if (!hpsb_send_packet(packet)) { retval = -EINVAL; goto hpsb_lock_fail; } down(&packet->state_change); down(&packet->state_change); retval = hpsb_packet_success(packet); if (retval == 0) { *data = packet->data[0]; }hpsb_lock_fail: free_tlabel(host, node, packet->tlabel); free_hpsb_packet(packet); return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -