crc ^= c << 8; for (i = 0; i < 8; i++)
crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0); return crc;
}
/* * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the * opposite bit ordering.
*/ static u8 ipack_calc_crc1(struct ipack_device *dev)
{
u8 c;
u16 crc; unsignedint i;
crc = 0xffff; for (i = 0; i < dev->id_avail; i++) {
c = (i != 11) ? dev->id[i] : 0;
crc = ipack_crc_byte(crc, c);
}
crc = ~crc; return crc & 0xff;
}
/* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH" * we are dealing with a IndustryPack format 1 device. If we detect * "VITA4 " (16 bit big endian formatted) we are dealing with a
* IndustryPack format 2 device */ if ((ioread8(idmem + 1) == 'I') &&
(ioread8(idmem + 3) == 'P') &&
(ioread8(idmem + 5) == 'A') &&
((ioread8(idmem + 7) == 'C') ||
(ioread8(idmem + 7) == 'H'))) {
dev->id_format = IPACK_ID_VERSION_1;
dev->id_avail = ioread8(idmem + 0x15); if ((dev->id_avail < 0x0c) || (dev->id_avail > 0x40)) {
dev_warn(&dev->dev, "invalid id size");
dev->id_avail = 0x0c;
}
} elseif ((ioread8(idmem + 0) == 'I') &&
(ioread8(idmem + 1) == 'V') &&
(ioread8(idmem + 2) == 'A') &&
(ioread8(idmem + 3) == 'T') &&
(ioread8(idmem + 4) == ' ') &&
(ioread8(idmem + 5) == '4')) {
dev->id_format = IPACK_ID_VERSION_2;
dev->id_avail = ioread16be(idmem + 0x16); if ((dev->id_avail < 0x1a) || (dev->id_avail > 0x40)) {
dev_warn(&dev->dev, "invalid id size");
dev->id_avail = 0x1a;
}
} else {
dev->id_format = IPACK_ID_VERSION_INVALID;
dev->id_avail = 0;
}
if (!dev->id_avail) {
ret = -ENODEV; goto out;
}
/* Obtain the amount of memory required to store a copy of the complete
* ID ROM contents */
dev->id = kmalloc(dev->id_avail, GFP_KERNEL); if (!dev->id) {
ret = -ENOMEM; goto out;
} for (i = 0; i < dev->id_avail; i++) { if (dev->id_format == IPACK_ID_VERSION_1)
dev->id[i] = ioread8(idmem + (i << 1) + 1); else
dev->id[i] = ioread8(idmem + i);
}
/* now we can finally work with the copy */ switch (dev->id_format) { case IPACK_ID_VERSION_1:
ipack_parse_id1(dev); break; case IPACK_ID_VERSION_2:
ipack_parse_id2(dev); break;
}
out:
iounmap(idmem);
return ret;
}
int ipack_device_init(struct ipack_device *dev)
{ int ret;
dev->dev.bus = &ipack_bus_type;
dev->dev.release = ipack_device_release;
dev->dev.parent = dev->bus->parent;
ret = dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); if (ret) return ret;
device_initialize(&dev->dev);
if (dev->bus->ops->set_clockrate(dev, 8))
dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); if (dev->bus->ops->reset_timeout(dev))
dev_warn(&dev->dev, "failed to reset potential timeout.");
ret = ipack_device_read_id(dev); if (ret < 0) {
dev_err(&dev->dev, "error reading device id section.\n"); return ret;
}
/* if the device supports 32 MHz operation, use it. */ if (dev->speed_32mhz) {
ret = dev->bus->ops->set_clockrate(dev, 32); if (ret < 0)
dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
}
return 0;
}
EXPORT_SYMBOL_GPL(ipack_device_init);
int ipack_device_add(struct ipack_device *dev)
{ return device_add(&dev->dev);
}
EXPORT_SYMBOL_GPL(ipack_device_add);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.