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: (55 commits)
  ieee1394: sbp2: code formatting around work_struct stuff
  ieee1394: nodemgr: remove a kcalloc
  ieee1394: conditionally export ieee1394_bus_type
  ieee1394: Consolidate driver registering
  ieee1394: sbp2: convert from PCI DMA to generic DMA
  ieee1394: nodemgr: spaces to tabs
  ieee1394: nodemgr: fix deadlock in shutdown
  ieee1394: nodemgr: remove duplicate assignment
  sbp2: make 1bit bitfield unsigned
  ieee1394: schedule *_oui sysfs attributes for removal
  ieee1394: schedule unused symbol exports for removal
  ieee1394: dv1394: schedule for feature removal
  ieee1394: raw1394: defer feature removal of old isoch interface
  ieee1394: ohci1394: call PMac code in shutdown only for proper machines
  ieee1394: ohci1394: reformat PPC_PMAC platform code
  ieee1394: ohci1394: add PPC_PMAC platform code to driver probe
  ieee1394: sbp2: wrap two functions into one
  ieee1394: sbp2: update comment on things to do
  ieee1394: sbp2: use list_move_tail()
  ieee1394: sbp2: more concise names for types and variables
  ...
This commit is contained in:
Linus Torvalds 2006-12-07 16:18:46 -08:00
commit c99767974e
18 changed files with 1448 additions and 1914 deletions

View File

@ -30,11 +30,39 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
When: November 2006
Why: Deprecated in favour of the new ioctl-based rawiso interface, which is
more efficient. You should really be using libraw1394 for raw1394
access anyway.
Who: Jody McIntyre <scjody@modernduck.com>
When: June 2007
Why: Deprecated in favour of the more efficient and robust rawiso interface.
Affected are applications which use the deprecated part of libraw1394
(raw1394_iso_write, raw1394_start_iso_write, raw1394_start_iso_rcv,
raw1394_stop_iso_rcv) or bypass libraw1394.
Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: dv1394 driver (CONFIG_IEEE1394_DV1394)
When: June 2007
Why: Replaced by raw1394 + userspace libraries, notably libiec61883. This
shift of application support has been indicated on www.linux1394.org
and developers' mailinglists for quite some time. Major applications
have been converted, with the exception of ffmpeg and hence xine.
Piped output of dvgrab2 is a partial equivalent to dv1394.
Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: ieee1394 core's unused exports (CONFIG_IEEE1394_EXPORT_FULL_API)
When: January 2007
Why: There are no projects known to use these exported symbols, except
dfg1394 (uses one symbol whose functionality is core-internal now).
Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
What: ieee1394's *_oui sysfs attributes (CONFIG_IEEE1394_OUI_DB)
When: January 2007
Files: drivers/ieee1394/: oui.db, oui2c.sh
Why: big size, little value
Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------

View File

@ -36,7 +36,7 @@ config IEEE1394_VERBOSEDEBUG
else says N.
config IEEE1394_OUI_DB
bool "OUI Database built-in"
bool "OUI Database built-in (deprecated)"
depends on IEEE1394
help
If you say Y here, then an OUI list (vendor unique ID's) will be
@ -67,16 +67,11 @@ config IEEE1394_CONFIG_ROM_IP1394
eth1394 option below.
config IEEE1394_EXPORT_FULL_API
bool "Export all symbols of ieee1394's API"
bool "Export all symbols of ieee1394's API (deprecated)"
depends on IEEE1394
default n
help
Export all symbols of ieee1394's driver programming interface, even
those that are not currently used by the standard IEEE 1394 drivers.
This option does not affect the interface to userspace applications.
Say Y here if you want to compile externally developed drivers that
make extended use of ieee1394's API. It is otherwise safe to say N.
This option will be removed soon. Don't worry, say N.
comment "Device Drivers"
depends on IEEE1394
@ -125,7 +120,7 @@ comment "SBP-2 support (for storage devices) requires SCSI"
config IEEE1394_SBP2
tristate "SBP-2 support (Harddisks etc.)"
depends on IEEE1394 && SCSI && (PCI || BROKEN)
depends on IEEE1394 && SCSI
help
This option enables you to use SBP-2 devices connected to an IEEE
1394 bus. SBP-2 devices include storage devices like harddisks and
@ -161,17 +156,12 @@ config IEEE1394_ETH1394
MCAP, therefore multicast support is significantly limited.
config IEEE1394_DV1394
tristate "OHCI-DV I/O support"
tristate "OHCI-DV I/O support (deprecated)"
depends on IEEE1394 && IEEE1394_OHCI1394
help
This driver allows you to transmit and receive DV (digital video)
streams on an OHCI-1394 card using a simple frame-oriented
interface.
The user-space API for dv1394 is documented in dv1394.h.
To compile this driver as a module, say M here: the
module will be called dv1394.
The dv1394 driver will be removed from Linux in a future release.
Its functionality is now provided by raw1394 together with libraries
such as libiec61883.
config IEEE1394_RAWIO
tristate "Raw IEEE1394 I/O support"

View File

@ -3,8 +3,11 @@
#
ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
highlevel.o csr.o nodemgr.o oui.o dma.o iso.o \
highlevel.o csr.o nodemgr.o dma.o iso.o \
csr1212.o config_roms.o
ifdef CONFIG_IEEE1394_OUI_DB
ieee1394-objs += oui.o
endif
obj-$(CONFIG_IEEE1394) += ieee1394.o
obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o

View File

@ -158,12 +158,10 @@ static void host_reset(struct hpsb_host *host)
*/
static inline void calculate_expire(struct csr_control *csr)
{
unsigned long usecs =
(csr->split_timeout_hi & 0x07) * USEC_PER_SEC +
(csr->split_timeout_lo >> 19) * 125L;
csr->expire = usecs_to_jiffies(usecs > 100000L ? usecs : 100000L);
unsigned int usecs = (csr->split_timeout_hi & 7) * 1000000 +
(csr->split_timeout_lo >> 19) * 125;
csr->expire = usecs_to_jiffies(usecs > 100000 ? usecs : 100000);
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
}

View File

@ -1536,27 +1536,20 @@ static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count
static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct video_card *video;
struct video_card *video = file_to_video_card(file);
unsigned long flags;
int ret = -EINVAL;
void __user *argp = (void __user *)arg;
DECLARE_WAITQUEUE(wait, current);
lock_kernel();
video = file_to_video_card(file);
/* serialize this to prevent multi-threaded mayhem */
if (file->f_flags & O_NONBLOCK) {
if (!mutex_trylock(&video->mtx)) {
unlock_kernel();
if (!mutex_trylock(&video->mtx))
return -EAGAIN;
}
} else {
if (mutex_lock_interruptible(&video->mtx)) {
unlock_kernel();
if (mutex_lock_interruptible(&video->mtx))
return -ERESTARTSYS;
}
}
switch(cmd)
@ -1780,7 +1773,6 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
out:
mutex_unlock(&video->mtx);
unlock_kernel();
return ret;
}
@ -2188,12 +2180,8 @@ static struct ieee1394_device_id dv1394_id_table[] = {
MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
static struct hpsb_protocol_driver dv1394_driver = {
.name = "DV/1394 Driver",
.name = "dv1394",
.id_table = dv1394_id_table,
.driver = {
.name = "dv1394",
.bus = &ieee1394_bus_type,
},
};
@ -2587,6 +2575,10 @@ static int __init dv1394_init_module(void)
{
int ret;
printk(KERN_WARNING
"WARNING: The dv1394 driver is unsupported and will be removed "
"from Linux soon. Use raw1394 instead.\n");
cdev_init(&dv1394_cdev, &dv1394_fops);
dv1394_cdev.owner = THIS_MODULE;
kobject_set_name(&dv1394_cdev.kobj, "dv1394");

View File

@ -474,12 +474,10 @@ static struct ieee1394_device_id eth1394_id_table[] = {
MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
static struct hpsb_protocol_driver eth1394_proto_driver = {
.name = "IPv4 over 1394 Driver",
.name = ETH1394_DRIVER_NAME,
.id_table = eth1394_id_table,
.update = eth1394_update,
.driver = {
.name = ETH1394_DRIVER_NAME,
.bus = &ieee1394_bus_type,
.probe = eth1394_probe,
.remove = eth1394_remove,
},

View File

@ -24,7 +24,6 @@ struct hpsb_address_serve {
/* Only the following structures are of interest to actual highlevel drivers. */
struct hpsb_highlevel {
struct module *owner;
const char *name;
/* Any of the following pointers can legally be NULL, except for

View File

@ -44,9 +44,10 @@ static void delayed_reset_bus(struct work_struct *work)
CSR_SET_BUS_INFO_GENERATION(host->csr.rom, generation);
if (csr1212_generate_csr_image(host->csr.rom) != CSR1212_SUCCESS) {
/* CSR image creation failed, reset generation field and do not
* issue a bus reset. */
CSR_SET_BUS_INFO_GENERATION(host->csr.rom, host->csr.generation);
/* CSR image creation failed.
* Reset generation field and do not issue a bus reset. */
CSR_SET_BUS_INFO_GENERATION(host->csr.rom,
host->csr.generation);
return;
}
@ -54,7 +55,8 @@ static void delayed_reset_bus(struct work_struct *work)
host->update_config_rom = 0;
if (host->driver->set_hw_config_rom)
host->driver->set_hw_config_rom(host, host->csr.rom->bus_info_data);
host->driver->set_hw_config_rom(host,
host->csr.rom->bus_info_data);
host->csr.gen_timestamp[host->csr.generation] = jiffies;
hpsb_reset_bus(host, SHORT_RESET);
@ -70,7 +72,8 @@ static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
return -1;
}
static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg)
static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command,
unsigned long arg)
{
return -1;
}
@ -128,10 +131,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
return NULL;
h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h);
if (!h->csr.rom) {
kfree(h);
return NULL;
}
if (!h->csr.rom)
goto fail;
h->hostdata = h + 1;
h->driver = drv;
@ -151,16 +152,15 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
init_timer(&h->timeout);
h->timeout.data = (unsigned long) h;
h->timeout.function = abort_timedouts;
h->timeout_interval = HZ / 20; // 50ms by default
h->timeout_interval = HZ / 20; /* 50ms, half of minimum SPLIT_TIMEOUT */
h->topology_map = h->csr.topology_map + 3;
h->speed_map = (u8 *)(h->csr.speed_map + 2);
mutex_lock(&host_num_alloc);
while (nodemgr_for_each_host(&hostnum, alloc_hostnum_cb))
hostnum++;
mutex_unlock(&host_num_alloc);
h->id = hostnum;
memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
@ -171,13 +171,19 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
h->class_dev.class = &hpsb_host_class;
snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id);
device_register(&h->device);
class_device_register(&h->class_dev);
if (device_register(&h->device))
goto fail;
if (class_device_register(&h->class_dev)) {
device_unregister(&h->device);
goto fail;
}
get_device(&h->device);
mutex_unlock(&host_num_alloc);
return h;
fail:
kfree(h);
return NULL;
}
int hpsb_add_host(struct hpsb_host *host)
@ -229,7 +235,8 @@ int hpsb_update_config_rom_image(struct hpsb_host *host)
if (time_before(jiffies, host->csr.gen_timestamp[next_gen] + 60 * HZ))
/* Wait 60 seconds from the last time this generation number was
* used. */
reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
reset_delay =
(60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
else
/* Wait 1 second in case some other code wants to change the
* Config ROM in the near future. */

View File

@ -1237,10 +1237,10 @@ EXPORT_SYMBOL(highlevel_remove_host);
/** nodemgr.c **/
EXPORT_SYMBOL(hpsb_node_fill_packet);
EXPORT_SYMBOL(hpsb_node_write);
EXPORT_SYMBOL(hpsb_register_protocol);
EXPORT_SYMBOL(__hpsb_register_protocol);
EXPORT_SYMBOL(hpsb_unregister_protocol);
EXPORT_SYMBOL(ieee1394_bus_type);
#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
EXPORT_SYMBOL(ieee1394_bus_type);
EXPORT_SYMBOL(nodemgr_for_each_host);
#endif

View File

@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/freezer.h>
#include <asm/atomic.h>
@ -67,7 +68,7 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
{
quadlet_t q;
u8 i, *speed, old_speed, good_speed;
int ret;
int error;
speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
old_speed = *speed;
@ -79,9 +80,9 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
* just finished its initialization. */
for (i = IEEE1394_SPEED_100; i <= old_speed; i++) {
*speed = i;
ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
&q, sizeof(quadlet_t));
if (ret)
error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
&q, sizeof(quadlet_t));
if (error)
break;
*buffer = q;
good_speed = i;
@ -95,19 +96,19 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
return 0;
}
*speed = old_speed;
return ret;
return error;
}
static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
void *buffer, void *__ci)
void *buffer, void *__ci)
{
struct nodemgr_csr_info *ci = (struct nodemgr_csr_info*)__ci;
int i, ret;
int i, error;
for (i = 1; ; i++) {
ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
buffer, length);
if (!ret) {
error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
buffer, length);
if (!error) {
ci->speed_unverified = 0;
break;
}
@ -118,14 +119,14 @@ static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
/* The ieee1394_core guessed the node's speed capability from
* the self ID. Check whether a lower speed works. */
if (ci->speed_unverified && length == sizeof(quadlet_t)) {
ret = nodemgr_check_speed(ci, addr, buffer);
if (!ret)
error = nodemgr_check_speed(ci, addr, buffer);
if (!error)
break;
}
if (msleep_interruptible(334))
return -EINTR;
}
return ret;
return error;
}
static int nodemgr_get_max_rom(quadlet_t *bus_info_data, void *__ci)
@ -260,9 +261,20 @@ static struct device nodemgr_dev_template_ne = {
.release = nodemgr_release_ne,
};
/* This dummy driver prevents the host devices from being scanned. We have no
* useful drivers for them yet, and there would be a deadlock possible if the
* driver core scans the host device while the host's low-level driver (i.e.
* the host's parent device) is being removed. */
static struct device_driver nodemgr_mid_layer_driver = {
.bus = &ieee1394_bus_type,
.name = "nodemgr",
.owner = THIS_MODULE,
};
struct device nodemgr_dev_template_host = {
.bus = &ieee1394_bus_type,
.release = nodemgr_release_host,
.driver = &nodemgr_mid_layer_driver,
};
@ -307,8 +319,8 @@ static ssize_t fw_drv_show_##field (struct device_driver *drv, char *buf) \
return sprintf(buf, format_string, (type)driver->field);\
} \
static struct driver_attribute driver_attr_drv_##field = { \
.attr = {.name = __stringify(field), .mode = S_IRUGO }, \
.show = fw_drv_show_##field, \
.attr = {.name = __stringify(field), .mode = S_IRUGO }, \
.show = fw_drv_show_##field, \
};
@ -362,7 +374,7 @@ static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
#endif
spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
return sprintf(buf, "0x%016llx\n", tm);
return sprintf(buf, "0x%016llx\n", (unsigned long long)tm);
}
static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
#endif /* HPSB_DEBUG_TLABELS */
@ -374,11 +386,11 @@ static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute
int state = simple_strtoul(buf, NULL, 10);
if (state == 1) {
down_write(&dev->bus->subsys.rwsem);
device_release_driver(dev);
ud->ignore_driver = 1;
up_write(&dev->bus->subsys.rwsem);
} else if (!state)
down_write(&ieee1394_bus_type.subsys.rwsem);
device_release_driver(dev);
up_write(&ieee1394_bus_type.subsys.rwsem);
} else if (state == 0)
ud->ignore_driver = 0;
return count;
@ -413,11 +425,14 @@ static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count)
static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf,
size_t count)
{
int error = 0;
if (simple_strtoul(buf, NULL, 10) == 1)
bus_rescan_devices(&ieee1394_bus_type);
return count;
error = bus_rescan_devices(&ieee1394_bus_type);
return error ? error : count;
}
static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
{
@ -433,7 +448,7 @@ static ssize_t fw_set_ignore_drivers(struct bus_type *bus, const char *buf, size
if (state == 1)
ignore_drivers = 1;
else if (!state)
else if (state == 0)
ignore_drivers = 0;
return count;
@ -526,7 +541,7 @@ static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
int length = 0;
char *scratch = buf;
driver = container_of(drv, struct hpsb_protocol_driver, driver);
driver = container_of(drv, struct hpsb_protocol_driver, driver);
for (id = driver->id_table; id->match_flags != 0; id++) {
int need_coma = 0;
@ -583,7 +598,11 @@ static void nodemgr_create_drv_files(struct hpsb_protocol_driver *driver)
int i;
for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++)
driver_create_file(drv, fw_drv_attrs[i]);
if (driver_create_file(drv, fw_drv_attrs[i]))
goto fail;
return;
fail:
HPSB_ERR("Failed to add sysfs attribute for driver %s", driver->name);
}
@ -603,7 +622,12 @@ static void nodemgr_create_ne_dev_files(struct node_entry *ne)
int i;
for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++)
device_create_file(dev, fw_ne_attrs[i]);
if (device_create_file(dev, fw_ne_attrs[i]))
goto fail;
return;
fail:
HPSB_ERR("Failed to add sysfs attribute for node %016Lx",
(unsigned long long)ne->guid);
}
@ -613,11 +637,16 @@ static void nodemgr_create_host_dev_files(struct hpsb_host *host)
int i;
for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++)
device_create_file(dev, fw_host_attrs[i]);
if (device_create_file(dev, fw_host_attrs[i]))
goto fail;
return;
fail:
HPSB_ERR("Failed to add sysfs attribute for host %d", host->id);
}
static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid);
static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
nodeid_t nodeid);
static void nodemgr_update_host_dev_links(struct hpsb_host *host)
{
@ -628,12 +657,18 @@ static void nodemgr_update_host_dev_links(struct hpsb_host *host)
sysfs_remove_link(&dev->kobj, "busmgr_id");
sysfs_remove_link(&dev->kobj, "host_id");
if ((ne = find_entry_by_nodeid(host, host->irm_id)))
sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id");
if ((ne = find_entry_by_nodeid(host, host->busmgr_id)))
sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id");
if ((ne = find_entry_by_nodeid(host, host->node_id)))
sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id");
if ((ne = find_entry_by_nodeid(host, host->irm_id)) &&
sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id"))
goto fail;
if ((ne = find_entry_by_nodeid(host, host->busmgr_id)) &&
sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id"))
goto fail;
if ((ne = find_entry_by_nodeid(host, host->node_id)) &&
sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id"))
goto fail;
return;
fail:
HPSB_ERR("Failed to update sysfs attributes for host %d", host->id);
}
static void nodemgr_create_ud_dev_files(struct unit_directory *ud)
@ -642,32 +677,39 @@ static void nodemgr_create_ud_dev_files(struct unit_directory *ud)
int i;
for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++)
device_create_file(dev, fw_ud_attrs[i]);
if (device_create_file(dev, fw_ud_attrs[i]))
goto fail;
if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
device_create_file(dev, &dev_attr_ud_specifier_id);
if (device_create_file(dev, &dev_attr_ud_specifier_id))
goto fail;
if (ud->flags & UNIT_DIRECTORY_VERSION)
device_create_file(dev, &dev_attr_ud_version);
if (device_create_file(dev, &dev_attr_ud_version))
goto fail;
if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) {
device_create_file(dev, &dev_attr_ud_vendor_id);
if (ud->vendor_name_kv)
device_create_file(dev, &dev_attr_ud_vendor_name_kv);
if (device_create_file(dev, &dev_attr_ud_vendor_id))
goto fail;
if (ud->vendor_name_kv &&
device_create_file(dev, &dev_attr_ud_vendor_name_kv))
goto fail;
}
if (ud->flags & UNIT_DIRECTORY_MODEL_ID) {
device_create_file(dev, &dev_attr_ud_model_id);
if (ud->model_name_kv)
device_create_file(dev, &dev_attr_ud_model_name_kv);
if (device_create_file(dev, &dev_attr_ud_model_id))
goto fail;
if (ud->model_name_kv &&
device_create_file(dev, &dev_attr_ud_model_name_kv))
goto fail;
}
return;
fail:
HPSB_ERR("Failed to add sysfs attributes for unit %s",
ud->device.bus_id);
}
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
{
struct hpsb_protocol_driver *driver;
struct unit_directory *ud;
struct hpsb_protocol_driver *driver;
struct unit_directory *ud;
struct ieee1394_device_id *id;
/* We only match unit directories */
@ -675,55 +717,77 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
return 0;
ud = container_of(dev, struct unit_directory, device);
driver = container_of(drv, struct hpsb_protocol_driver, driver);
if (ud->ne->in_limbo || ud->ignore_driver)
return 0;
for (id = driver->id_table; id->match_flags != 0; id++) {
if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
id->vendor_id != ud->vendor_id)
continue;
/* We only match drivers of type hpsb_protocol_driver */
if (drv == &nodemgr_mid_layer_driver)
return 0;
if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
id->model_id != ud->model_id)
continue;
driver = container_of(drv, struct hpsb_protocol_driver, driver);
for (id = driver->id_table; id->match_flags != 0; id++) {
if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
id->vendor_id != ud->vendor_id)
continue;
if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
id->specifier_id != ud->specifier_id)
continue;
if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
id->model_id != ud->model_id)
continue;
if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
id->version != ud->version)
continue;
if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
id->specifier_id != ud->specifier_id)
continue;
if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
id->version != ud->version)
continue;
return 1;
}
}
return 0;
}
static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
static void nodemgr_remove_uds(struct node_entry *ne)
{
struct class_device *cdev, *next;
struct unit_directory *ud;
list_for_each_entry_safe(cdev, next, &nodemgr_ud_class.children, node) {
ud = container_of(cdev, struct unit_directory, class_dev);
if (ud->ne != ne)
continue;
struct class_device *cdev;
struct unit_directory *tmp, *ud;
/* Iteration over nodemgr_ud_class.children has to be protected by
* nodemgr_ud_class.sem, but class_device_unregister() will eventually
* take nodemgr_ud_class.sem too. Therefore pick out one ud at a time,
* release the semaphore, and then unregister the ud. Since this code
* may be called from other contexts besides the knodemgrds, protect the
* gap after release of the semaphore by nodemgr_serialize_remove_uds.
*/
mutex_lock(&nodemgr_serialize_remove_uds);
for (;;) {
ud = NULL;
down(&nodemgr_ud_class.sem);
list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
tmp = container_of(cdev, struct unit_directory,
class_dev);
if (tmp->ne == ne) {
ud = tmp;
break;
}
}
up(&nodemgr_ud_class.sem);
if (ud == NULL)
break;
class_device_unregister(&ud->class_dev);
device_unregister(&ud->device);
}
mutex_unlock(&nodemgr_serialize_remove_uds);
}
static void nodemgr_remove_ne(struct node_entry *ne)
{
struct device *dev = &ne->device;
struct device *dev;
dev = get_device(&ne->device);
if (!dev)
@ -748,7 +812,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data)
static void nodemgr_remove_host_dev(struct device *dev)
{
device_for_each_child(dev, NULL, __nodemgr_remove_host_dev);
WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev));
sysfs_remove_link(&dev->kobj, "irm_id");
sysfs_remove_link(&dev->kobj, "busmgr_id");
sysfs_remove_link(&dev->kobj, "host_id");
@ -762,16 +826,16 @@ static void nodemgr_update_bus_options(struct node_entry *ne)
#endif
quadlet_t busoptions = be32_to_cpu(ne->csr->bus_info_data[2]);
ne->busopt.irmc = (busoptions >> 31) & 1;
ne->busopt.cmc = (busoptions >> 30) & 1;
ne->busopt.isc = (busoptions >> 29) & 1;
ne->busopt.bmc = (busoptions >> 28) & 1;
ne->busopt.pmc = (busoptions >> 27) & 1;
ne->busopt.cyc_clk_acc = (busoptions >> 16) & 0xff;
ne->busopt.max_rec = 1 << (((busoptions >> 12) & 0xf) + 1);
ne->busopt.irmc = (busoptions >> 31) & 1;
ne->busopt.cmc = (busoptions >> 30) & 1;
ne->busopt.isc = (busoptions >> 29) & 1;
ne->busopt.bmc = (busoptions >> 28) & 1;
ne->busopt.pmc = (busoptions >> 27) & 1;
ne->busopt.cyc_clk_acc = (busoptions >> 16) & 0xff;
ne->busopt.max_rec = 1 << (((busoptions >> 12) & 0xf) + 1);
ne->busopt.max_rom = (busoptions >> 8) & 0x3;
ne->busopt.generation = (busoptions >> 4) & 0xf;
ne->busopt.lnkspd = busoptions & 0x7;
ne->busopt.generation = (busoptions >> 4) & 0xf;
ne->busopt.lnkspd = busoptions & 0x7;
HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
"cyc_clk_acc=%d max_rec=%d max_rom=%d gen=%d lspd=%d",
@ -792,7 +856,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
ne = kzalloc(sizeof(*ne), GFP_KERNEL);
if (!ne)
return NULL;
goto fail_alloc;
ne->host = host;
ne->nodeid = nodeid;
@ -815,12 +879,15 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx",
(unsigned long long)(ne->guid));
device_register(&ne->device);
class_device_register(&ne->class_dev);
if (device_register(&ne->device))
goto fail_devreg;
if (class_device_register(&ne->class_dev))
goto fail_classdevreg;
get_device(&ne->device);
if (ne->guid_vendor_oui)
device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui);
if (ne->guid_vendor_oui &&
device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui))
goto fail_addoiu;
nodemgr_create_ne_dev_files(ne);
nodemgr_update_bus_options(ne);
@ -830,17 +897,28 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
return ne;
fail_addoiu:
put_device(&ne->device);
fail_classdevreg:
device_unregister(&ne->device);
fail_devreg:
kfree(ne);
fail_alloc:
HPSB_ERR("Failed to create node ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
return NULL;
}
static struct node_entry *find_entry_by_guid(u64 guid)
{
struct class *class = &nodemgr_ne_class;
struct class_device *cdev;
struct node_entry *ne, *ret_ne = NULL;
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
down(&nodemgr_ne_class.sem);
list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
ne = container_of(cdev, struct node_entry, class_dev);
if (ne->guid == guid) {
@ -848,20 +926,20 @@ static struct node_entry *find_entry_by_guid(u64 guid)
break;
}
}
up_read(&class->subsys.rwsem);
up(&nodemgr_ne_class.sem);
return ret_ne;
return ret_ne;
}
static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid)
static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
nodeid_t nodeid)
{
struct class *class = &nodemgr_ne_class;
struct class_device *cdev;
struct node_entry *ne, *ret_ne = NULL;
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
down(&nodemgr_ne_class.sem);
list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
ne = container_of(cdev, struct node_entry, class_dev);
if (ne->host == host && ne->nodeid == nodeid) {
@ -869,7 +947,7 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t
break;
}
}
up_read(&class->subsys.rwsem);
up(&nodemgr_ne_class.sem);
return ret_ne;
}
@ -891,13 +969,25 @@ static void nodemgr_register_device(struct node_entry *ne,
snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
device_register(&ud->device);
class_device_register(&ud->class_dev);
if (device_register(&ud->device))
goto fail_devreg;
if (class_device_register(&ud->class_dev))
goto fail_classdevreg;
get_device(&ud->device);
if (ud->vendor_oui)
device_create_file(&ud->device, &dev_attr_ud_vendor_oui);
if (ud->vendor_oui &&
device_create_file(&ud->device, &dev_attr_ud_vendor_oui))
goto fail_addoui;
nodemgr_create_ud_dev_files(ud);
return;
fail_addoui:
put_device(&ud->device);
fail_classdevreg:
device_unregister(&ud->device);
fail_devreg:
HPSB_ERR("Failed to create unit %s", ud->device.bus_id);
}
@ -977,10 +1067,9 @@ static struct unit_directory *nodemgr_process_unit_directory
/* Logical Unit Number */
if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
ud_child = kmalloc(sizeof(*ud_child), GFP_KERNEL);
ud_child = kmemdup(ud, sizeof(*ud_child), GFP_KERNEL);
if (!ud_child)
goto unit_directory_error;
memcpy(ud_child, ud, sizeof(*ud_child));
nodemgr_register_device(ne, ud_child, &ne->device);
ud_child = NULL;
@ -1094,10 +1183,16 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
last_key_id = kv->key.id;
}
if (ne->vendor_oui)
device_create_file(&ne->device, &dev_attr_ne_vendor_oui);
if (ne->vendor_name_kv)
device_create_file(&ne->device, &dev_attr_ne_vendor_name_kv);
if (ne->vendor_oui &&
device_create_file(&ne->device, &dev_attr_ne_vendor_oui))
goto fail;
if (ne->vendor_name_kv &&
device_create_file(&ne->device, &dev_attr_ne_vendor_name_kv))
goto fail;
return;
fail:
HPSB_ERR("Failed to add sysfs attribute for node %016Lx",
(unsigned long long)ne->guid);
}
#ifdef CONFIG_HOTPLUG
@ -1161,16 +1256,20 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
#endif /* CONFIG_HOTPLUG */
int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
int __hpsb_register_protocol(struct hpsb_protocol_driver *drv,
struct module *owner)
{
int ret;
int error;
drv->driver.bus = &ieee1394_bus_type;
drv->driver.owner = owner;
drv->driver.name = drv->name;
/* This will cause a probe for devices */
ret = driver_register(&driver->driver);
if (!ret)
nodemgr_create_drv_files(driver);
return ret;
error = driver_register(&drv->driver);
if (!error)
nodemgr_create_drv_files(drv);
return error;
}
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
@ -1298,26 +1397,25 @@ static void nodemgr_node_scan_one(struct host_info *hi,
static void nodemgr_node_scan(struct host_info *hi, int generation)
{
int count;
struct hpsb_host *host = hi->host;
struct selfid *sid = (struct selfid *)host->topology_map;
nodeid_t nodeid = LOCAL_BUS;
int count;
struct hpsb_host *host = hi->host;
struct selfid *sid = (struct selfid *)host->topology_map;
nodeid_t nodeid = LOCAL_BUS;
/* Scan each node on the bus */
for (count = host->selfid_count; count; count--, sid++) {
if (sid->extended)
continue;
/* Scan each node on the bus */
for (count = host->selfid_count; count; count--, sid++) {
if (sid->extended)
continue;
if (!sid->link_active) {
nodeid++;
continue;
}
nodemgr_node_scan_one(hi, nodeid++, generation);
}
if (!sid->link_active) {
nodeid++;
continue;
}
nodemgr_node_scan_one(hi, nodeid++, generation);
}
}
/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
static void nodemgr_suspend_ne(struct node_entry *ne)
{
struct class_device *cdev;
@ -1327,21 +1425,22 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
ne->in_limbo = 1;
device_create_file(&ne->device, &dev_attr_ne_in_limbo);
WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
down_write(&ne->device.bus->subsys.rwsem);
down(&nodemgr_ud_class.sem);
list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
ud = container_of(cdev, struct unit_directory, class_dev);
if (ud->ne != ne)
continue;
down_write(&ieee1394_bus_type.subsys.rwsem);
if (ud->device.driver &&
(!ud->device.driver->suspend ||
ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
device_release_driver(&ud->device);
up_write(&ieee1394_bus_type.subsys.rwsem);
}
up_write(&ne->device.bus->subsys.rwsem);
up(&nodemgr_ud_class.sem);
}
@ -1353,45 +1452,47 @@ static void nodemgr_resume_ne(struct node_entry *ne)
ne->in_limbo = 0;
device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
down_read(&nodemgr_ud_class.subsys.rwsem);
down_read(&ne->device.bus->subsys.rwsem);
down(&nodemgr_ud_class.sem);
list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
ud = container_of(cdev, struct unit_directory, class_dev);
if (ud->ne != ne)
continue;
down_read(&ieee1394_bus_type.subsys.rwsem);
if (ud->device.driver && ud->device.driver->resume)
ud->device.driver->resume(&ud->device);
up_read(&ieee1394_bus_type.subsys.rwsem);
}
up_read(&ne->device.bus->subsys.rwsem);
up_read(&nodemgr_ud_class.subsys.rwsem);
up(&nodemgr_ud_class.sem);
HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
}
/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
static void nodemgr_update_pdrv(struct node_entry *ne)
{
struct unit_directory *ud;
struct hpsb_protocol_driver *pdrv;
struct class_device *cdev;
down(&nodemgr_ud_class.sem);
list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
ud = container_of(cdev, struct unit_directory, class_dev);
if (ud->ne != ne || !ud->device.driver)
if (ud->ne != ne)
continue;
pdrv = container_of(ud->device.driver, struct hpsb_protocol_driver, driver);
if (pdrv->update && pdrv->update(ud)) {
down_write(&ud->device.bus->subsys.rwsem);
device_release_driver(&ud->device);
up_write(&ud->device.bus->subsys.rwsem);
down_write(&ieee1394_bus_type.subsys.rwsem);
if (ud->device.driver) {
pdrv = container_of(ud->device.driver,
struct hpsb_protocol_driver,
driver);
if (pdrv->update && pdrv->update(ud))
device_release_driver(&ud->device);
}
up_write(&ieee1394_bus_type.subsys.rwsem);
}
up(&nodemgr_ud_class.sem);
}
@ -1405,7 +1506,7 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
{
const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
quadlet_t bc_remote, bc_local;
int ret;
int error;
if (!ne->host->is_irm || ne->generation != generation ||
ne->nodeid == ne->host->node_id)
@ -1414,16 +1515,14 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
/* Check if the register is implemented and 1394a compliant. */
ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
sizeof(bc_remote));
if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
error = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
sizeof(bc_remote));
if (!error && bc_remote & cpu_to_be32(0x80000000) &&
bc_remote != bc_local)
hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
}
/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader because the
* calls to nodemgr_update_pdrv() and nodemgr_suspend_ne() here require it. */
static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
{
struct device *dev;
@ -1456,7 +1555,6 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
static void nodemgr_node_probe(struct host_info *hi, int generation)
{
struct hpsb_host *host = hi->host;
struct class *class = &nodemgr_ne_class;
struct class_device *cdev;
struct node_entry *ne;
@ -1469,18 +1567,18 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
* while probes are time-consuming. (Well, those probes need some
* improvement...) */
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
down(&nodemgr_ne_class.sem);
list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
ne = container_of(cdev, struct node_entry, class_dev);
if (!ne->needs_probe)
nodemgr_probe_ne(hi, ne, generation);
}
list_for_each_entry(cdev, &class->children, node) {
list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
ne = container_of(cdev, struct node_entry, class_dev);
if (ne->needs_probe)
nodemgr_probe_ne(hi, ne, generation);
}
up_read(&class->subsys.rwsem);
up(&nodemgr_ne_class.sem);
/* If we had a bus reset while we were scanning the bus, it is
@ -1498,15 +1596,14 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
* just removed. */
if (generation == get_hpsb_generation(host))
bus_rescan_devices(&ieee1394_bus_type);
return;
if (bus_rescan_devices(&ieee1394_bus_type))
HPSB_DEBUG("bus_rescan_devices had an error");
}
static int nodemgr_send_resume_packet(struct hpsb_host *host)
{
struct hpsb_packet *packet;
int ret = 1;
int error = -ENOMEM;
packet = hpsb_make_phypacket(host,
EXTPHYPACKET_TYPE_RESUME |
@ -1514,12 +1611,12 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host)
if (packet) {
packet->no_waiter = 1;
packet->generation = get_hpsb_generation(host);
ret = hpsb_send_packet(packet);
error = hpsb_send_packet(packet);
}
if (ret)
if (error)
HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
host->id);
return ret;
return error;
}
/* Perform a few high-level IRM responsibilities. */
@ -1692,19 +1789,18 @@ exit:
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
{
struct class *class = &hpsb_host_class;
struct class_device *cdev;
struct hpsb_host *host;
int error = 0;
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
down(&hpsb_host_class.sem);
list_for_each_entry(cdev, &hpsb_host_class.children, node) {
host = container_of(cdev, struct hpsb_host, class_dev);
if ((error = cb(host, __data)))
break;
}
up_read(&class->subsys.rwsem);
up(&hpsb_host_class.sem);
return error;
}
@ -1726,10 +1822,10 @@ int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
{
pkt->host = ne->host;
pkt->generation = ne->generation;
pkt->host = ne->host;
pkt->generation = ne->generation;
barrier();
pkt->node_id = ne->nodeid;
pkt->node_id = ne->nodeid;
}
int hpsb_node_write(struct node_entry *ne, u64 addr,
@ -1789,26 +1885,25 @@ static struct hpsb_highlevel nodemgr_highlevel = {
int init_ieee1394_nodemgr(void)
{
int ret;
int error;
ret = class_register(&nodemgr_ne_class);
if (ret < 0)
return ret;
error = class_register(&nodemgr_ne_class);
if (error)
return error;
ret = class_register(&nodemgr_ud_class);
if (ret < 0) {
error = class_register(&nodemgr_ud_class);
if (error) {
class_unregister(&nodemgr_ne_class);
return ret;
return error;
}
error = driver_register(&nodemgr_mid_layer_driver);
hpsb_register_highlevel(&nodemgr_highlevel);
return 0;
}
void cleanup_ieee1394_nodemgr(void)
{
hpsb_unregister_highlevel(&nodemgr_highlevel);
hpsb_unregister_highlevel(&nodemgr_highlevel);
class_unregister(&nodemgr_ud_class);
class_unregister(&nodemgr_ne_class);

View File

@ -144,7 +144,12 @@ struct hpsb_protocol_driver {
struct device_driver driver;
};
int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
int __hpsb_register_protocol(struct hpsb_protocol_driver *, struct module *);
static inline int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
{
return __hpsb_register_protocol(driver, THIS_MODULE);
}
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
static inline int hpsb_node_entry_valid(struct node_entry *ne)

View File

@ -468,7 +468,6 @@ static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
/* Global initialization */
static void ohci_initialize(struct ti_ohci *ohci)
{
char irq_buf[16];
quadlet_t buf;
int num_ports, i;
@ -586,11 +585,10 @@ static void ohci_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
buf = reg_read(ohci, OHCI1394_Version);
sprintf (irq_buf, "%d", ohci->dev->irq);
PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] "
PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%d] "
"MMIO=[%llx-%llx] Max Packet=[%d] IR/IT contexts=[%d/%d]",
((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf,
((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq,
(unsigned long long)pci_resource_start(ohci->dev, 0),
(unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
ohci->max_packet_size,
@ -3217,6 +3215,18 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
struct ti_ohci *ohci; /* shortcut to currently handled device */
resource_size_t ohci_base;
#ifdef CONFIG_PPC_PMAC
/* Necessary on some machines if ohci1394 was loaded/ unloaded before */
if (machine_is(powermac)) {
struct device_node *ofn = pci_device_to_OF_node(dev);
if (ofn) {
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 1);
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
}
}
#endif /* CONFIG_PPC_PMAC */
if (pci_enable_device(dev))
FAIL(-ENXIO, "Failed to enable OHCI hardware");
pci_set_master(dev);
@ -3505,17 +3515,14 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
#endif
#ifdef CONFIG_PPC_PMAC
/* On UniNorth, power down the cable and turn off the chip
* clock when the module is removed to save power on
* laptops. Turning it back ON is done by the arch code when
* pci_enable_device() is called */
{
struct device_node* of_node;
/* On UniNorth, power down the cable and turn off the chip clock
* to save power on laptops */
if (machine_is(powermac)) {
struct device_node* ofn = pci_device_to_OF_node(ohci->dev);
of_node = pci_device_to_OF_node(ohci->dev);
if (of_node) {
pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node, 0, 0);
if (ofn) {
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
}
}
#endif /* CONFIG_PPC_PMAC */
@ -3529,56 +3536,99 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
static int ohci1394_pci_resume (struct pci_dev *pdev)
static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
int err;
struct ti_ohci *ohci = pci_get_drvdata(pdev);
printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
OHCI1394_DRIVER_NAME);
if (!ohci) {
printk(KERN_ERR "%s: tried to suspend nonexisting host\n",
OHCI1394_DRIVER_NAME);
return -ENXIO;
}
DBGMSG("suspend called");
/* Clear the async DMA contexts and stop using the controller */
hpsb_bus_reset(ohci->host);
/* See ohci1394_pci_remove() for comments on this sequence */
reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
reg_write(ohci, OHCI1394_BusOptions,
(reg_read(ohci, OHCI1394_BusOptions) & 0x0000f007) |
0x00ff0000);
reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);
set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4));
reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT);
ohci_soft_reset(ohci);
err = pci_save_state(pdev);
if (err) {
PRINT(KERN_ERR, "pci_save_state failed with %d", err);
return err;
}
err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
if (err)
DBGMSG("pci_set_power_state failed with %d", err);
/* PowerMac suspend code comes last */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *ofn = pci_device_to_OF_node(pdev);
if (ofn)
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
}
#endif /* CONFIG_PPC_PMAC */
return 0;
}
static int ohci1394_pci_resume(struct pci_dev *pdev)
{
int err;
struct ti_ohci *ohci = pci_get_drvdata(pdev);
if (!ohci) {
printk(KERN_ERR "%s: tried to resume nonexisting host\n",
OHCI1394_DRIVER_NAME);
return -ENXIO;
}
DBGMSG("resume called");
/* PowerMac resume code comes first */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *of_node;
struct device_node *ofn = pci_device_to_OF_node(pdev);
/* Re-enable 1394 */
of_node = pci_device_to_OF_node (pdev);
if (of_node)
pmac_call_feature (PMAC_FTR_1394_ENABLE, of_node, 0, 1);
if (ofn)
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
}
#endif /* CONFIG_PPC_PMAC */
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
return pci_enable_device(pdev);
}
static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{
int err;
printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
OHCI1394_DRIVER_NAME);
err = pci_save_state(pdev);
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "%s: pci_save_state failed with %d\n",
OHCI1394_DRIVER_NAME, err);
PRINT(KERN_ERR, "pci_enable_device failed with %d", err);
return err;
}
err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
#ifdef OHCI1394_DEBUG
if (err)
printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n",
OHCI1394_DRIVER_NAME, err);
#endif /* OHCI1394_DEBUG */
/* PowerMac suspend code comes last */
#ifdef CONFIG_PPC_PMAC
if (machine_is(powermac)) {
struct device_node *of_node;
/* Disable 1394 */
of_node = pci_device_to_OF_node (pdev);
if (of_node)
pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
}
#endif /* CONFIG_PPC_PMAC */
/* See ohci1394_pci_probe() for comments on this sequence */
ohci_soft_reset(ohci);
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS);
reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
mdelay(50);
ohci_initialize(ohci);
return 0;
}

View File

@ -1428,10 +1428,9 @@ static int __devinit add_card(struct pci_dev *dev,
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENOMEM;
i2c_ad = kmalloc(sizeof(*i2c_ad), GFP_KERNEL);
i2c_ad = kmemdup(&bit_ops, sizeof(*i2c_ad), GFP_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
i2c_adapter_data = bit_data;
i2c_ad->algo_data = &i2c_adapter_data;
i2c_adapter_data.data = lynx;

View File

@ -27,12 +27,12 @@ struct file_info {
struct hpsb_host *host;
struct list_head req_pending;
struct list_head req_complete;
struct list_head req_pending; /* protected by reqlists_lock */
struct list_head req_complete; /* protected by reqlists_lock */
spinlock_t reqlists_lock;
wait_queue_head_t wait_complete;
struct list_head addr_list;
struct list_head addr_list; /* protected by host_info_lock */
u8 __user *fcp_buffer;
@ -63,7 +63,7 @@ struct arm_addr {
u8 client_transactions;
u64 recvb;
u16 rec_length;
u8 *addr_space_buffer; /* accessed by read/write/lock */
u8 *addr_space_buffer; /* accessed by read/write/lock requests */
};
struct pending_request {
@ -79,7 +79,7 @@ struct pending_request {
struct host_info {
struct list_head list;
struct hpsb_host *host;
struct list_head file_info_list;
struct list_head file_info_list; /* protected by host_info_lock */
};
#endif /* IEEE1394_RAW1394_PRIVATE_H */

View File

@ -99,6 +99,21 @@ static struct hpsb_address_ops arm_ops = {
static void queue_complete_cb(struct pending_request *req);
#include <asm/current.h>
static void print_old_iso_deprecation(void)
{
static pid_t p;
if (p == current->pid)
return;
p = current->pid;
printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported"
" isochronous request types which will be removed in a next"
" kernel release\n", current->comm);
printk(KERN_WARNING "raw1394: Update your software to use libraw1394's"
" newer interface\n");
}
static struct pending_request *__alloc_pending_request(gfp_t flags)
{
struct pending_request *req;
@ -2292,6 +2307,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
return sizeof(struct raw1394_request);
case RAW1394_REQ_ISO_SEND:
print_old_iso_deprecation();
return handle_iso_send(fi, req, node);
case RAW1394_REQ_ARM_REGISTER:
@ -2310,6 +2326,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
return reset_notification(fi, req);
case RAW1394_REQ_ISO_LISTEN:
print_old_iso_deprecation();
handle_iso_listen(fi, req);
return sizeof(struct raw1394_request);
@ -2970,12 +2987,8 @@ static struct ieee1394_device_id raw1394_id_table[] = {
MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
static struct hpsb_protocol_driver raw1394_driver = {
.name = "raw1394 Driver",
.name = "raw1394",
.id_table = raw1394_id_table,
.driver = {
.name = "raw1394",
.bus = &ieee1394_bus_type,
},
};
/******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@ -25,25 +25,25 @@
#define SBP2_DEVICE_NAME "sbp2"
/*
* SBP2 specific structures and defines
* SBP-2 specific definitions
*/
#define ORB_DIRECTION_WRITE_TO_MEDIA 0x0
#define ORB_DIRECTION_READ_FROM_MEDIA 0x1
#define ORB_DIRECTION_NO_DATA_TRANSFER 0x2
#define ORB_DIRECTION_WRITE_TO_MEDIA 0x0
#define ORB_DIRECTION_READ_FROM_MEDIA 0x1
#define ORB_DIRECTION_NO_DATA_TRANSFER 0x2
#define ORB_SET_NULL_PTR(value) ((value & 0x1) << 31)
#define ORB_SET_NOTIFY(value) ((value & 0x1) << 31)
#define ORB_SET_RQ_FMT(value) ((value & 0x3) << 29) /* unused ? */
#define ORB_SET_NODE_ID(value) ((value & 0xffff) << 16)
#define ORB_SET_STATUS_FIFO_HI(value, id) (value >> 32 | ORB_SET_NODE_ID(id))
#define ORB_SET_STATUS_FIFO_LO(value) (value & 0xffffffff)
#define ORB_SET_DATA_SIZE(value) (value & 0xffff)
#define ORB_SET_PAGE_SIZE(value) ((value & 0x7) << 16)
#define ORB_SET_PAGE_TABLE_PRESENT(value) ((value & 0x1) << 19)
#define ORB_SET_MAX_PAYLOAD(value) ((value & 0xf) << 20)
#define ORB_SET_SPEED(value) ((value & 0x7) << 24)
#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)
#define ORB_SET_NULL_PTR(v) (((v) & 0x1) << 31)
#define ORB_SET_NOTIFY(v) (((v) & 0x1) << 31)
#define ORB_SET_RQ_FMT(v) (((v) & 0x3) << 29)
#define ORB_SET_NODE_ID(v) (((v) & 0xffff) << 16)
#define ORB_SET_STATUS_FIFO_HI(v, id) ((v) >> 32 | ORB_SET_NODE_ID(id))
#define ORB_SET_STATUS_FIFO_LO(v) ((v) & 0xffffffff)
#define ORB_SET_DATA_SIZE(v) ((v) & 0xffff)
#define ORB_SET_PAGE_SIZE(v) (((v) & 0x7) << 16)
#define ORB_SET_PAGE_TABLE_PRESENT(v) (((v) & 0x1) << 19)
#define ORB_SET_MAX_PAYLOAD(v) (((v) & 0xf) << 20)
#define ORB_SET_SPEED(v) (((v) & 0x7) << 24)
#define ORB_SET_DIRECTION(v) (((v) & 0x1) << 27)
struct sbp2_command_orb {
u32 next_ORB_hi;
@ -64,12 +64,12 @@ struct sbp2_command_orb {
#define SBP2_LOGICAL_UNIT_RESET 0xe
#define SBP2_TARGET_RESET_REQUEST 0xf
#define ORB_SET_LUN(value) (value & 0xffff)
#define ORB_SET_FUNCTION(value) ((value & 0xf) << 16)
#define ORB_SET_RECONNECT(value) ((value & 0xf) << 20)
#define ORB_SET_EXCLUSIVE(value) ((value & 0x1) << 28)
#define ORB_SET_LOGIN_RESP_LENGTH(value) (value & 0xffff)
#define ORB_SET_PASSWD_LENGTH(value) ((value & 0xffff) << 16)
#define ORB_SET_LUN(v) ((v) & 0xffff)
#define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16)
#define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20)
#define ORB_SET_EXCLUSIVE(v) (((v) & 0x1) << 28)
#define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff)
#define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16)
struct sbp2_login_orb {
u32 password_hi;
@ -82,9 +82,9 @@ struct sbp2_login_orb {
u32 status_fifo_lo;
} __attribute__((packed));
#define RESPONSE_GET_LOGIN_ID(value) (value & 0xffff)
#define RESPONSE_GET_LENGTH(value) ((value >> 16) & 0xffff)
#define RESPONSE_GET_RECONNECT_HOLD(value) (value & 0xffff)
#define RESPONSE_GET_LOGIN_ID(v) ((v) & 0xffff)
#define RESPONSE_GET_LENGTH(v) (((v) >> 16) & 0xffff)
#define RESPONSE_GET_RECONNECT_HOLD(v) ((v) & 0xffff)
struct sbp2_login_response {
u32 length_login_ID;
@ -93,9 +93,8 @@ struct sbp2_login_response {
u32 reconnect_hold;
} __attribute__((packed));
#define ORB_SET_LOGIN_ID(value) (value & 0xffff)
#define ORB_SET_QUERY_LOGINS_RESP_LENGTH(value) (value & 0xffff)
#define ORB_SET_LOGIN_ID(v) ((v) & 0xffff)
#define ORB_SET_QUERY_LOGINS_RESP_LENGTH(v) ((v) & 0xffff)
struct sbp2_query_logins_orb {
u32 reserved1;
@ -108,8 +107,8 @@ struct sbp2_query_logins_orb {
u32 status_fifo_lo;
} __attribute__((packed));
#define RESPONSE_GET_MAX_LOGINS(value) (value & 0xffff)
#define RESPONSE_GET_ACTIVE_LOGINS(value) ((RESPONSE_GET_LENGTH(value) - 4) / 12)
#define RESPONSE_GET_MAX_LOGINS(v) ((v) & 0xffff)
#define RESPONSE_GET_ACTIVE_LOGINS(v) ((RESPONSE_GET_LENGTH((v)) - 4) / 12)
struct sbp2_query_logins_response {
u32 length_max_logins;
@ -140,8 +139,8 @@ struct sbp2_logout_orb {
u32 status_fifo_lo;
} __attribute__((packed));
#define PAGE_TABLE_SET_SEGMENT_BASE_HI(value) (value & 0xffff)
#define PAGE_TABLE_SET_SEGMENT_LENGTH(value) ((value & 0xffff) << 16)
#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;
@ -171,23 +170,14 @@ struct sbp2_unrestricted_page_table {
#define SFMT_DEFERRED_ERROR 0x1
#define SFMT_VENDOR_DEPENDENT_STATUS 0x3
#define SBP2_SCSI_STATUS_GOOD 0x0
#define SBP2_SCSI_STATUS_CHECK_CONDITION 0x2
#define SBP2_SCSI_STATUS_CONDITION_MET 0x4
#define SBP2_SCSI_STATUS_BUSY 0x8
#define SBP2_SCSI_STATUS_RESERVATION_CONFLICT 0x18
#define SBP2_SCSI_STATUS_COMMAND_TERMINATED 0x22
#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
#define STATUS_GET_SRC(value) (((value) >> 30) & 0x3)
#define STATUS_GET_RESP(value) (((value) >> 28) & 0x3)
#define STATUS_GET_LEN(value) (((value) >> 24) & 0x7)
#define STATUS_GET_SBP_STATUS(value) (((value) >> 16) & 0xff)
#define STATUS_GET_ORB_OFFSET_HI(value) ((value) & 0x0000ffff)
#define STATUS_TEST_DEAD(value) ((value) & 0x08000000)
#define STATUS_GET_SRC(v) (((v) >> 30) & 0x3)
#define STATUS_GET_RESP(v) (((v) >> 28) & 0x3)
#define STATUS_GET_LEN(v) (((v) >> 24) & 0x7)
#define STATUS_GET_SBP_STATUS(v) (((v) >> 16) & 0xff)
#define STATUS_GET_ORB_OFFSET_HI(v) ((v) & 0x0000ffff)
#define STATUS_TEST_DEAD(v) ((v) & 0x08000000)
/* test 'resp' | 'dead' | 'sbp2_status' */
#define STATUS_TEST_RDS(value) ((value) & 0x38ff0000)
#define STATUS_TEST_RDS(v) ((v) & 0x38ff0000)
struct sbp2_status_block {
u32 ORB_offset_hi_misc;
@ -195,66 +185,70 @@ struct sbp2_status_block {
u8 command_set_dependent[24];
} __attribute__((packed));
/*
* Miscellaneous SBP2 related config rom defines
*/
#define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1
#define SBP2_CSR_OFFSET_KEY 0x54
#define SBP2_UNIT_SPEC_ID_KEY 0x12
#define SBP2_UNIT_SW_VERSION_KEY 0x13
#define SBP2_COMMAND_SET_SPEC_ID_KEY 0x38
#define SBP2_COMMAND_SET_KEY 0x39
#define SBP2_UNIT_CHARACTERISTICS_KEY 0x3a
#define SBP2_DEVICE_TYPE_AND_LUN_KEY 0x14
#define SBP2_FIRMWARE_REVISION_KEY 0x3c
#define SBP2_AGENT_STATE_OFFSET 0x00ULL
#define SBP2_AGENT_RESET_OFFSET 0x04ULL
#define SBP2_ORB_POINTER_OFFSET 0x08ULL
#define SBP2_DOORBELL_OFFSET 0x10ULL
#define SBP2_UNSOLICITED_STATUS_ENABLE_OFFSET 0x14ULL
#define SBP2_UNSOLICITED_STATUS_VALUE 0xf
#define SBP2_BUSY_TIMEOUT_ADDRESS 0xfffff0000210ULL
#define SBP2_BUSY_TIMEOUT_VALUE 0xf
#define SBP2_AGENT_RESET_DATA 0xf
/*
* Unit spec id and sw version entry for SBP-2 devices
* SBP2 related configuration ROM definitions
*/
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
#define SBP2_SW_VERSION_ENTRY 0x00010483
#define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1
#define SBP2_CSR_OFFSET_KEY 0x54
#define SBP2_UNIT_SPEC_ID_KEY 0x12
#define SBP2_UNIT_SW_VERSION_KEY 0x13
#define SBP2_COMMAND_SET_SPEC_ID_KEY 0x38
#define SBP2_COMMAND_SET_KEY 0x39
#define SBP2_UNIT_CHARACTERISTICS_KEY 0x3a
#define SBP2_DEVICE_TYPE_AND_LUN_KEY 0x14
#define SBP2_FIRMWARE_REVISION_KEY 0x3c
#define SBP2_AGENT_STATE_OFFSET 0x00ULL
#define SBP2_AGENT_RESET_OFFSET 0x04ULL
#define SBP2_ORB_POINTER_OFFSET 0x08ULL
#define SBP2_DOORBELL_OFFSET 0x10ULL
#define SBP2_UNSOLICITED_STATUS_ENABLE_OFFSET 0x14ULL
#define SBP2_UNSOLICITED_STATUS_VALUE 0xf
#define SBP2_BUSY_TIMEOUT_ADDRESS 0xfffff0000210ULL
/* biggest possible value for Single Phase Retry count is 0xf */
#define SBP2_BUSY_TIMEOUT_VALUE 0xf
#define SBP2_AGENT_RESET_DATA 0xf
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
#define SBP2_SW_VERSION_ENTRY 0x00010483
/*
* SCSI specific stuff
* SCSI specific definitions
*/
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
#define SBP2_MAX_CMDS 8 /* This should be safe */
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_MAX_SECTORS 255
/* 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. */
#define SBP2_MAX_CMDS 8
/* Flags for detected oddities and brokeness */
#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
#define SBP2_WORKAROUND_INQUIRY_36 0x2
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
#define SBP2_WORKAROUND_OVERRIDE 0x100
#define SBP2_SCSI_STATUS_GOOD 0x0
#define SBP2_SCSI_STATUS_CHECK_CONDITION 0x2
#define SBP2_SCSI_STATUS_CONDITION_MET 0x4
#define SBP2_SCSI_STATUS_BUSY 0x8
#define SBP2_SCSI_STATUS_RESERVATION_CONFLICT 0x18
#define SBP2_SCSI_STATUS_COMMAND_TERMINATED 0x22
#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
/* This is the two dma types we use for cmd_dma below */
enum cmd_dma_types {
/*
* Representations of commands and devices
*/
enum sbp2_dma_types {
CMD_DMA_NONE,
CMD_DMA_PAGE,
CMD_DMA_SINGLE
};
/*
* Encapsulates all the info necessary for an outstanding command.
*/
/* Per SCSI command */
struct sbp2_command_info {
struct list_head list;
struct sbp2_command_orb command_orb ____cacheline_aligned;
dma_addr_t command_orb_dma ____cacheline_aligned;
@ -262,25 +256,25 @@ struct sbp2_command_info {
void (*Current_done)(struct scsi_cmnd *);
/* Also need s/g structure for each sbp2 command */
struct sbp2_unrestricted_page_table scatter_gather_element[SG_ALL] ____cacheline_aligned;
struct sbp2_unrestricted_page_table
scatter_gather_element[SG_ALL] ____cacheline_aligned;
dma_addr_t sge_dma ____cacheline_aligned;
void *sge_buffer;
dma_addr_t cmd_dma;
enum cmd_dma_types dma_type;
enum sbp2_dma_types dma_type;
unsigned long dma_size;
int dma_dir;
enum dma_data_direction dma_dir;
};
struct sbp2scsi_host_info;
/* Per FireWire host */
struct sbp2_fwhost_info {
struct hpsb_host *host;
struct list_head logical_units;
};
/*
* Information needed on a per scsi id basis (one for each sbp2 device)
*/
struct scsi_id_instance_data {
/*
* Various sbp2 specific structures
*/
/* Per logical unit */
struct sbp2_lu {
/* Operation request blocks */
struct sbp2_command_orb *last_orb;
dma_addr_t last_orb_dma;
struct sbp2_login_orb *login_orb;
@ -297,116 +291,59 @@ struct scsi_id_instance_data {
dma_addr_t logout_orb_dma;
struct sbp2_status_block status_block;
/*
* Stuff we need to know about the sbp2 device itself
*/
u64 sbp2_management_agent_addr;
u64 sbp2_command_block_agent_addr;
/* How to talk to the unit */
u64 management_agent_addr;
u64 command_block_agent_addr;
u32 speed_code;
u32 max_payload_size;
u16 lun;
/*
* Values pulled from the device's unit directory
*/
u32 sbp2_command_set_spec_id;
u32 sbp2_command_set;
u32 sbp2_unit_characteristics;
u32 sbp2_lun;
u32 sbp2_firmware_revision;
/*
* Address for the device to write status blocks to
*/
/* Address for the unit to write status blocks to */
u64 status_fifo_addr;
/*
* Waitqueue flag for logins, reconnects, logouts, query logins
*/
int access_complete:1;
/* Waitqueue flag for logins, reconnects, logouts, query logins */
unsigned int access_complete:1;
/*
* Pool of command orbs, so we can have more than overlapped command per id
*/
spinlock_t sbp2_command_orb_lock;
struct list_head sbp2_command_orb_inuse;
struct list_head sbp2_command_orb_completed;
/* Pool of command ORBs for this logical unit */
spinlock_t cmd_orb_lock;
struct list_head cmd_orb_inuse;
struct list_head cmd_orb_completed;
struct list_head scsi_list;
/* Backlink to FireWire host; list of units attached to the host */
struct sbp2_fwhost_info *hi;
struct list_head lu_list;
/* Node entry, as retrieved from NodeMgr entries */
/* IEEE 1394 core's device representations */
struct node_entry *ne;
struct unit_directory *ud;
/* A backlink to our host_info */
struct sbp2scsi_host_info *hi;
/* SCSI related pointers */
/* SCSI core's device representations */
struct scsi_device *sdev;
struct Scsi_Host *scsi_host;
struct Scsi_Host *shost;
/* Device specific workarounds/brokeness */
unsigned workarounds;
/* Connection state */
atomic_t state;
struct delayed_work protocol_work;
/* For deferred requests to the fetch agent */
struct work_struct protocol_work;
};
/* For use in scsi_id_instance_data.state */
/* For use in sbp2_lu.state */
enum sbp2lu_state_types {
SBP2LU_STATE_RUNNING, /* all normal */
SBP2LU_STATE_IN_RESET, /* between bus reset and reconnect */
SBP2LU_STATE_IN_SHUTDOWN /* when sbp2_remove was called */
};
/* Sbp2 host data structure (one per IEEE1394 host) */
struct sbp2scsi_host_info {
struct hpsb_host *host; /* IEEE1394 host */
struct list_head scsi_ids; /* List of scsi ids on this host */
};
/*
* Function prototypes
*/
/*
* Various utility prototypes
*/
static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_id);
static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_id);
static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb);
static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt);
static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *Current_SCpnt,
void (*Current_done)(struct scsi_cmnd *));
static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command);
static int sbp2_start_device(struct scsi_id_instance_data *scsi_id);
static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id);
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
u64 addr, size_t length, u16 flags);
static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
u64 addr, size_t length, u16 flags);
#endif
/*
* SBP-2 protocol related prototypes
*/
static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id);
static int sbp2_login_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status,
unchar *sense_data);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
struct unit_directory *ud);
static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);
static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id);
/* For use in sbp2_lu.workarounds and in the corresponding
* module load parameter */
#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
#define SBP2_WORKAROUND_INQUIRY_36 0x2
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
#define SBP2_WORKAROUND_OVERRIDE 0x100
#endif /* SBP2_H */

View File

@ -714,8 +714,8 @@ static inline unsigned video1394_buffer_state(struct dma_iso_ctx *d,
return ret;
}
static int __video1394_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
static long video1394_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct file_ctx *ctx = (struct file_ctx *)file->private_data;
struct ti_ohci *ohci = ctx->ohci;
@ -884,13 +884,14 @@ static int __video1394_ioctl(struct file *file,
struct dma_iso_ctx *d;
int next_prg;
if (copy_from_user(&v, argp, sizeof(v)))
if (unlikely(copy_from_user(&v, argp, sizeof(v))))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
if (d == NULL) return -EFAULT;
if (unlikely(d == NULL))
return -EFAULT;
if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
@ -898,7 +899,7 @@ static int __video1394_ioctl(struct file *file,
spin_lock_irqsave(&d->lock,flags);
if (d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED) {
if (unlikely(d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED)) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d is already used",v.buffer);
spin_unlock_irqrestore(&d->lock,flags);
@ -949,13 +950,14 @@ static int __video1394_ioctl(struct file *file,
struct dma_iso_ctx *d;
int i = 0;
if (copy_from_user(&v, argp, sizeof(v)))
if (unlikely(copy_from_user(&v, argp, sizeof(v))))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
if (d == NULL) return -EFAULT;
if (unlikely(d == NULL))
return -EFAULT;
if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
@ -1008,7 +1010,7 @@ static int __video1394_ioctl(struct file *file,
spin_unlock_irqrestore(&d->lock, flags);
v.buffer=i;
if (copy_to_user(argp, &v, sizeof(v)))
if (unlikely(copy_to_user(argp, &v, sizeof(v))))
return -EFAULT;
return 0;
@ -1156,15 +1158,6 @@ static int __video1394_ioctl(struct file *file,
}
}
static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int err;
lock_kernel();
err = __video1394_ioctl(file, cmd, arg);
unlock_kernel();
return err;
}
/*
* This maps the vmalloced and reserved buffer to user space.
*
@ -1177,17 +1170,14 @@ static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long a
static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
{
struct file_ctx *ctx = (struct file_ctx *)file->private_data;
int res = -EINVAL;
lock_kernel();
if (ctx->current_ctx == NULL) {
PRINT(KERN_ERR, ctx->ohci->host->id,
"Current iso context not set");
} else
res = dma_region_mmap(&ctx->current_ctx->dma, file, vma);
unlock_kernel();
return -EINVAL;
}
return res;
return dma_region_mmap(&ctx->current_ctx->dma, file, vma);
}
static unsigned int video1394_poll(struct file *file, poll_table *pt)
@ -1198,14 +1188,12 @@ static unsigned int video1394_poll(struct file *file, poll_table *pt)
struct dma_iso_ctx *d;
int i;
lock_kernel();
ctx = file->private_data;
d = ctx->current_ctx;
if (d == NULL) {
PRINT(KERN_ERR, ctx->ohci->host->id,
"Current iso context not set");
mask = POLLERR;
goto done;
return POLLERR;
}
poll_wait(file, &d->waitq, pt);
@ -1218,8 +1206,6 @@ static unsigned int video1394_poll(struct file *file, poll_table *pt)
}
}
spin_unlock_irqrestore(&d->lock, flags);
done:
unlock_kernel();
return mask;
}
@ -1255,7 +1241,6 @@ static int video1394_release(struct inode *inode, struct file *file)
struct list_head *lh, *next;
u64 mask;
lock_kernel();
list_for_each_safe(lh, next, &ctx->context_list) {
struct dma_iso_ctx *d;
d = list_entry(lh, struct dma_iso_ctx, link);
@ -1276,7 +1261,6 @@ static int video1394_release(struct inode *inode, struct file *file)
kfree(ctx);
file->private_data = NULL;
unlock_kernel();
return 0;
}
@ -1324,12 +1308,8 @@ static struct ieee1394_device_id video1394_id_table[] = {
MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
static struct hpsb_protocol_driver video1394_driver = {
.name = "1394 Digital Camera Driver",
.name = VIDEO1394_DRIVER_NAME,
.id_table = video1394_id_table,
.driver = {
.name = VIDEO1394_DRIVER_NAME,
.bus = &ieee1394_bus_type,
},
};