Commit 1eee21ab authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: Add more documentation to firewire-cdev.h
  firewire: fix ioctl() return code
  firewire: fix setting tag and sy in iso transmission
  firewire: fw-sbp2: fix another small generation access bug
  firewire: fw-sbp2: enforce s/g segment size limit
  firewire: fw_send_request_sync()
  ieee1394: survive a few seconds connection loss
  ieee1394: nodemgr clean up class iterators
  ieee1394: dv1394, video1394: remove unnecessary expressions
  ieee1394: raw1394: make write() thread-safe
  ieee1394: raw1394: narrow down the state_mutex protected region
  ieee1394: raw1394: replace BKL by local mutex, make ioctl() and mmap() thread-safe
  ieee1394: sbp2: enforce s/g segment size limit
  ieee1394: sbp2: check for DMA mapping failures
  ieee1394: sbp2: stricter dma_sync
  ieee1394: Use DIV_ROUND_UP
parents 9d85db22 be585c07
......@@ -189,39 +189,16 @@ static const char gap_count_table[] = {
63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
};
struct bm_data {
struct fw_transaction t;
struct {
__be32 arg;
__be32 data;
} lock;
u32 old;
int rcode;
struct completion done;
};
static void
complete_bm_lock(struct fw_card *card, int rcode,
void *payload, size_t length, void *data)
{
struct bm_data *bmd = data;
if (rcode == RCODE_COMPLETE)
bmd->old = be32_to_cpu(*(__be32 *) payload);
bmd->rcode = rcode;
complete(&bmd->done);
}
static void
fw_card_bm_work(struct work_struct *work)
{
struct fw_card *card = container_of(work, struct fw_card, work.work);
struct fw_device *root_device;
struct fw_node *root_node, *local_node;
struct bm_data bmd;
unsigned long flags;
int root_id, new_root_id, irm_id, gap_count, generation, grace;
int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
bool do_reset = false;
__be32 lock_data[2];
spin_lock_irqsave(&card->lock, flags);
local_node = card->local_node;
......@@ -263,33 +240,28 @@ fw_card_bm_work(struct work_struct *work)
goto pick_me;
}
bmd.lock.arg = cpu_to_be32(0x3f);
bmd.lock.data = cpu_to_be32(local_node->node_id);
lock_data[0] = cpu_to_be32(0x3f);
lock_data[1] = cpu_to_be32(local_node->node_id);
spin_unlock_irqrestore(&card->lock, flags);
init_completion(&bmd.done);
fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP,
irm_id, generation,
SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
&bmd.lock, sizeof(bmd.lock),
complete_bm_lock, &bmd);
wait_for_completion(&bmd.done);
rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
irm_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
lock_data, sizeof(lock_data));
if (bmd.rcode == RCODE_GENERATION) {
/*
* Another bus reset happened. Just return,
* the BM work has been rescheduled.
*/
if (rcode == RCODE_GENERATION)
/* Another bus reset, BM work has been rescheduled. */
goto out;
}
if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f)
if (rcode == RCODE_COMPLETE &&
lock_data[0] != cpu_to_be32(0x3f))
/* Somebody else is BM, let them do the work. */
goto out;
spin_lock_irqsave(&card->lock, flags);
if (bmd.rcode != RCODE_COMPLETE) {
if (rcode != RCODE_COMPLETE) {
/*
* The lock request failed, maybe the IRM
* isn't really IRM capable after all. Let's
......
......@@ -720,8 +720,8 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
#define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff)
#define GET_INTERRUPT(v) (((v) >> 16) & 0x01)
#define GET_SKIP(v) (((v) >> 17) & 0x01)
#define GET_TAG(v) (((v) >> 18) & 0x02)
#define GET_SY(v) (((v) >> 20) & 0x04)
#define GET_TAG(v) (((v) >> 18) & 0x03)
#define GET_SY(v) (((v) >> 20) & 0x0f)
#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
static int ioctl_queue_iso(struct client *client, void *buffer)
......@@ -913,7 +913,7 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
return -EFAULT;
}
return 0;
return retval;
}
static long
......
......@@ -381,46 +381,21 @@ static struct device_attribute fw_device_attributes[] = {
__ATTR_NULL,
};
struct read_quadlet_callback_data {
struct completion done;
int rcode;
u32 data;
};
static void
complete_transaction(struct fw_card *card, int rcode,
void *payload, size_t length, void *data)
{
struct read_quadlet_callback_data *callback_data = data;
if (rcode == RCODE_COMPLETE)
callback_data->data = be32_to_cpu(*(__be32 *)payload);
callback_data->rcode = rcode;
complete(&callback_data->done);
}
static int
read_rom(struct fw_device *device, int generation, int index, u32 *data)
{
struct read_quadlet_callback_data callback_data;
struct fw_transaction t;
u64 offset;
int rcode;
/* device->node_id, accessed below, must not be older than generation */
smp_rmb();
init_completion(&callback_data.done);
offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST,
device->node_id, generation, device->max_speed,
offset, NULL, 4, complete_transaction, &callback_data);
wait_for_completion(&callback_data.done);
*data = callback_data.data;
(CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4,
data, 4);
be32_to_cpus(data);
return callback_data.rcode;
return rcode;
}
#define READ_BIB_ROM_SIZE 256
......
......@@ -29,6 +29,7 @@
*/
#include <linux/blkdev.h>
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
......@@ -181,10 +182,16 @@ struct sbp2_target {
#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
#define SBP2_ORB_NULL 0x80000000
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_RETRY_LIMIT 0xf /* 15 retries */
#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */
/*
* The default maximum s/g segment size of a FireWire controller is
* usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
* be quadlet-aligned, we set the length limit to 0xffff & ~3.
*/
#define SBP2_MAX_SEG_SIZE 0xfffc
/* Unit directory keys */
#define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a
#define SBP2_CSR_FIRMWARE_REVISION 0x3c
......@@ -621,25 +628,15 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
return retval;
}
static void
complete_agent_reset_write(struct fw_card *card, int rcode,
void *payload, size_t length, void *done)
{
complete(done);
}
static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
DECLARE_COMPLETION_ONSTACK(done);
struct fw_transaction t;
static u32 z;
__be32 d = 0;
fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
lu->command_block_agent_address + SBP2_AGENT_RESET,
&z, sizeof(z), complete_agent_reset_write, &done);
wait_for_completion(&done);
fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
lu->command_block_agent_address + SBP2_AGENT_RESET,
&d, sizeof(d));
}
static void
......@@ -653,7 +650,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_transaction *t;
static u32 z;
static __be32 d;
t = kmalloc(sizeof(*t), GFP_ATOMIC);
if (t == NULL)
......@@ -662,7 +659,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
lu->command_block_agent_address + SBP2_AGENT_RESET,
&z, sizeof(z), complete_agent_reset_write_no_wait, t);
&d, sizeof(d), complete_agent_reset_write_no_wait, t);
}
static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
......@@ -823,13 +820,6 @@ static void sbp2_target_put(struct sbp2_target *tgt)
kref_put(&tgt->kref, sbp2_release_target);
}
static void
complete_set_busy_timeout(struct fw_card *card, int rcode,
void *payload, size_t length, void *done)
{
complete(done);
}
/*
* Write retransmit retry values into the BUSY_TIMEOUT register.
* - The single-phase retry protocol is supported by all SBP-2 devices, but the
......@@ -849,17 +839,12 @@ complete_set_busy_timeout(struct fw_card *card, int rcode,
static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
DECLARE_COMPLETION_ONSTACK(done);
struct fw_transaction t;
static __be32 busy_timeout;
busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
__be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
sizeof(busy_timeout), complete_set_busy_timeout, &done);
wait_for_completion(&done);
fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT,
&d, sizeof(d));
}
static void sbp2_reconnect(struct work_struct *work);
......@@ -1121,6 +1106,10 @@ static int sbp2_probe(struct device *dev)
struct Scsi_Host *shost;
u32 model, firmware_revision;
if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
BUG_ON(dma_set_max_seg_size(device->card->device,
SBP2_MAX_SEG_SIZE));
shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
if (shost == NULL)
return -ENOMEM;
......@@ -1369,14 +1358,12 @@ static int
sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
struct sbp2_logical_unit *lu)
{
struct scatterlist *sg;
int sg_len, l, i, j, count;
dma_addr_t sg_addr;
sg = scsi_sglist(orb->cmd);
count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
orb->cmd->sc_data_direction);
if (count == 0)
struct scatterlist *sg = scsi_sglist(orb->cmd);
int i, n;
n = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
orb->cmd->sc_data_direction);
if (n == 0)
goto fail;
/*
......@@ -1386,7 +1373,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
* as the second generation iPod which doesn't support page
* tables.
*/
if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
if (n == 1) {
orb->request.data_descriptor.high =
cpu_to_be32(lu->tgt->address_high);
orb->request.data_descriptor.low =
......@@ -1396,29 +1383,9 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
return 0;
}
/*
* Convert the scatterlist to an sbp2 page table. If any
* scatterlist entries are too big for sbp2, we split them as we
* go. Even if we ask the block I/O layer to not give us sg
* elements larger than 65535 bytes, some IOMMUs may merge sg elements
* during DMA mapping, and Linux currently doesn't prevent this.
*/
for (i = 0, j = 0; i < count; i++, sg = sg_next(sg)) {
sg_len = sg_dma_len(sg);
sg_addr = sg_dma_address(sg);
while (sg_len) {
/* FIXME: This won't get us out of the pinch. */
if (unlikely(j >= ARRAY_SIZE(orb->page_table))) {
fw_error("page table overflow\n");
goto fail_page_table;
}
l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
orb->page_table[j].low = cpu_to_be32(sg_addr);
orb->page_table[j].high = cpu_to_be32(l << 16);
sg_addr += l;
sg_len -= l;
j++;
}
for_each_sg(sg, sg, n, i) {
orb->page_table[i].high = cpu_to_be32(sg_dma_len(sg) << 16);
orb->page_table[i].low = cpu_to_be32(sg_dma_address(sg));
}
orb->page_table_bus =
......@@ -1437,13 +1404,13 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high);
orb->request.data_descriptor.low = cpu_to_be32(orb->page_table_bus);
orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT |
COMMAND_ORB_DATA_SIZE(j));
COMMAND_ORB_DATA_SIZE(n));
return 0;
fail_page_table:
dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
orb->cmd->sc_data_direction);
dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
scsi_sg_count(orb->cmd), orb->cmd->sc_data_direction);
fail:
return -ENOMEM;
}
......@@ -1456,7 +1423,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
unsigned int max_payload;
int retval = SCSI_MLQUEUE_HOST_BUSY;
int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
/*
* Bidirectional commands are not yet implemented, and unknown
......@@ -1500,6 +1467,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
if (cmd->sc_data_direction == DMA_FROM_DEVICE)
orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION);
generation = device->generation;
smp_rmb(); /* sbp2_map_scatterlist looks at tgt->address_high */
if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
goto out;
......@@ -1512,7 +1482,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
if (dma_mapping_error(device->card->device, orb->base.request_bus))
goto out;
sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation,
sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation,
lu->command_block_agent_address + SBP2_ORB_POINTER);
retval = 0;
out:
......@@ -1564,6 +1534,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
return 0;
}
......
......@@ -247,7 +247,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
*/
void
fw_send_request(struct fw_card *card, struct fw_transaction *t,
int tcode, int node_id, int generation, int speed,
int tcode, int destination_id, int generation, int speed,
unsigned long long offset,
void *payload, size_t length,
fw_transaction_callback_t callback, void *callback_data)
......@@ -279,13 +279,14 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
card->tlabel_mask |= (1 << tlabel);
t->node_id = node_id;
t->node_id = destination_id;
t->tlabel = tlabel;
t->callback = callback;
t->callback_data = callback_data;
fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id,
generation, speed, offset, payload, length);
fw_fill_request(&t->packet, tcode, t->tlabel,
destination_id, card->node_id, generation,
speed, offset, payload, length);
t->packet.callback = transmit_complete_callback;
list_add_tail(&t->link, &card->transaction_list);
......@@ -296,6 +297,45 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
}
EXPORT_SYMBOL(fw_send_request);
struct transaction_callback_data {
struct completion done;
void *payload;
int rcode;
};
static void transaction_callback(struct fw_card *card, int rcode,
void *payload, size_t length, void *data)
{
struct transaction_callback_data *d = data;
if (rcode == RCODE_COMPLETE)
memcpy(d->payload, payload, length);
d->rcode = rcode;
complete(&d->done);
}
/**
* fw_run_transaction - send request and sleep until transaction is completed
*
* Returns the RCODE.
*/
int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
int generation, int speed, unsigned long long offset,
void *data, size_t length)
{
struct transaction_callback_data d;
struct fw_transaction t;
init_completion(&d.done);
d.payload = data;
fw_send_request(card, &t, tcode, destination_id, generation, speed,
offset, data, length, transaction_callback, &d);
wait_for_completion(&d.done);
return d.rcode;
}
EXPORT_SYMBOL(fw_run_transaction);
static DEFINE_MUTEX(phy_config_mutex);
static DECLARE_COMPLETION(phy_config_done);
......
......@@ -426,11 +426,14 @@ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
void
fw_send_request(struct fw_card *card, struct fw_transaction *t,
int tcode, int node_id, int generation, int speed,
unsigned long long offset,
void *data, size_t length,
int tcode, int destination_id, int generation, int speed,
unsigned long long offset, void *data, size_t length,
fw_transaction_callback_t callback, void *callback_data);
int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
int generation, int speed, unsigned long long offset,
void *data, size_t length);
int fw_cancel_transaction(struct fw_card *card,
struct fw_transaction *transaction);
......
......@@ -84,7 +84,7 @@ static const u8 csr1212_key_id_type_map[0x30] = {
#define quads_to_bytes(_q) ((_q) * sizeof(u32))
#define bytes_to_quads(_b) (((_b) + sizeof(u32) - 1) / sizeof(u32))
#define bytes_to_quads(_b) DIV_ROUND_UP(_b, sizeof(u32))
static void free_keyval(struct csr1212_keyval *kv)
{
......
......@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
/* default SYT offset is 3 cycles */
init->syt_offset = 3;
if ( (init->channel > 63) || (init->channel < 0) )
if (init->channel > 63)
init->channel = 63;
chan_mask = (u64)1 << init->channel;
......
......@@ -1361,7 +1361,7 @@ static unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
hdr->ff.dgl = dgl;
adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
}
return (dg_size + adj_max_payload - 1) / adj_max_payload;
return DIV_ROUND_UP(dg_size, adj_max_payload);
}
static unsigned int ether1394_encapsulate(struct sk_buff *skb,
......
This diff is collapsed.
......@@ -110,7 +110,7 @@ struct node_entry {
struct device node_dev;
/* Means this node is not attached anymore */
int in_limbo;
bool in_limbo;
struct csr1212_csr *csr;
};
......
......@@ -22,6 +22,7 @@ enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0,
struct file_info {
struct list_head list;
struct mutex state_mutex;
enum { opened, initialized, connected } state;
unsigned int protocol_version;
......
......@@ -34,6 +34,7 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
......@@ -2267,6 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
return -EFAULT;
}
mutex_lock(&fi->state_mutex);
switch (fi->state) {
case opened:
retval = state_opened(fi, req);
......@@ -2281,6 +2284,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
break;
}
mutex_unlock(&fi->state_mutex);
if (retval < 0) {
free_pending_request(req);
} else {
......@@ -2541,109 +2546,120 @@ static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
{
struct file_info *fi = file->private_data;
int ret;
mutex_lock(&fi->state_mutex);
if (fi->iso_state == RAW1394_ISO_INACTIVE)
return -EINVAL;
ret = -EINVAL;
else
ret = dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
mutex_unlock(&fi->state_mutex);
return dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
return ret;
}
/* ioctl is only used for rawiso operations */
static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd,
void __user *argp)
{
switch (cmd) {
case RAW1394_IOC_ISO_XMIT_INIT:
return raw1394_iso_xmit_init(fi, argp);
case RAW1394_IOC_ISO_RECV_INIT:
return raw1394_iso_recv_init(fi, argp);
default:
return -EINVAL;
}
}
static long raw1394_ioctl_recv(struct file_info *fi, unsigned int cmd,
unsigned long arg)
{
struct file_info *fi = file->private_data;
void __user *argp = (void __user *)arg;
switch (fi->iso_state) {
case RAW1394_ISO_INACTIVE:
switch (cmd) {
case RAW1394_IOC_ISO_XMIT_INIT:
return raw1394_iso_xmit_init(fi, argp);
case RAW1394_IOC_ISO_RECV_INIT:
return raw1394_iso_recv_init(fi, argp);
default:
break;
switch (cmd) {
case RAW1394_IOC_ISO_RECV_START:{
int args[3];
if (copy_from_user(&args[0], argp, sizeof(args)))
return -EFAULT;
return hpsb_iso_recv_start(fi->iso_handle,
args[0], args[1], args[2]);
}
break;
case RAW1394_ISO_RECV:
switch (cmd) {
case RAW1394_IOC_ISO_RECV_START:{
/* copy args from user-space */
int args[3];
if (copy_from_user
(&args[0], argp, sizeof(args)))
return -EFAULT;
return hpsb_iso_recv_start(fi->iso_handle,
args[0], args[1],
args[2]);
}
case RAW1394_IOC_ISO_XMIT_RECV_STOP:
hpsb_iso_stop(fi->iso_handle);
return 0;
case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
return hpsb_iso_recv_listen_channel(fi->iso_handle,
arg);
case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
return hpsb_iso_recv_unlisten_channel(fi->iso_handle,
arg);
case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
/* copy the u64 from user-space */
u64 mask;
if (copy_from_user(&mask, argp, sizeof(mask)))
return -EFAULT;
return hpsb_iso_recv_set_channel_mask(fi->
iso_handle,
mask);
}
case RAW1394_IOC_ISO_GET_STATUS:
return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_RECV_PACKETS:
return raw1394_iso_recv_packets(fi, argp);
case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
return hpsb_iso_recv_release_packets(fi->iso_handle,
arg);
case RAW1394_IOC_ISO_RECV_FLUSH:
return hpsb_iso_recv_flush(fi->iso_handle);
case RAW1394_IOC_ISO_SHUTDOWN:
raw1394_iso_shutdown(fi);
return 0;
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
queue_rawiso_event(fi);
return 0;
case RAW1394_IOC_ISO_XMIT_RECV_STOP:
hpsb_iso_stop(fi->iso_handle);
return 0;
case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
return hpsb_iso_recv_listen_channel(fi->iso_handle, arg);
case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg);
case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
u64 mask;
if (copy_from_user(&mask, argp, sizeof(mask)))
return -EFAULT;
return hpsb_iso_recv_set_channel_mask(fi->iso_handle,
mask);
}
break;
case RAW1394_ISO_XMIT:
switch (cmd) {
case RAW1394_IOC_ISO_XMIT_START:{
/* copy two ints from user-space */
int args[2];
if (copy_from_user
(&args[0], argp, sizeof(args)))
return -EFAULT;
return hpsb_iso_xmit_start(fi->iso_handle,
args[0], args[1]);
}
case RAW1394_IOC_ISO_XMIT_SYNC:
return hpsb_iso_xmit_sync(fi->iso_handle);
case RAW1394_IOC_ISO_XMIT_RECV_STOP:
hpsb_iso_stop(fi->iso_handle);
return 0;
case RAW1394_IOC_ISO_GET_STATUS:
return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_XMIT_PACKETS:
return raw1394_iso_send_packets(fi, argp);
case RAW1394_IOC_ISO_SHUTDOWN:
raw1394_iso_shutdown(fi);
return 0;
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
queue_rawiso_event(fi);
return 0;
case RAW1394_IOC_ISO_GET_STATUS:
return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_RECV_PACKETS:
return raw1394_iso_recv_packets(fi, argp);
case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
case RAW1394_IOC_ISO_RECV_FLUSH:
return hpsb_iso_recv_flush(fi->iso_handle);
case RAW1394_IOC_ISO_SHUTDOWN:
raw1394_iso_shutdown(fi);
return 0;
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
queue_rawiso_event(fi);
return 0;
default:
return -EINVAL;
}
}
static long raw1394_ioctl_xmit(struct file_info *fi, unsigned int cmd,
void __user *argp)
{
switch (cmd) {
case RAW1394_IOC_ISO_XMIT_START:{
int args[2];
if (copy_from_user(&args[0], argp, sizeof(args)))
return -EFAULT;
return hpsb_iso_xmit_start(fi->iso_handle,
args[0], args[1]);
}
break;
case RAW1394_IOC_ISO_XMIT_SYNC:
return hpsb_iso_xmit_sync(fi->iso_handle);
case RAW1394_IOC_ISO_XMIT_RECV_STOP:
hpsb_iso_stop(fi->iso_handle);
return 0;
case RAW1394_IOC_ISO_GET_STATUS:
return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_XMIT_PACKETS:
return raw1394_iso_send_packets(fi, argp);
case RAW1394_IOC_ISO_SHUTDOWN:
raw1394_iso_shutdown(fi);
return 0;
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
queue_rawiso_event(fi);
return 0;
default:
break;
return -EINVAL;
}
}
/* ioctl is only used for rawiso operations */
static long raw1394_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct file_info *fi = file->private_data;
void __user *argp = (void __user *)arg;
long ret;
/* state-independent commands */
switch(cmd) {
......@@ -2653,16 +2669,25 @@ static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
break;
}
return -EINVAL;
}
mutex_lock(&fi->state_mutex);
switch (fi->iso_state) {
case RAW1394_ISO_INACTIVE:
ret = raw1394_ioctl_inactive(fi, cmd, argp);
break;
case RAW1394_ISO_RECV:
ret = raw1394_ioctl_recv(fi, cmd, arg);
break;
case RAW1394_ISO_XMIT:
ret = raw1394_ioctl_xmit(fi, cmd, argp);
break;
default:
ret = -EINVAL;
break;
}
mutex_unlock(&fi->state_mutex);
static long raw1394_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
long ret;
lock_kernel();
ret = do_raw1394_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
......@@ -2700,7 +2725,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
!copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
infos = compat_ptr(infos32);
if (!copy_to_user(&dst->infos, &infos, sizeof infos))
err = do_raw1394_ioctl(file, cmd, (unsigned long)dst);
err = raw1394_ioctl(file, cmd, (unsigned long)dst);
}
return err;
}
......@@ -2724,7 +2749,6 @@ static long raw1394_compat_ioctl(struct file *file,
void __user *argp = (void __user *)arg;
long err;
lock_kernel();
switch (cmd) {
/* These requests have same format as long as 'int' has same size. */
case RAW1394_IOC_ISO_RECV_INIT:
......@@ -2741,7 +2765,7 @@ static long raw1394_compat_ioctl(struct file *file,
case RAW1394_IOC_ISO_GET_STATUS:
case RAW1394_IOC_ISO_SHUTDOWN:
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
err = do_raw1394_ioctl(file, cmd, arg);
err = raw1394_ioctl(file, cmd, arg);
break;
/* These request have different format. */
case RAW1394_IOC_ISO_RECV_PACKETS32:
......@@ -2757,7 +2781,6 @@ static long raw1394_compat_ioctl(struct file *file,
err = -EINVAL;
break;
}
unlock_kernel();
return err;
}
......@@ -2791,6 +2814,7 @@ static int raw1394_open(struct inode *inode, struct file *file)
fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */
INIT_LIST_HEAD(&fi->list);
mutex_init(&fi->state_mutex);
fi->state = opened;
INIT_LIST_HEAD(&fi->req_pending);
INIT_LIST_HEAD(&fi->req_complete);
......
This diff is collapsed.
......@@ -139,13 +139,10 @@ struct sbp2_logout_orb {
u32 status_fifo_lo;
} __attribute__((packed));
#define PAGE_TABLE_SET_SEGMENT_BASE_HI(v) ((v) & 0xffff)
#define PAGE_TABLE_SET_SEGMENT_LENGTH(v) (((v) & 0xffff) << 16)
struct sbp2_unrestricted_page_table {
u32 length_segment_base_hi;
u32 segment_base_lo;
} __attribute__((packed));
__be32 high;
__be32 low;
};
#define RESP_STATUS_REQUEST_COMPLETE 0x0
#define RESP_STATUS_TRANSPORT_FAILURE 0x1
......@@ -216,15 +213,18 @@ struct sbp2_status_block {
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
#define SBP2_SW_VERSION_ENTRY 0x00010483
/*
* SCSI specific definitions
* The default maximum s/g segment size of a FireWire controller is
* usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
* be quadlet-aligned, we set the length limit to 0xffff & ~3.
*/
#define SBP2_MAX_SEG_SIZE 0xfffc
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
/* There is no real limitation of the queue depth (i.e. length of the linked
/*
* There is no real limitation of the queue depth (i.e. length of the linked
* list of command ORBs) at the target. The chosen depth is merely an
* implementation detail of the sbp2 driver. */
* implementation detail of the sbp2 driver.
*/
#define SBP2_MAX_CMDS 8
#define SBP2_SCSI_STATUS_GOOD 0x0
......@@ -240,12 +240,6 @@ struct sbp2_status_block {
* Representations of commands and devices
*/
enum sbp2_dma_types {
CMD_DMA_NONE,
CMD_DMA_PAGE,
CMD_DMA_SINGLE
};
/* Per SCSI command */
struct sbp2_command_info {
struct list_head list;
......@@ -258,11 +252,6 @@ struct sbp2_command_info {
struct sbp2_unrestricted_page_table
scatter_gather_element[SG_ALL] __attribute__((aligned(8)));
dma_addr_t sge_dma;
void *sge_buffer;
dma_addr_t cmd_dma;
enum sbp2_dma_types dma_type;
unsigned long dma_size;
enum dma_data_direction dma_dir;
};
/* Per FireWire host */
......
......@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file *file,
if (unlikely(d == NULL))
return -EFAULT;
if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
if (unlikely(v.buffer >= d->num_desc - 1)) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
......@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file *file,
if (unlikely(d == NULL))
return -EFAULT;
if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
if (unlikely(v.buffer > d->num_desc - 1)) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
......@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file *file,
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
if (d == NULL) return -EFAULT;
if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
if (v.buffer >= d->num_desc - 1) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
......@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file *file,
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
if (d == NULL) return -EFAULT;
if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
if (v.buffer >= d->num_desc - 1) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
......
......@@ -154,8 +154,13 @@ struct fw_cdev_event_iso_interrupt {
* @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST
* @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT
*
* Convenience union for userspace use. Events could be read(2) into a char
* buffer and then cast to this union for further processing.
* Convenience union for userspace use. Events could be read(2) into an
* appropriately aligned char buffer and then cast to this union for further
* processing. Note that for a request, response or iso_interrupt event,
* the data[] or header[] may make the size of the full event larger than
* sizeof(union fw_cdev_event). Also note that if you attempt to read(2)
* an event into a buffer that is not large enough for it, the data that does
* not fit will be discarded so that the next read(2) will return a new event.
*/
union fw_cdev_event {
struct fw_cdev_event_common common;
......
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