Commit 3581ab9b authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[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
parent 054cb795
......@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/param.h>
#include <linux/spinlock.h>
#include "ieee1394_types.h"
#include "hosts.h"
......
......@@ -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 <bcollins@debian.org>";
"$Rev: 1043 $ Ben Collins <bcollins@debian.org>";
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)))
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......
......@@ -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,
......
......@@ -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 <bcollins@debian.org>";
"$Rev: 1045 $ Ben Collins <bcollins@debian.org>";
/* 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;
......
......@@ -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);
......
......@@ -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
......
......@@ -80,7 +80,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 1018 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1034 $ Ben Collins <bcollins@debian.org>";
/*
* 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment