From 3581ab9bc0de9a07b576ad3df128f4bbab0b17c6 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Mon, 1 Sep 2003 06:16:27 -0700 Subject: [PATCH] [PATCH] Update IEEE1394 (r1047) subsys : - Added hpsb_make_streampacket() helper - Fix re-probe of bus after reset, when node's generation changes - Missing spinlock.h include for csr.c general : - Fix a few warnings from size mismatches in printk's raw1394 : - Added RAW1394_REQ_ASYNC_STREAM - Use vmalloc/vfree for larger buffer support ohci1394 : - Fix a few endianess bugs in ISO routines eth1394 : - Fix cleanup of failed packets --- drivers/ieee1394/csr.c | 1 + drivers/ieee1394/eth1394.c | 17 +++++---- drivers/ieee1394/ieee1394_core.c | 1 + drivers/ieee1394/ieee1394_transactions.c | 46 +++++++++++++++++------- drivers/ieee1394/ieee1394_transactions.h | 2 ++ drivers/ieee1394/nodemgr.c | 10 +++--- drivers/ieee1394/ohci1394.c | 8 ++--- drivers/ieee1394/raw1394.c | 40 ++++++++++++++------- drivers/ieee1394/raw1394.h | 1 + drivers/ieee1394/sbp2.c | 5 ++- 10 files changed, 87 insertions(+), 44 deletions(-) diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c index 687452338b21c..e69e6c6850f03 100644 --- a/drivers/ieee1394/csr.c +++ b/drivers/ieee1394/csr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "ieee1394_types.h" #include "hosts.h" diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 29409d251f1ff..4371f30f5d84b 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -89,7 +89,7 @@ #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 1020 $ Ben Collins "; + "$Rev: 1043 $ Ben Collins "; struct fragment_info { struct list_head list; @@ -1349,21 +1349,20 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) ptask->dest_node, ptask->addr, ptask->skb->data, tx_len)) { - goto fail; + free_hpsb_packet(packet); + return -1; } ptask->packet = packet; hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb, ptask); - if (hpsb_send_packet(packet)) - return 0; - -fail: - if (packet) + if (!hpsb_send_packet(packet)) { ether1394_free_packet(packet); + return -1; + } - return -1; + return 0; } @@ -1600,7 +1599,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy (info.driver, driver_name); - strcpy (info.version, "$Rev: 1020 $"); + strcpy (info.version, "$Rev: 1043 $"); /* FIXME XXX provide sane businfo */ strcpy (info.bus_info, "ieee1394"); if (copy_to_user (useraddr, &info, sizeof (info))) diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1f2ddaed055f9..79604fe7f9cde 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -1237,6 +1237,7 @@ EXPORT_SYMBOL(hpsb_get_tlabel); EXPORT_SYMBOL(hpsb_free_tlabel); EXPORT_SYMBOL(hpsb_make_readpacket); EXPORT_SYMBOL(hpsb_make_writepacket); +EXPORT_SYMBOL(hpsb_make_streampacket); EXPORT_SYMBOL(hpsb_make_lockpacket); EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 0272d93033196..6303261be6bd9 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -104,7 +104,7 @@ static void fill_async_stream_packet(struct hpsb_packet *packet, int length, int channel, int tag, int sync) { packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_STREAM_DATA << 4) | sync; + | (TCODE_STREAM_DATA << 4) | sync; packet->header_size = 4; packet->data_size = length; @@ -317,6 +317,35 @@ struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node return packet; } +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length, + int channel, int tag, int sync) +{ + struct hpsb_packet *packet; + + if (length == 0) + return NULL; + + packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + if (!packet) + return NULL; + + if (length % 4) { /* zero padding bytes */ + packet->data[length >> 2] = 0; + } + packet->host = host; + + if (hpsb_get_tlabel(packet)) { + free_hpsb_packet(packet); + return NULL; + } + + fill_async_stream_packet(packet, length, channel, tag, sync); + if (buffer) + memcpy(packet->data, buffer, length); + + return packet; +} + struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode, quadlet_t *data, quadlet_t arg) @@ -580,25 +609,18 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8; u8 specifier_id_lo = specifier_id & 0xff; - HPSB_VERBOSE("Send GASP: channel = %d, length = %d", channel, length); + HPSB_VERBOSE("Send GASP: channel = %d, length = %Zd", channel, length); length += 8; - - packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + + packet = hpsb_make_streampacket(host, NULL, length, channel, 3, 0); if (!packet) return -ENOMEM; - if (length % 4) { - packet->data[length / 4] = 0; - } - - packet->host = host; - fill_async_stream_packet(packet, length, channel, 3, 0); - packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi); packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff)); - memcpy(&(packet->data[2]), buffer, length - 4); + memcpy(&(packet->data[2]), buffer, length - 8); packet->generation = generation; diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index 0cd6e28a335cc..526a43ceb4960 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h @@ -25,6 +25,8 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int tag, int sync); struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length); +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, + int length, int channel, int tag, int sync); /* * hpsb_packet_success - Make sense of the ack and reply codes and diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index b97c928417277..4a74607438854 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -1304,12 +1304,14 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions, * unregister all the unit directories. */ nodemgr_remove_node_uds(ne); + /* With all the ud's gone, mark the generation current, + * this way the probe will succeed. */ + ne->generation = generation; + /* This will re-register our unitdir's */ nodemgr_process_config_rom (hi, ne, busoptions); - } - - /* Since that's done, we can declare this record current */ - ne->generation = generation; + } else + ne->generation = generation; /* Update unit_dirs with attached drivers */ bus_for_each_dev(&ieee1394_bus_type, NULL, ne, diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index a98f7d1e61ea8..10c2accd219c9 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -161,7 +161,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 1023 $ Ben Collins "; + "$Rev: 1045 $ Ben Collins "; /* Module Parameters */ static int phys_dma = 1; @@ -1451,7 +1451,7 @@ static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, in if (sync != -1) { /* set sync flag on first DMA descriptor */ struct dma_cmd *cmd = &recv->block[recv->block_dma]; - cmd->control |= DMA_CTL_WAIT; + cmd->control |= cpu_to_le32(DMA_CTL_WAIT); /* match sync field */ contextMatch |= (sync&0xf)<<8; @@ -1675,10 +1675,10 @@ static void ohci_iso_recv_bufferfill_task(struct hpsb_iso *iso, struct ohci_iso_ struct dma_cmd *im = &recv->block[recv->block_dma]; /* check the DMA descriptor for new writes to xferStatus */ - u16 xferstatus = im->status >> 16; + u16 xferstatus = le32_to_cpu(im->status) >> 16; /* rescount is the number of bytes *remaining to be written* in the block */ - u16 rescount = im->status & 0xFFFF; + u16 rescount = le32_to_cpu(im->status) & 0xFFFF; unsigned char event = xferstatus & 0x1F; diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index be2e677e28d2e..96f5f9305e9a2 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -180,6 +180,7 @@ static void queue_complete_cb(struct pending_request *req) if ((req->req.type == RAW1394_REQ_ASYNC_READ) || (req->req.type == RAW1394_REQ_ASYNC_WRITE) || + (req->req.type == RAW1394_REQ_ASYNC_STREAM) || (req->req.type == RAW1394_REQ_LOCK) || (req->req.type == RAW1394_REQ_LOCK64)) hpsb_free_tlabel(packet); @@ -689,6 +690,21 @@ static int handle_async_request(struct file_info *fi, req->req.length = 0; break; + case RAW1394_REQ_ASYNC_STREAM: + DBGMSG("stream_request called"); + + packet = hpsb_make_streampacket(fi->host, NULL, req->req.length, node & 0x3f/*channel*/, + (req->req.misc >> 16) & 0x3, req->req.misc & 0xf); + if (!packet) + return -ENOMEM; + + if (copy_from_user(packet->data, int2ptr(req->req.sendb), + req->req.length)) + req->req.error = RAW1394_ERROR_MEMFAULT; + + req->req.length = 0; + break; + case RAW1394_REQ_LOCK: DBGMSG("lock_request called"); if ((req->req.misc == EXTCODE_FETCH_ADD) @@ -892,7 +908,7 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, struct arm_request_response *arm_req_resp = NULL; DBGMSG("arm_read called by node: %X" - "addr: %4.4x %8.8x length: %u", nodeid, + "addr: %4.4x %8.8x length: %Zu", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), length); spin_lock(&host_info_lock); @@ -1028,7 +1044,7 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid, struct arm_request_response *arm_req_resp = NULL; DBGMSG("arm_write called by node: %X" - "addr: %4.4x %8.8x length: %u", nodeid, + "addr: %4.4x %8.8x length: %Zu", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), length); spin_lock(&host_info_lock); @@ -1566,8 +1582,8 @@ static int arm_register(struct file_info *fi, struct pending_request *req) req->req.length, ((req->req.misc >> 8) & 0xFF), (req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF)); /* check addressrange */ - if ((((req->req.address) & ~((u64)0xFFFFFFFFFFFFLL)) != 0) || - (((req->req.address + req->req.length) & ~((u64)0xFFFFFFFFFFFFLL)) != 0)) { + if ((((req->req.address) & ~(0xFFFFFFFFFFFFULL)) != 0) || + (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) != 0)) { req->req.length = 0; return (-EINVAL); } @@ -1578,7 +1594,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) return (-ENOMEM); } /* allocation of addr_space_buffer */ - addr->addr_space_buffer = (u8 *)kmalloc(req->req.length,SLAB_KERNEL); + addr->addr_space_buffer = (u8 *)vmalloc(req->req.length); if (!(addr->addr_space_buffer)) { kfree(addr); req->req.length = 0; @@ -1592,7 +1608,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) /* init: user -> kernel */ if (copy_from_user(addr->addr_space_buffer,int2ptr(req->req.sendb), req->req.length)) { - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); return (-EFAULT); } @@ -1633,7 +1649,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) } if (same_host) { /* addressrange occupied by same host */ - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EALREADY); @@ -1668,7 +1684,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) int2ptr(&addr->start),sizeof(u64))) { printk(KERN_ERR "raw1394: arm_register failed " " address-range-entry is invalid -> EFAULT !!!\n"); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EFAULT); @@ -1686,7 +1702,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) list_add_tail(&addr->addr_list, &fi->addr_list); } else { DBGMSG("arm_register failed errno: %d \n",retval); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); return (-EALREADY); @@ -1760,7 +1776,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) if (another_host) { DBGMSG("delete entry from list -> success"); list_del(&addr->addr_list); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ spin_unlock_irqrestore(&host_info_lock, flags); @@ -1775,7 +1791,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) DBGMSG("delete entry from list -> success"); list_del(&addr->addr_list); spin_unlock_irqrestore(&host_info_lock, flags); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ return sizeof(struct raw1394_request); @@ -2440,7 +2456,7 @@ static int raw1394_release(struct inode *inode, struct file *file) } DBGMSG("raw1394_release: delete addr_entry from list"); list_del(&addr->addr_list); - kfree(addr->addr_space_buffer); + vfree(addr->addr_space_buffer); kfree(addr); } /* while */ spin_unlock_irq(&host_info_lock); diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h index 5f3abd58b82a8..e178bda643823 100644 --- a/drivers/ieee1394/raw1394.h +++ b/drivers/ieee1394/raw1394.h @@ -19,6 +19,7 @@ #define RAW1394_REQ_LOCK64 103 #define RAW1394_REQ_ISO_SEND 104 #define RAW1394_REQ_ASYNC_SEND 105 +#define RAW1394_REQ_ASYNC_STREAM 106 #define RAW1394_REQ_ISO_LISTEN 200 #define RAW1394_REQ_FCP_LISTEN 201 diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index fb86f80c03260..3cd5840f35296 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -80,7 +80,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 1018 $ Ben Collins "; + "$Rev: 1034 $ Ben Collins "; /* * Module load parameter definitions @@ -1002,9 +1002,8 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); /* Remove it from the scsi layer now */ - if (sdev) { + if (sdev) scsi_remove_device(sdev); - } sbp2util_remove_command_orb_pool(scsi_id); -- 2.53.0