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: Install firewire-constants.h and firewire-cdev.h for userspace. firewire: Change struct fw_cdev_iso_packet to not use bitfields. firewire: Implement suspend/resume PCI driver hooks. firewire: add to MAINTAINERS firewire: fw-sbp2: implement sysfs ieee1394_id ieee1394: sbp2: offer SAM-conforming target port ID in sysfs ieee1394: fix calculation of sysfs attribute "address"
This commit is contained in:
commit
f285e3d329
|
@ -1498,6 +1498,14 @@ P: Alexander Viro
|
||||||
M: viro@zeniv.linux.org.uk
|
M: viro@zeniv.linux.org.uk
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
FIREWIRE SUBSYSTEM
|
||||||
|
P: Kristian Hoegsberg, Stefan Richter
|
||||||
|
M: krh@redhat.com, stefanr@s5r6.in-berlin.de
|
||||||
|
L: linux1394-devel@lists.sourceforge.net
|
||||||
|
W: http://www.linux1394.org/
|
||||||
|
T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
FIRMWARE LOADER (request_firmware)
|
FIRMWARE LOADER (request_firmware)
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
S: Orphan
|
S: Orphan
|
||||||
|
|
|
@ -407,11 +407,6 @@ fw_card_add(struct fw_card *card,
|
||||||
card->link_speed = link_speed;
|
card->link_speed = link_speed;
|
||||||
card->guid = guid;
|
card->guid = guid;
|
||||||
|
|
||||||
/* Activate link_on bit and contender bit in our self ID packets.*/
|
|
||||||
if (card->driver->update_phy_reg(card, 4, 0,
|
|
||||||
PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The subsystem grabs a reference when the card is added and
|
* The subsystem grabs a reference when the card is added and
|
||||||
* drops it when the driver calls fw_core_remove_card.
|
* drops it when the driver calls fw_core_remove_card.
|
||||||
|
|
|
@ -677,12 +677,21 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Macros for decoding the iso packet control header. */
|
||||||
|
#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_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
|
||||||
|
|
||||||
static int ioctl_queue_iso(struct client *client, void *buffer)
|
static int ioctl_queue_iso(struct client *client, void *buffer)
|
||||||
{
|
{
|
||||||
struct fw_cdev_queue_iso *request = buffer;
|
struct fw_cdev_queue_iso *request = buffer;
|
||||||
struct fw_cdev_iso_packet __user *p, *end, *next;
|
struct fw_cdev_iso_packet __user *p, *end, *next;
|
||||||
struct fw_iso_context *ctx = client->iso_context;
|
struct fw_iso_context *ctx = client->iso_context;
|
||||||
unsigned long payload, buffer_end, header_length;
|
unsigned long payload, buffer_end, header_length;
|
||||||
|
u32 control;
|
||||||
int count;
|
int count;
|
||||||
struct {
|
struct {
|
||||||
struct fw_iso_packet packet;
|
struct fw_iso_packet packet;
|
||||||
|
@ -717,8 +726,14 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
|
||||||
end = (void __user *)p + request->size;
|
end = (void __user *)p + request->size;
|
||||||
count = 0;
|
count = 0;
|
||||||
while (p < end) {
|
while (p < end) {
|
||||||
if (__copy_from_user(&u.packet, p, sizeof(*p)))
|
if (get_user(control, &p->control))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
u.packet.payload_length = GET_PAYLOAD_LENGTH(control);
|
||||||
|
u.packet.interrupt = GET_INTERRUPT(control);
|
||||||
|
u.packet.skip = GET_SKIP(control);
|
||||||
|
u.packet.tag = GET_TAG(control);
|
||||||
|
u.packet.sy = GET_SY(control);
|
||||||
|
u.packet.header_length = GET_HEADER_LENGTH(control);
|
||||||
|
|
||||||
if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
|
if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
|
||||||
header_length = u.packet.header_length;
|
header_length = u.packet.header_length;
|
||||||
|
|
|
@ -99,6 +99,7 @@ fw_unit(struct device *dev)
|
||||||
#define CSR_DEPENDENT_INFO 0x14
|
#define CSR_DEPENDENT_INFO 0x14
|
||||||
#define CSR_MODEL 0x17
|
#define CSR_MODEL 0x17
|
||||||
#define CSR_INSTANCE 0x18
|
#define CSR_INSTANCE 0x18
|
||||||
|
#define CSR_DIRECTORY_ID 0x20
|
||||||
|
|
||||||
#define SBP2_COMMAND_SET_SPECIFIER 0x38
|
#define SBP2_COMMAND_SET_SPECIFIER 0x38
|
||||||
#define SBP2_COMMAND_SET 0x39
|
#define SBP2_COMMAND_SET 0x39
|
||||||
|
|
|
@ -417,12 +417,21 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
|
||||||
ctx->current_buffer = ab.next;
|
ctx->current_buffer = ab.next;
|
||||||
ctx->pointer = ctx->current_buffer->data;
|
ctx->pointer = ctx->current_buffer->data;
|
||||||
|
|
||||||
reg_write(ctx->ohci, COMMAND_PTR(ctx->regs),
|
return 0;
|
||||||
le32_to_cpu(ab.descriptor.branch_address));
|
}
|
||||||
|
|
||||||
|
static void ar_context_run(struct ar_context *ctx)
|
||||||
|
{
|
||||||
|
struct ar_buffer *ab = ctx->current_buffer;
|
||||||
|
dma_addr_t ab_bus;
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
|
offset = offsetof(struct ar_buffer, data);
|
||||||
|
ab_bus = ab->descriptor.data_address - offset;
|
||||||
|
|
||||||
|
reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1);
|
||||||
reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
|
reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
|
||||||
flush_writes(ctx->ohci);
|
flush_writes(ctx->ohci);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void context_tasklet(unsigned long data)
|
static void context_tasklet(unsigned long data)
|
||||||
|
@ -1039,11 +1048,78 @@ static irqreturn_t irq_handler(int irq, void *data)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int software_reset(struct fw_ohci *ohci)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
|
||||||
|
|
||||||
|
for (i = 0; i < OHCI_LOOP_COUNT; i++) {
|
||||||
|
if ((reg_read(ohci, OHCI1394_HCControlSet) &
|
||||||
|
OHCI1394_HCControl_softReset) == 0)
|
||||||
|
return 0;
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
|
static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
|
||||||
{
|
{
|
||||||
struct fw_ohci *ohci = fw_ohci(card);
|
struct fw_ohci *ohci = fw_ohci(card);
|
||||||
struct pci_dev *dev = to_pci_dev(card->device);
|
struct pci_dev *dev = to_pci_dev(card->device);
|
||||||
|
|
||||||
|
if (software_reset(ohci)) {
|
||||||
|
fw_error("Failed to reset ohci card.\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now enable LPS, which we need in order to start accessing
|
||||||
|
* most of the registers. In fact, on some cards (ALI M5251),
|
||||||
|
* accessing registers in the SClk domain without LPS enabled
|
||||||
|
* will lock up the machine. Wait 50msec to make sure we have
|
||||||
|
* full link enabled.
|
||||||
|
*/
|
||||||
|
reg_write(ohci, OHCI1394_HCControlSet,
|
||||||
|
OHCI1394_HCControl_LPS |
|
||||||
|
OHCI1394_HCControl_postedWriteEnable);
|
||||||
|
flush_writes(ohci);
|
||||||
|
msleep(50);
|
||||||
|
|
||||||
|
reg_write(ohci, OHCI1394_HCControlClear,
|
||||||
|
OHCI1394_HCControl_noByteSwapData);
|
||||||
|
|
||||||
|
reg_write(ohci, OHCI1394_LinkControlSet,
|
||||||
|
OHCI1394_LinkControl_rcvSelfID |
|
||||||
|
OHCI1394_LinkControl_cycleTimerEnable |
|
||||||
|
OHCI1394_LinkControl_cycleMaster);
|
||||||
|
|
||||||
|
reg_write(ohci, OHCI1394_ATRetries,
|
||||||
|
OHCI1394_MAX_AT_REQ_RETRIES |
|
||||||
|
(OHCI1394_MAX_AT_RESP_RETRIES << 4) |
|
||||||
|
(OHCI1394_MAX_PHYS_RESP_RETRIES << 8));
|
||||||
|
|
||||||
|
ar_context_run(&ohci->ar_request_ctx);
|
||||||
|
ar_context_run(&ohci->ar_response_ctx);
|
||||||
|
|
||||||
|
reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
|
||||||
|
reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
|
||||||
|
reg_write(ohci, OHCI1394_IntEventClear, ~0);
|
||||||
|
reg_write(ohci, OHCI1394_IntMaskClear, ~0);
|
||||||
|
reg_write(ohci, OHCI1394_IntMaskSet,
|
||||||
|
OHCI1394_selfIDComplete |
|
||||||
|
OHCI1394_RQPkt | OHCI1394_RSPkt |
|
||||||
|
OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
|
||||||
|
OHCI1394_isochRx | OHCI1394_isochTx |
|
||||||
|
OHCI1394_masterIntEnable |
|
||||||
|
OHCI1394_cycle64Seconds);
|
||||||
|
|
||||||
|
/* Activate link_on bit and contender bit in our self ID packets.*/
|
||||||
|
if (ohci_update_phy_reg(card, 4, 0,
|
||||||
|
PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the link is not yet enabled, the atomic config rom
|
* When the link is not yet enabled, the atomic config rom
|
||||||
* update mechanism described below in ohci_set_config_rom()
|
* update mechanism described below in ohci_set_config_rom()
|
||||||
|
@ -1701,22 +1777,6 @@ static const struct fw_card_driver ohci_driver = {
|
||||||
.stop_iso = ohci_stop_iso,
|
.stop_iso = ohci_stop_iso,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int software_reset(struct fw_ohci *ohci)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
|
|
||||||
|
|
||||||
for (i = 0; i < OHCI_LOOP_COUNT; i++) {
|
|
||||||
if ((reg_read(ohci, OHCI1394_HCControlSet) &
|
|
||||||
OHCI1394_HCControl_softReset) == 0)
|
|
||||||
return 0;
|
|
||||||
msleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __devinit
|
static int __devinit
|
||||||
pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
|
@ -1762,33 +1822,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
goto fail_iomem;
|
goto fail_iomem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (software_reset(ohci)) {
|
|
||||||
fw_error("Failed to reset ohci card.\n");
|
|
||||||
err = -EBUSY;
|
|
||||||
goto fail_registers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now enable LPS, which we need in order to start accessing
|
|
||||||
* most of the registers. In fact, on some cards (ALI M5251),
|
|
||||||
* accessing registers in the SClk domain without LPS enabled
|
|
||||||
* will lock up the machine. Wait 50msec to make sure we have
|
|
||||||
* full link enabled.
|
|
||||||
*/
|
|
||||||
reg_write(ohci, OHCI1394_HCControlSet,
|
|
||||||
OHCI1394_HCControl_LPS |
|
|
||||||
OHCI1394_HCControl_postedWriteEnable);
|
|
||||||
flush_writes(ohci);
|
|
||||||
msleep(50);
|
|
||||||
|
|
||||||
reg_write(ohci, OHCI1394_HCControlClear,
|
|
||||||
OHCI1394_HCControl_noByteSwapData);
|
|
||||||
|
|
||||||
reg_write(ohci, OHCI1394_LinkControlSet,
|
|
||||||
OHCI1394_LinkControl_rcvSelfID |
|
|
||||||
OHCI1394_LinkControl_cycleTimerEnable |
|
|
||||||
OHCI1394_LinkControl_cycleMaster);
|
|
||||||
|
|
||||||
ar_context_init(&ohci->ar_request_ctx, ohci,
|
ar_context_init(&ohci->ar_request_ctx, ohci,
|
||||||
OHCI1394_AsReqRcvContextControlSet);
|
OHCI1394_AsReqRcvContextControlSet);
|
||||||
|
|
||||||
|
@ -1801,11 +1834,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
context_init(&ohci->at_response_ctx, ohci, AT_BUFFER_SIZE,
|
context_init(&ohci->at_response_ctx, ohci, AT_BUFFER_SIZE,
|
||||||
OHCI1394_AsRspTrContextControlSet, handle_at_packet);
|
OHCI1394_AsRspTrContextControlSet, handle_at_packet);
|
||||||
|
|
||||||
reg_write(ohci, OHCI1394_ATRetries,
|
|
||||||
OHCI1394_MAX_AT_REQ_RETRIES |
|
|
||||||
(OHCI1394_MAX_AT_RESP_RETRIES << 4) |
|
|
||||||
(OHCI1394_MAX_PHYS_RESP_RETRIES << 8));
|
|
||||||
|
|
||||||
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
|
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
|
||||||
ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
|
ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
|
||||||
reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
|
reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
|
||||||
|
@ -1835,18 +1863,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
||||||
goto fail_registers;
|
goto fail_registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
|
|
||||||
reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
|
|
||||||
reg_write(ohci, OHCI1394_IntEventClear, ~0);
|
|
||||||
reg_write(ohci, OHCI1394_IntMaskClear, ~0);
|
|
||||||
reg_write(ohci, OHCI1394_IntMaskSet,
|
|
||||||
OHCI1394_selfIDComplete |
|
|
||||||
OHCI1394_RQPkt | OHCI1394_RSPkt |
|
|
||||||
OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
|
|
||||||
OHCI1394_isochRx | OHCI1394_isochTx |
|
|
||||||
OHCI1394_masterIntEnable |
|
|
||||||
OHCI1394_cycle64Seconds);
|
|
||||||
|
|
||||||
bus_options = reg_read(ohci, OHCI1394_BusOptions);
|
bus_options = reg_read(ohci, OHCI1394_BusOptions);
|
||||||
max_receive = (bus_options >> 12) & 0xf;
|
max_receive = (bus_options >> 12) & 0xf;
|
||||||
link_speed = bus_options & 0x7;
|
link_speed = bus_options & 0x7;
|
||||||
|
@ -1908,6 +1924,45 @@ static void pci_remove(struct pci_dev *dev)
|
||||||
fw_notify("Removed fw-ohci device.\n");
|
fw_notify("Removed fw-ohci device.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct fw_ohci *ohci = pci_get_drvdata(pdev);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
software_reset(ohci);
|
||||||
|
free_irq(pdev->irq, ohci);
|
||||||
|
err = pci_save_state(pdev);
|
||||||
|
if (err) {
|
||||||
|
fw_error("pci_save_state failed with %d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||||
|
if (err) {
|
||||||
|
fw_error("pci_set_power_state failed with %d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_resume(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct fw_ohci *ohci = pci_get_drvdata(pdev);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
pci_set_power_state(pdev, PCI_D0);
|
||||||
|
pci_restore_state(pdev);
|
||||||
|
err = pci_enable_device(pdev);
|
||||||
|
if (err) {
|
||||||
|
fw_error("pci_enable_device failed with %d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ohci_enable(&ohci->card, ohci->config_rom, CONFIG_ROM_SIZE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct pci_device_id pci_table[] = {
|
static struct pci_device_id pci_table[] = {
|
||||||
{ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) },
|
{ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) },
|
||||||
{ }
|
{ }
|
||||||
|
@ -1920,6 +1975,10 @@ static struct pci_driver fw_ohci_pci_driver = {
|
||||||
.id_table = pci_table,
|
.id_table = pci_table,
|
||||||
.probe = pci_probe,
|
.probe = pci_probe,
|
||||||
.remove = pci_remove,
|
.remove = pci_remove,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.resume = pci_resume,
|
||||||
|
.suspend = pci_suspend,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
|
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
|
||||||
|
|
|
@ -1108,6 +1108,58 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format of /sys/bus/scsi/devices/.../ieee1394_id:
|
||||||
|
* u64 EUI-64 : u24 directory_ID : u16 LUN (all printed in hexadecimal)
|
||||||
|
*
|
||||||
|
* This is the concatenation of target port identifier and logical unit
|
||||||
|
* identifier as per SAM-2...SAM-4 annex A.
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct scsi_device *sdev = to_scsi_device(dev);
|
||||||
|
struct sbp2_device *sd;
|
||||||
|
struct fw_unit *unit;
|
||||||
|
struct fw_device *device;
|
||||||
|
u32 directory_id;
|
||||||
|
struct fw_csr_iterator ci;
|
||||||
|
int key, value, lun;
|
||||||
|
|
||||||
|
if (!sdev)
|
||||||
|
return 0;
|
||||||
|
sd = (struct sbp2_device *)sdev->host->hostdata;
|
||||||
|
unit = sd->unit;
|
||||||
|
device = fw_device(unit->device.parent);
|
||||||
|
|
||||||
|
/* implicit directory ID */
|
||||||
|
directory_id = ((unit->directory - device->config_rom) * 4
|
||||||
|
+ CSR_CONFIG_ROM) & 0xffffff;
|
||||||
|
|
||||||
|
/* explicit directory ID, overrides implicit ID if present */
|
||||||
|
fw_csr_iterator_init(&ci, unit->directory);
|
||||||
|
while (fw_csr_iterator_next(&ci, &key, &value))
|
||||||
|
if (key == CSR_DIRECTORY_ID) {
|
||||||
|
directory_id = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Make this work for multi-lun devices. */
|
||||||
|
lun = 0;
|
||||||
|
|
||||||
|
return sprintf(buf, "%08x%08x:%06x:%04x\n",
|
||||||
|
device->config_rom[3], device->config_rom[4],
|
||||||
|
directory_id, lun);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
|
||||||
|
|
||||||
|
static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
|
||||||
|
&dev_attr_ieee1394_id,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static struct scsi_host_template scsi_driver_template = {
|
static struct scsi_host_template scsi_driver_template = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.name = "SBP-2 IEEE-1394",
|
.name = "SBP-2 IEEE-1394",
|
||||||
|
@ -1121,6 +1173,7 @@ static struct scsi_host_template scsi_driver_template = {
|
||||||
.use_clustering = ENABLE_CLUSTERING,
|
.use_clustering = ENABLE_CLUSTERING,
|
||||||
.cmd_per_lun = 1,
|
.cmd_per_lun = 1,
|
||||||
.can_queue = 1,
|
.can_queue = 1,
|
||||||
|
.sdev_attrs = sbp2_scsi_sysfs_attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
|
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
|
||||||
|
|
|
@ -976,7 +976,8 @@ static struct unit_directory *nodemgr_process_unit_directory
|
||||||
|
|
||||||
ud->ne = ne;
|
ud->ne = ne;
|
||||||
ud->ignore_driver = ignore_drivers;
|
ud->ignore_driver = ignore_drivers;
|
||||||
ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE;
|
ud->address = ud_kv->offset + CSR1212_REGISTER_SPACE_BASE;
|
||||||
|
ud->directory_id = ud->address & 0xffffff;
|
||||||
ud->ud_kv = ud_kv;
|
ud->ud_kv = ud_kv;
|
||||||
ud->id = (*id)++;
|
ud->id = (*id)++;
|
||||||
|
|
||||||
|
@ -1085,6 +1086,10 @@ static struct unit_directory *nodemgr_process_unit_directory
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CSR1212_KV_ID_DIRECTORY_ID:
|
||||||
|
ud->directory_id = kv->value.immediate;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct unit_directory {
|
||||||
struct csr1212_keyval *model_name_kv;
|
struct csr1212_keyval *model_name_kv;
|
||||||
quadlet_t specifier_id;
|
quadlet_t specifier_id;
|
||||||
quadlet_t version;
|
quadlet_t version;
|
||||||
|
quadlet_t directory_id;
|
||||||
|
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,27 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
|
||||||
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
|
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
|
||||||
", or a combination)");
|
", or a combination)");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This influences the format of the sysfs attribute
|
||||||
|
* /sys/bus/scsi/devices/.../ieee1394_id.
|
||||||
|
*
|
||||||
|
* The default format is like in older kernels: %016Lx:%d:%d
|
||||||
|
* It contains the target's EUI-64, a number given to the logical unit by
|
||||||
|
* the ieee1394 driver's nodemgr (starting at 0), and the LUN.
|
||||||
|
*
|
||||||
|
* The long format is: %016Lx:%06x:%04x
|
||||||
|
* It contains the target's EUI-64, the unit directory's directory_ID as per
|
||||||
|
* IEEE 1212 clause 7.7.19, and the LUN. This format comes closest to the
|
||||||
|
* format of SBP(-3) target port and logical unit identifier as per SAM (SCSI
|
||||||
|
* Architecture Model) rev.2 to 4 annex A. Therefore and because it is
|
||||||
|
* independent of the implementation of the ieee1394 nodemgr, the longer format
|
||||||
|
* is recommended for future use.
|
||||||
|
*/
|
||||||
|
static int sbp2_long_sysfs_ieee1394_id;
|
||||||
|
module_param_named(long_ieee1394_id, sbp2_long_sysfs_ieee1394_id, bool, 0644);
|
||||||
|
MODULE_PARM_DESC(long_ieee1394_id, "8+3+2 bytes format of ieee1394_id in sysfs "
|
||||||
|
"(default = backwards-compatible = N, SAM-conforming = Y)");
|
||||||
|
|
||||||
|
|
||||||
#define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args)
|
#define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args)
|
||||||
#define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
|
#define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
|
||||||
|
@ -2100,8 +2121,14 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
|
||||||
if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0]))
|
if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0]))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)lu->ne->guid,
|
if (sbp2_long_sysfs_ieee1394_id)
|
||||||
lu->ud->id, ORB_SET_LUN(lu->lun));
|
return sprintf(buf, "%016Lx:%06x:%04x\n",
|
||||||
|
(unsigned long long)lu->ne->guid,
|
||||||
|
lu->ud->directory_id, ORB_SET_LUN(lu->lun));
|
||||||
|
else
|
||||||
|
return sprintf(buf, "%016Lx:%d:%d\n",
|
||||||
|
(unsigned long long)lu->ne->guid,
|
||||||
|
lu->ud->id, ORB_SET_LUN(lu->lun));
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_AUTHOR("Ben Collins <bcollins@debian.org>");
|
MODULE_AUTHOR("Ben Collins <bcollins@debian.org>");
|
||||||
|
|
|
@ -62,6 +62,8 @@ header-y += fadvise.h
|
||||||
header-y += fd.h
|
header-y += fd.h
|
||||||
header-y += fdreg.h
|
header-y += fdreg.h
|
||||||
header-y += fib_rules.h
|
header-y += fib_rules.h
|
||||||
|
header-y += firewire-cdev.h
|
||||||
|
header-y += firewire-constants.h
|
||||||
header-y += fuse.h
|
header-y += fuse.h
|
||||||
header-y += genetlink.h
|
header-y += genetlink.h
|
||||||
header-y += gen_stats.h
|
header-y += gen_stats.h
|
||||||
|
|
|
@ -198,13 +198,15 @@ struct fw_cdev_create_iso_context {
|
||||||
__u32 handle;
|
__u32 handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v)
|
||||||
|
#define FW_CDEV_ISO_INTERRUPT (1 << 16)
|
||||||
|
#define FW_CDEV_ISO_SKIP (1 << 17)
|
||||||
|
#define FW_CDEV_ISO_TAG(v) ((v) << 18)
|
||||||
|
#define FW_CDEV_ISO_SY(v) ((v) << 20)
|
||||||
|
#define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24)
|
||||||
|
|
||||||
struct fw_cdev_iso_packet {
|
struct fw_cdev_iso_packet {
|
||||||
__u16 payload_length; /* Length of indirect payload. */
|
__u32 control;
|
||||||
__u32 interrupt : 1; /* Generate interrupt on this packet */
|
|
||||||
__u32 skip : 1; /* Set to not send packet at all. */
|
|
||||||
__u32 tag : 2;
|
|
||||||
__u32 sy : 4;
|
|
||||||
__u32 header_length : 8; /* Length of immediate header. */
|
|
||||||
__u32 header[0];
|
__u32 header[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue