Commit e2a0532d authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[PATCH] ieee1394 update (r925)

- Remove some 2.4 compatibility macros
- Fix userspace pointer misuse in video1394 ioctl. Caught by the
  Stanford Checker. Gotta love the automated systems.
- Move our hotplug stuff around, to make the transition to putting our
  module dev table in mod_devicetable.h.
- Fix ohci1394 for possible crash with async stream packets. Cleaned up
  some debug messages.
parent 077570f0
......@@ -835,8 +835,8 @@ static int stream_alloc_packet_lists(struct stream *s)
max_nevents = fraction_ceil(&s->samples_per_cycle);
max_packet_size = max_nevents * s->dimension * 4 + 8;
s->packet_pool = hpsb_pci_pool_create("packet pool", s->host->ohci->dev,
max_packet_size, 0, 0 ,SLAB_KERNEL);
s->packet_pool = pci_pool_create("packet pool", s->host->ohci->dev,
max_packet_size, 0, 0);
if (s->packet_pool == NULL)
return -1;
......@@ -1021,9 +1021,9 @@ struct stream *stream_alloc(struct amdtp_host *host)
return NULL;
}
s->descriptor_pool = hpsb_pci_pool_create("descriptor pool", host->ohci->dev,
s->descriptor_pool = pci_pool_create("descriptor pool", host->ohci->dev,
sizeof(struct descriptor_block),
16, 0 ,SLAB_KERNEL);
16, 0);
if (s->descriptor_pool == NULL) {
kfree(s->input);
......
......@@ -115,7 +115,7 @@
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "ieee1394_hotplug.h"
#include "nodemgr.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
......
......@@ -56,6 +56,7 @@
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <asm/delay.h>
#include <asm/semaphore.h>
#include <net/arp.h>
......@@ -78,7 +79,7 @@
printk(KERN_ERR fmt, ## args)
static char version[] __devinitdata =
"$Rev: 906 $ Ben Collins <bcollins@debian.org>";
"$Rev: 918 $ Ben Collins <bcollins@debian.org>";
/* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394"
......@@ -853,8 +854,8 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
ptask->dest_node = dest_node;
/* TODO: When 2.4 is out of the way, give each of our ethernet
* dev's a workqueue to handle these. */
HPSB_INIT_WORK(&ptask->tq, hpsb_write_sched, ptask);
hpsb_schedule_work(&ptask->tq);
INIT_WORK(&ptask->tq, hpsb_write_sched, ptask);
schedule_work(&ptask->tq);
return 0;
fail:
......
......@@ -67,7 +67,7 @@ struct packet_task {
struct sk_buff *skb; /* Socket buffer we are sending */
nodeid_t dest_node; /* Destination of the packet */
u64 addr; /* Address */
struct hpsb_queue_struct tq; /* The task */
struct work_struct tq; /* The task */
eth1394_tx_type tx_type; /* Send data via GASP or Write Req. */
};
......
......@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "ieee1394_types.h"
#include "hosts.h"
......@@ -140,7 +141,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
atomic_set(&h->generation, 0);
HPSB_INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
h->topology_map = h->csr.topology_map + 3;
h->speed_map = (u8 *)(h->csr.speed_map + 2);
......
......@@ -4,6 +4,7 @@
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <asm/semaphore.h>
#include "ieee1394_types.h"
......@@ -32,7 +33,7 @@ struct hpsb_host {
struct list_head pending_packets;
spinlock_t pending_pkt_lock;
struct hpsb_queue_struct timeout_tq;
struct work_struct timeout_tq;
unsigned char iso_listen_count[64];
......
......@@ -31,6 +31,8 @@
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
#include <asm/byteorder.h>
#include <asm/semaphore.h>
......@@ -42,7 +44,6 @@
#include "ieee1394_transactions.h"
#include "csr.h"
#include "nodemgr.h"
#include "ieee1394_hotplug.h"
#include "dma.h"
#include "iso.h"
......@@ -437,7 +438,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
up(&packet->state_change);
hpsb_schedule_work(&host->timeout_tq);
schedule_work(&host->timeout_tq);
}
/**
......@@ -985,7 +986,7 @@ void abort_timedouts(struct hpsb_host *host)
}
if (!list_empty(&host->pending_packets))
hpsb_schedule_work(&host->timeout_tq);
schedule_work(&host->timeout_tq);
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
......
#ifndef _IEEE1394_HOTPLUG_H
#define _IEEE1394_HOTPLUG_H
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mod_devicetable.h>
#include "ieee1394_core.h"
#include "nodemgr.h"
/* Unit spec id and sw version entry for some protocols */
#define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define AVC_SW_VERSION_ENTRY 0x00010001
#define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define CAMERA_SW_VERSION_ENTRY 0x00000100
/* Check to make sure this all isn't already defined */
#ifndef IEEE1394_MATCH_VENDOR_ID
#define IEEE1394_MATCH_VENDOR_ID 0x0001
#define IEEE1394_MATCH_MODEL_ID 0x0002
#define IEEE1394_MATCH_SPECIFIER_ID 0x0004
#define IEEE1394_MATCH_VERSION 0x0008
/*
* Unit spec id and sw version entry for some protocols
*/
#define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define AVC_SW_VERSION_ENTRY 0x00010001
#define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D
#define CAMERA_SW_VERSION_ENTRY 0x00000100
struct ieee1394_device_id {
u32 match_flags;
u32 vendor_id;
......@@ -28,33 +28,6 @@ struct ieee1394_device_id {
void *driver_data;
};
struct hpsb_protocol_driver {
/* The name of the driver, e.g. SBP2 or IP1394 */
const char *name;
/*
* The device id table describing the protocols and/or devices
* supported by this driver. This is used by the nodemgr to
* decide if a driver could support a given node, but the
* probe function below can implement further protocol
* dependent or vendor dependent checking.
*/
struct ieee1394_device_id *id_table;
/*
* The update function is called when the node has just
* survived a bus reset, i.e. it is still present on the bus.
* However, it may be necessary to reestablish the connection
* or login into the node again, depending on the protocol.
*/
void (*update)(struct unit_directory *ud);
/* Our LDM structure */
struct device_driver driver;
};
int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
#endif
#endif /* _IEEE1394_HOTPLUG_H */
......@@ -18,58 +18,12 @@
#define minor(dev) MINOR(dev)
#endif
#ifndef __devexit_p
#define __devexit_p(x) x
#endif
#include <linux/spinlock.h>
#ifndef list_for_each_safe
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
#define pte_offset_kernel pte_offset
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
/* Compatibility for task/work queues */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,42)
/* Use task queue */
#include <linux/tqueue.h>
#define hpsb_queue_struct tq_struct
#define hpsb_queue_list list
#define hpsb_schedule_work(x) schedule_task(x)
#define HPSB_INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z)
#define HPSB_PREPARE_WORK(x,y,z) PREPARE_TQUEUE(x,y,z)
#else
/* Use work queue */
#include <linux/workqueue.h>
#define hpsb_queue_struct work_struct
#define hpsb_queue_list entry
#define hpsb_schedule_work(x) schedule_work(x)
#define HPSB_INIT_WORK(x,y,z) INIT_WORK(x,y,z)
#define HPSB_PREPARE_WORK(x,y,z) PREPARE_WORK(x,y,z)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
/* pci_pool_create changed. does not take the flags arg any longer */
#define hpsb_pci_pool_create(a,b,c,d,e,f) pci_pool_create(a,b,c,d,e,f)
#else
#define hpsb_pci_pool_create(a,b,c,d,e,f) pci_pool_create(a,b,c,d,e)
#endif
/* Transaction Label handling */
struct hpsb_tlabel_pool {
DECLARE_BITMAP(pool, 64);
......
......@@ -22,9 +22,9 @@
#include "ieee1394_types.h"
#include "ieee1394.h"
#include "nodemgr.h"
#include "hosts.h"
#include "ieee1394_transactions.h"
#include "ieee1394_hotplug.h"
#include "highlevel.h"
#include "csr.h"
#include "nodemgr.h"
......
......@@ -21,6 +21,8 @@
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
#include "ieee1394_core.h"
#include "ieee1394_hotplug.h"
#define CONFIG_ROM_BUS_INFO_LENGTH(q) ((q) >> 24)
#define CONFIG_ROM_BUS_CRC_LENGTH(q) (((q) >> 16) & 0xff)
......@@ -142,6 +144,34 @@ struct node_entry {
quadlet_t quadlets[0];
};
struct hpsb_protocol_driver {
/* The name of the driver, e.g. SBP2 or IP1394 */
const char *name;
/*
* The device id table describing the protocols and/or devices
* supported by this driver. This is used by the nodemgr to
* decide if a driver could support a given node, but the
* probe function below can implement further protocol
* dependent or vendor dependent checking.
*/
struct ieee1394_device_id *id_table;
/*
* The update function is called when the node has just
* survived a bus reset, i.e. it is still present on the bus.
* However, it may be necessary to reestablish the connection
* or login into the node again, depending on the protocol.
*/
void (*update)(struct unit_directory *ud);
/* Our LDM structure */
struct device_driver driver;
};
int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
static inline int hpsb_node_entry_valid(struct node_entry *ne)
{
return ne->generation == get_hpsb_generation(ne->host);
......
......@@ -164,7 +164,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: 908 $ Ben Collins <bcollins@debian.org>";
"$Rev: 921 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
......@@ -623,8 +623,10 @@ static void insert_packet(struct ti_ohci *ohci,
u32 cycleTimer;
int idx = d->prg_ind;
DBGMSG(ohci->id, "Inserting packet for node %d, tlabel=%d, tcode=0x%x, speed=%d",
packet->node_id, packet->tlabel, packet->tcode, packet->speed_code);
DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT
", tlabel=%d, tcode=0x%x, speed=%d",
NODE_BUS_ARGS(packet->node_id), packet->tlabel,
packet->tcode, packet->speed_code);
d->prg_cpu[idx]->begin.address = 0;
d->prg_cpu[idx]->begin.branchAddress = 0;
......@@ -1505,6 +1507,7 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
so disable branch and enable interrupt */
next->branchAddress = 0;
next->control |= cpu_to_le32(3 << 20);
next->status = cpu_to_le32(recv->buf_stride);
/* link prev to next */
prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog,
......@@ -2691,19 +2694,25 @@ static void dma_trm_tasklet (unsigned long data)
#ifdef OHCI1394_DEBUG
if (datasize)
DBGMSG(ohci->id,
"Packet sent to node %d tcode=0x%X tLabel="
"0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d",
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])
>>16)&0x3f,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
>>4)&0xf,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
>>10)&0x3f,
status&0x1f, (status>>5)&0x3,
le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])
>>16,
d->ctx);
if(((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa)
DBGMSG(ohci->id,
"Stream packet sent to channel %d tcode=0x%X "
"ack=0x%X spd=%d dataLength=%d ctx=%d",
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>8)&0x3f,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
status&0x1f, (status>>5)&0x3,
le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16,
d->ctx);
else
DBGMSG(ohci->id,
"Packet sent to node %d tcode=0x%X tLabel="
"0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d",
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16)&0x3f,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
(le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>10)&0x3f,
status&0x1f, (status>>5)&0x3,
le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])>>16,
d->ctx);
else
DBGMSG(ohci->id,
"Packet sent to node %d tcode=0x%X tLabel="
......@@ -2888,8 +2897,8 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
return -ENOMEM;
}
d->prg_pool = hpsb_pci_pool_create("ohci1394 rcv prg", ohci->dev,
sizeof(struct dma_cmd), 4, 0, SLAB_KERNEL);
d->prg_pool = pci_pool_create("ohci1394 rcv prg", ohci->dev,
sizeof(struct dma_cmd), 4, 0);
OHCI_DMA_ALLOC("dma_rcv prg pool");
for (i=0; i<d->num_desc; i++) {
......@@ -3016,8 +3025,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));
memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
d->prg_pool = hpsb_pci_pool_create("ohci1394 trm prg", ohci->dev,
sizeof(struct at_dma_prg), 4, 0, SLAB_KERNEL);
d->prg_pool = pci_pool_create("ohci1394 trm prg", ohci->dev,
sizeof(struct at_dma_prg), 4, 0);
OHCI_DMA_ALLOC("dma_rcv prg pool");
for (i = 0; i < d->num_desc; i++) {
......
......@@ -42,6 +42,7 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/kdev_t.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/io.h>
......
......@@ -45,11 +45,11 @@
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "ieee1394_core.h"
#include "nodemgr.h"
#include "hosts.h"
#include "highlevel.h"
#include "iso.h"
#include "ieee1394_transactions.h"
#include "ieee1394_hotplug.h"
#include "raw1394.h"
#include "raw1394-private.h"
......
......@@ -283,22 +283,19 @@
#include "../scsi/scsi.h"
#include "../scsi/hosts.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,47)
#include "../scsi/sd.h"
#endif
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "ieee1394_core.h"
#include "nodemgr.h"
#include "hosts.h"
#include "nodemgr.h"
#include "highlevel.h"
#include "ieee1394_transactions.h"
#include "ieee1394_hotplug.h"
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 912 $ James Goodwin <jamesg@filanet.com>";
"$Rev: 919 $ James Goodwin <jamesg@filanet.com>";
/*
* Module load parameter definitions
......@@ -2914,15 +2911,9 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
/*
* Tell scsi stack that we're done with this command
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_lock_irqsave(&io_request_lock,flags);
done (SCpnt);
spin_unlock_irqrestore(&io_request_lock,flags);
#else
spin_lock_irqsave(scsi_id->hi->scsi_host->host_lock,flags);
done (SCpnt);
spin_unlock_irqrestore(scsi_id->hi->scsi_host->host_lock,flags);
#endif
return;
}
......
......@@ -47,11 +47,12 @@
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "ieee1394_hotplug.h"
#include "nodemgr.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "video1394.h"
#include "nodemgr.h"
#include "dma.h"
#include "ohci1394.h"
......@@ -991,6 +992,8 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
struct video1394_queue_variable qv;
struct dma_iso_ctx *d;
qv.packet_sizes = NULL;
if(copy_from_user(&v, (void *)arg, sizeof(v)))
return -EFAULT;
......@@ -1003,12 +1006,22 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
}
if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
unsigned int *psizes;
int buf_size = d->nb_cmd * sizeof(unsigned int);
if (copy_from_user(&qv, (void *)arg, sizeof(qv)))
return -EFAULT;
if (!access_ok(VERIFY_READ, qv.packet_sizes,
d->nb_cmd * sizeof(unsigned int))) {
psizes = kmalloc(buf_size, GFP_KERNEL);
if (!psizes)
return -ENOMEM;
if (copy_from_user(psizes, qv.packet_sizes, buf_size)) {
kfree(psizes);
return -EFAULT;
}
qv.packet_sizes = psizes;
}
spin_lock_irqsave(&d->lock,flags);
......@@ -1017,6 +1030,8 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
PRINT(KERN_ERR, ohci->id,
"Buffer %d is already used",v.buffer);
spin_unlock_irqrestore(&d->lock,flags);
if (qv.packet_sizes)
kfree(qv.packet_sizes);
return -EFAULT;
}
......@@ -1070,6 +1085,10 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
reg_write(ohci, d->ctrlSet, 0x1000);
}
}
if (qv.packet_sizes)
kfree(qv.packet_sizes);
return 0;
}
......
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