#include <linux/moduleparam.h>
#include <linux/bitops.h>
#include <linux/kdev_t.h>
+#include <linux/freezer.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
#include <linux/preempt.h>
{
if (host->in_bus_reset) {
HPSB_NOTICE("%s called while bus reset already in progress",
- __FUNCTION__);
+ __func__);
return 1;
}
u8 cldcnt[nodecount];
u8 *map = host->speed_map;
u8 *speedcap = host->speed;
+ u8 local_link_speed = host->csr.lnk_spd;
struct selfid *sid;
struct ext_selfid *esid;
int i, j, n;
if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
speedcap[n] = sid->speed;
+ if (speedcap[n] > local_link_speed)
+ speedcap[n] = local_link_speed;
n--;
}
}
}
}
-#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
- /* assume maximum speed for 1394b PHYs, nodemgr will correct it */
- for (n = 0; n < nodecount; n++)
- if (speedcap[n] == SELFID_SPEED_UNKNOWN)
- speedcap[n] = IEEE1394_SPEED_MAX;
-#endif
+ /* assume a maximum speed for 1394b PHYs, nodemgr will correct it */
+ if (local_link_speed > SELFID_SPEED_UNKNOWN)
+ for (i = 0; i < nodecount; i++)
+ if (speedcap[i] == SELFID_SPEED_UNKNOWN)
+ speedcap[i] = local_link_speed;
}
highlevel_host_reset(host);
}
-static spinlock_t pending_packets_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pending_packets_lock);
/**
* hpsb_packet_sent - notify core of sending a packet
packet->data_size = length;
}
-#define PREP_REPLY_PACKET(length) \
- packet = create_reply_packet(host, data, length); \
- if (packet == NULL) break
-
static void handle_incoming_packet(struct hpsb_host *host, int tcode,
- quadlet_t *data, size_t size, int write_acked)
+ quadlet_t *data, size_t size,
+ int write_acked)
{
struct hpsb_packet *packet;
int length, rcode, extcode;
u16 flags = (u16) data[0];
u64 addr;
- /* big FIXME - no error checking is done for an out of bounds length */
+ /* FIXME?
+ * Out-of-bounds lengths are left for highlevel_read|write to cap. */
switch (tcode) {
case TCODE_WRITEQ:
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, source, dest, data+3,
+ rcode = highlevel_write(host, source, dest, data + 3,
addr, 4, flags);
-
- if (!write_acked
- && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
- && (rcode >= 0)) {
- /* not a broadcast write, reply */
- PREP_REPLY_PACKET(0);
- fill_async_write_resp(packet, rcode);
- send_packet_nocare(packet);
- }
- break;
+ goto handle_write_request;
case TCODE_WRITEB:
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, source, dest, data+4,
- addr, data[3]>>16, flags);
-
- if (!write_acked
- && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
- && (rcode >= 0)) {
- /* not a broadcast write, reply */
- PREP_REPLY_PACKET(0);
+ rcode = highlevel_write(host, source, dest, data + 4,
+ addr, data[3] >> 16, flags);
+handle_write_request:
+ if (rcode < 0 || write_acked ||
+ NODEID_TO_NODE(data[0] >> 16) == NODE_MASK)
+ return;
+ /* not a broadcast write, reply */
+ packet = create_reply_packet(host, data, 0);
+ if (packet) {
fill_async_write_resp(packet, rcode);
send_packet_nocare(packet);
}
- break;
+ return;
case TCODE_READQ:
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
+ if (rcode < 0)
+ return;
- if (rcode >= 0) {
- PREP_REPLY_PACKET(0);
+ packet = create_reply_packet(host, data, 0);
+ if (packet) {
fill_async_readquad_resp(packet, rcode, buffer);
send_packet_nocare(packet);
}
- break;
+ return;
case TCODE_READB:
length = data[3] >> 16;
- PREP_REPLY_PACKET(length);
+ packet = create_reply_packet(host, data, length);
+ if (!packet)
+ return;
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
rcode = highlevel_read(host, source, packet->data, addr,
length, flags);
-
- if (rcode >= 0) {
- fill_async_readblock_resp(packet, rcode, length);
- send_packet_nocare(packet);
- } else {
+ if (rcode < 0) {
hpsb_free_packet(packet);
+ return;
}
- break;
+ fill_async_readblock_resp(packet, rcode, length);
+ send_packet_nocare(packet);
+ return;
case TCODE_LOCK_REQUEST:
length = data[3] >> 16;
extcode = data[3] & 0xffff;
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- PREP_REPLY_PACKET(8);
+ packet = create_reply_packet(host, data, 8);
+ if (!packet)
+ return;
- if ((extcode == 0) || (extcode >= 7)) {
+ if (extcode == 0 || extcode >= 7) {
/* let switch default handle error */
length = 0;
}
switch (length) {
case 4:
rcode = highlevel_lock(host, source, packet->data, addr,
- data[4], 0, extcode,flags);
+ data[4], 0, extcode, flags);
fill_async_lock_resp(packet, rcode, extcode, 4);
break;
case 8:
- if ((extcode != EXTCODE_FETCH_ADD)
- && (extcode != EXTCODE_LITTLE_ADD)) {
+ if (extcode != EXTCODE_FETCH_ADD &&
+ extcode != EXTCODE_LITTLE_ADD) {
rcode = highlevel_lock(host, source,
packet->data, addr,
data[5], data[4],
break;
default:
rcode = RCODE_TYPE_ERROR;
- fill_async_lock_resp(packet, rcode,
- extcode, 0);
+ fill_async_lock_resp(packet, rcode, extcode, 0);
}
- if (rcode >= 0) {
- send_packet_nocare(packet);
- } else {
+ if (rcode < 0)
hpsb_free_packet(packet);
- }
- break;
+ else
+ send_packet_nocare(packet);
+ return;
}
-
}
-#undef PREP_REPLY_PACKET
/**
* hpsb_packet_received - hand over received packet to the core
handle_incoming_packet(host, tcode, data, size, write_acked);
break;
-
- case TCODE_ISO_DATA:
- highlevel_iso_receive(host, data, size);
- break;
-
case TCODE_CYCLE_START:
/* simply ignore this packet if it is passed on */
break;
struct list_head tmp;
int may_schedule;
- current->flags |= PF_NOFREEZE;
-
while (!kthread_should_stop()) {
INIT_LIST_HEAD(&tmp);
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}
-fs_initcall(ieee1394_init); /* same as ohci1394 */
+fs_initcall(ieee1394_init);
module_exit(ieee1394_cleanup);
/* Exported symbols */
EXPORT_SYMBOL(hpsb_make_lockpacket);
EXPORT_SYMBOL(hpsb_make_lock64packet);
EXPORT_SYMBOL(hpsb_make_phypacket);
-EXPORT_SYMBOL(hpsb_make_isopacket);
EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write);
+EXPORT_SYMBOL(hpsb_lock);
EXPORT_SYMBOL(hpsb_packet_success);
/** highlevel.c **/
EXPORT_SYMBOL(hpsb_register_addrspace);
EXPORT_SYMBOL(hpsb_unregister_addrspace);
EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);
-EXPORT_SYMBOL(hpsb_listen_channel);
-EXPORT_SYMBOL(hpsb_unlisten_channel);
EXPORT_SYMBOL(hpsb_get_hostinfo);
EXPORT_SYMBOL(hpsb_create_hostinfo);
EXPORT_SYMBOL(hpsb_destroy_hostinfo);
EXPORT_SYMBOL(hpsb_set_hostinfo_key);
EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
EXPORT_SYMBOL(hpsb_set_hostinfo);
-EXPORT_SYMBOL(highlevel_host_reset);
/** nodemgr.c **/
EXPORT_SYMBOL(hpsb_node_fill_packet);