Skip to content

Commit

Permalink
firewire: add CSR PRIORITY_BUDGET support
Browse files Browse the repository at this point in the history
If supported by the OHCI controller, implement the PRIORITY_BUDGET
register, which is required for nodes that can use asynchronous
priority arbitration.

To allow the core to determine what features the lowlevel device
supports, add a new card driver callback.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
  • Loading branch information
cladisch committed Jun 10, 2010
1 parent 27a2329 commit a1a1132
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
14 changes: 14 additions & 0 deletions drivers/firewire/core-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,20 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
rcode = RCODE_TYPE_ERROR;
break;

case CSR_PRIORITY_BUDGET:
if (!(card->driver->get_features(card) &
FEATURE_PRIORITY_BUDGET))
rcode = RCODE_ADDRESS_ERROR;
else if (tcode == TCODE_READ_QUADLET_REQUEST)
*data = cpu_to_be32(card->driver->
read_csr_reg(card, CSR_PRIORITY_BUDGET));
else if (tcode == TCODE_WRITE_QUADLET_REQUEST)
card->driver->write_csr_reg(card, CSR_PRIORITY_BUDGET,
be32_to_cpu(*data));
else
rcode = RCODE_TYPE_ERROR;
break;

case CSR_BROADCAST_CHANNEL:
if (tcode == TCODE_READ_QUADLET_REQUEST)
*data = cpu_to_be32(card->broadcast_channel);
Expand Down
4 changes: 4 additions & 0 deletions drivers/firewire/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct fw_packet;
#define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31)
#define BROADCAST_CHANNEL_VALID (1 << 30)

#define FEATURE_PRIORITY_BUDGET 0x01

struct fw_card_driver {
/*
* Enable the given card with the given initial config rom.
Expand Down Expand Up @@ -78,6 +80,8 @@ struct fw_card_driver {
u32 (*read_csr_reg)(struct fw_card *card, int csr_offset);
void (*write_csr_reg)(struct fw_card *card, int csr_offset, u32 value);

unsigned int (*get_features)(struct fw_card *card);

struct fw_iso_context *
(*allocate_iso_context)(struct fw_card *card,
int type, int channel, size_t header_size);
Expand Down
27 changes: 27 additions & 0 deletions drivers/firewire/ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct fw_ohci {
int generation;
int request_generation; /* for timestamping incoming requests */
unsigned quirks;
unsigned int pri_req_max;
u32 bus_time;

/*
Expand Down Expand Up @@ -1738,6 +1739,11 @@ static int ohci_enable(struct fw_card *card,
reg_write(ohci, OHCI1394_IsochronousCycleTimer, seconds << 25);
ohci->bus_time = seconds & ~0x3f;

/* Get implemented bits of the priority arbitration request counter. */
reg_write(ohci, OHCI1394_FairnessControl, 0x3f);
ohci->pri_req_max = reg_read(ohci, OHCI1394_FairnessControl) & 0x3f;
reg_write(ohci, OHCI1394_FairnessControl, 0);

ar_context_run(&ohci->ar_request_ctx);
ar_context_run(&ohci->ar_response_ctx);

Expand Down Expand Up @@ -2028,6 +2034,10 @@ static u32 ohci_read_csr_reg(struct fw_card *card, int csr_offset)
value = reg_read(ohci, OHCI1394_ATRetries);
return (value >> 4) & 0x0ffff00f;

case CSR_PRIORITY_BUDGET:
return (reg_read(ohci, OHCI1394_FairnessControl) & 0x3f) |
(ohci->pri_req_max << 8);

default:
WARN_ON(1);
return 0;
Expand Down Expand Up @@ -2065,12 +2075,28 @@ static void ohci_write_csr_reg(struct fw_card *card, int csr_offset, u32 value)
flush_writes(ohci);
break;

case CSR_PRIORITY_BUDGET:
reg_write(ohci, OHCI1394_FairnessControl, value & 0x3f);
flush_writes(ohci);
break;

default:
WARN_ON(1);
break;
}
}

static unsigned int ohci_get_features(struct fw_card *card)
{
struct fw_ohci *ohci = fw_ohci(card);
unsigned int features = 0;

if (ohci->pri_req_max != 0)
features |= FEATURE_PRIORITY_BUDGET;

return features;
}

static void copy_iso_headers(struct iso_context *ctx, void *p)
{
int i = ctx->header_length;
Expand Down Expand Up @@ -2510,6 +2536,7 @@ static const struct fw_card_driver ohci_driver = {
.enable_phys_dma = ohci_enable_phys_dma,
.read_csr_reg = ohci_read_csr_reg,
.write_csr_reg = ohci_write_csr_reg,
.get_features = ohci_get_features,

.allocate_iso_context = ohci_allocate_iso_context,
.free_iso_context = ohci_free_iso_context,
Expand Down
1 change: 1 addition & 0 deletions include/linux/firewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define CSR_CYCLE_TIME 0x200
#define CSR_BUS_TIME 0x204
#define CSR_BUSY_TIMEOUT 0x210
#define CSR_PRIORITY_BUDGET 0x218
#define CSR_BUS_MANAGER_ID 0x21c
#define CSR_BANDWIDTH_AVAILABLE 0x220
#define CSR_CHANNELS_AVAILABLE 0x224
Expand Down

0 comments on commit a1a1132

Please sign in to comment.