aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig4
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acorn/block/fd1772.c2
-rw-r--r--drivers/acorn/block/mfmhd.c13
-rw-r--r--drivers/ata/ahci.c159
-rw-r--r--drivers/ata/ata_generic.c4
-rw-r--r--drivers/ata/ata_piix.c35
-rw-r--r--drivers/ata/libata-acpi.c914
-rw-r--r--drivers/ata/libata-core.c105
-rw-r--r--drivers/ata/libata-eh.c11
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/libata.h18
-rw-r--r--drivers/ata/pata_ali.c22
-rw-r--r--drivers/ata/pata_amd.c38
-rw-r--r--drivers/ata/pata_artop.c6
-rw-r--r--drivers/ata/pata_atiixp.c3
-rw-r--r--drivers/ata/pata_cmd640.c2
-rw-r--r--drivers/ata/pata_cmd64x.c12
-rw-r--r--drivers/ata/pata_cs5520.c4
-rw-r--r--drivers/ata/pata_cs5530.c8
-rw-r--r--drivers/ata/pata_cs5535.c4
-rw-r--r--drivers/ata/pata_cypress.c2
-rw-r--r--drivers/ata/pata_efar.c2
-rw-r--r--drivers/ata/pata_hpt366.c4
-rw-r--r--drivers/ata/pata_hpt37x.c20
-rw-r--r--drivers/ata/pata_hpt3x2n.c4
-rw-r--r--drivers/ata/pata_hpt3x3.c2
-rw-r--r--drivers/ata/pata_icside.c2
-rw-r--r--drivers/ata/pata_it8213.c4
-rw-r--r--drivers/ata/pata_it821x.c6
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c76
-rw-r--r--drivers/ata/pata_jmicron.c4
-rw-r--r--drivers/ata/pata_marvell.c8
-rw-r--r--drivers/ata/pata_netcell.c4
-rw-r--r--drivers/ata/pata_ns87410.c2
-rw-r--r--drivers/ata/pata_oldpiix.c2
-rw-r--r--drivers/ata/pata_opti.c2
-rw-r--r--drivers/ata/pata_optidma.c4
-rw-r--r--drivers/ata/pata_pdc202xx_old.c6
-rw-r--r--drivers/ata/pata_platform.c6
-rw-r--r--drivers/ata/pata_radisys.c2
-rw-r--r--drivers/ata/pata_rz1000.c2
-rw-r--r--drivers/ata/pata_sc1200.c6
-rw-r--r--drivers/ata/pata_serverworks.c12
-rw-r--r--drivers/ata/pata_sil680.c21
-rw-r--r--drivers/ata/pata_sis.c14
-rw-r--r--drivers/ata/pata_sl82c105.c4
-rw-r--r--drivers/ata/pata_triflex.c2
-rw-r--r--drivers/ata/pata_via.c8
-rw-r--r--drivers/ata/pdc_adma.c20
-rw-r--r--drivers/ata/sata_inic162x.c6
-rw-r--r--drivers/ata/sata_mv.c31
-rw-r--r--drivers/ata/sata_promise.c78
-rw-r--r--drivers/ata/sata_qstor.c2
-rw-r--r--drivers/ata/sata_sil.c13
-rw-r--r--drivers/ata/sata_sil24.c8
-rw-r--r--drivers/ata/sata_sis.c2
-rw-r--r--drivers/ata/sata_svw.c15
-rw-r--r--drivers/ata/sata_sx4.c168
-rw-r--r--drivers/ata/sata_uli.c2
-rw-r--r--drivers/ata/sata_via.c10
-rw-r--r--drivers/ata/sata_vsc.c2
-rw-r--r--drivers/block/Kconfig44
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/acsi.c1825
-rw-r--r--drivers/block/amiflop.c2
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/loop.c64
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/cdrom/Kconfig213
-rw-r--r--drivers/cdrom/Makefile10
-rw-r--r--drivers/cdrom/aztcd.c2492
-rw-r--r--drivers/cdrom/aztcd.h162
-rw-r--r--drivers/cdrom/cdrom.c216
-rw-r--r--drivers/cdrom/cdu31a.c3251
-rw-r--r--drivers/cdrom/cdu31a.h411
-rw-r--r--drivers/cdrom/cm206.c1594
-rw-r--r--drivers/cdrom/cm206.h171
-rw-r--r--drivers/cdrom/gscd.c1029
-rw-r--r--drivers/cdrom/gscd.h108
-rw-r--r--drivers/cdrom/isp16.c374
-rw-r--r--drivers/cdrom/isp16.h72
-rw-r--r--drivers/cdrom/mcdx.c1943
-rw-r--r--drivers/cdrom/mcdx.h185
-rw-r--r--drivers/cdrom/optcd.c2105
-rw-r--r--drivers/cdrom/optcd.h52
-rw-r--r--drivers/cdrom/sbpcd.c5966
-rw-r--r--drivers/cdrom/sbpcd.h839
-rw-r--r--drivers/cdrom/sjcd.c1815
-rw-r--r--drivers/cdrom/sjcd.h181
-rw-r--r--drivers/cdrom/sonycd535.c1689
-rw-r--r--drivers/cdrom/sonycd535.h183
-rw-r--r--drivers/char/keyboard.c4
-rw-r--r--drivers/char/mem.c9
-rw-r--r--drivers/ide/legacy/hd.c3
-rw-r--r--drivers/input/evdev.c84
-rw-r--r--drivers/input/input.c136
-rw-r--r--drivers/input/joydev.c84
-rw-r--r--drivers/input/joystick/Kconfig7
-rw-r--r--drivers/input/joystick/grip_mp.c4
-rw-r--r--drivers/input/joystick/xpad.c281
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/keyboard/pxa27x_keyboard.c2
-rw-r--r--drivers/input/misc/Kconfig6
-rw-r--r--drivers/input/misc/wistron_btns.c359
-rw-r--r--drivers/input/mouse/Kconfig16
-rw-r--r--drivers/input/mouse/Makefile1
-rw-r--r--drivers/input/mouse/gpio_mouse.c196
-rw-r--r--drivers/input/mouse/psmouse-base.c29
-rw-r--r--drivers/input/mouse/psmouse.h1
-rw-r--r--drivers/input/mousedev.c242
-rw-r--r--drivers/input/serio/serio_raw.c2
-rw-r--r--drivers/input/tablet/aiptek.c991
-rw-r--r--drivers/input/tablet/wacom.h8
-rw-r--r--drivers/input/tablet/wacom_sys.c6
-rw-r--r--drivers/input/tablet/wacom_wac.c47
-rw-r--r--drivers/input/tablet/wacom_wac.h1
-rw-r--r--drivers/input/touchscreen/Kconfig6
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c33
-rw-r--r--drivers/input/tsdev.c90
-rw-r--r--drivers/misc/eeprom_93cx6.c6
-rw-r--r--drivers/mmc/card/Kconfig18
-rw-r--r--drivers/mmc/card/block.c7
-rw-r--r--drivers/mmc/card/queue.c191
-rw-r--r--drivers/mmc/card/queue.h7
-rw-r--r--drivers/mmc/core/Makefile3
-rw-r--r--drivers/mmc/core/bus.c253
-rw-r--r--drivers/mmc/core/bus.h22
-rw-r--r--drivers/mmc/core/core.c147
-rw-r--r--drivers/mmc/core/core.h8
-rw-r--r--drivers/mmc/core/host.c156
-rw-r--r--drivers/mmc/core/host.h18
-rw-r--r--drivers/mmc/core/mmc.c65
-rw-r--r--drivers/mmc/core/sd.c63
-rw-r--r--drivers/mmc/core/sysfs.c347
-rw-r--r--drivers/mmc/core/sysfs.h19
-rw-r--r--drivers/mmc/host/at91_mci.c217
-rw-r--r--drivers/mmc/host/sdhci.c10
-rw-r--r--drivers/mtd/devices/docprobe.c2
-rw-r--r--drivers/mtd/maps/Kconfig6
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/lasat.c103
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8390.h11
-rw-r--r--drivers/net/Kconfig118
-rw-r--r--drivers/net/Makefile4
-rw-r--r--drivers/net/atari_pamsnet.c62
-rw-r--r--drivers/net/atl1/atl1_main.c3
-rw-r--r--drivers/net/ax88796.c952
-rw-r--r--drivers/net/bonding/bond_main.c16
-rw-r--r--drivers/net/bonding/bonding.h2
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c5
-rw-r--r--drivers/net/e100.c12
-rw-r--r--drivers/net/ehea/ehea.h8
-rw-r--r--drivers/net/ehea/ehea_main.c23
-rw-r--r--drivers/net/ioc3-eth.c41
-rw-r--r--drivers/net/macmace.c2
-rw-r--r--drivers/net/myri10ge/myri10ge.c3
-rw-r--r--drivers/net/netxen/netxen_nic.h103
-rw-r--r--drivers/net/netxen/netxen_nic_main.c97
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c1
-rw-r--r--drivers/net/phy/marvell.c123
-rw-r--r--drivers/net/ps3_gelic_net.c1576
-rw-r--r--drivers/net/ps3_gelic_net.h239
-rw-r--r--drivers/net/rrunner.c2
-rw-r--r--drivers/net/s2io.c6
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/sk98lin/Makefile87
-rw-r--r--drivers/net/sk98lin/h/lm80.h179
-rw-r--r--drivers/net/sk98lin/h/skaddr.h285
-rw-r--r--drivers/net/sk98lin/h/skcsum.h213
-rw-r--r--drivers/net/sk98lin/h/skdebug.h74
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h188
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h447
-rw-r--r--drivers/net/sk98lin/h/skerror.h55
-rw-r--r--drivers/net/sk98lin/h/skgedrv.h51
-rw-r--r--drivers/net/sk98lin/h/skgehw.h2126
-rw-r--r--drivers/net/sk98lin/h/skgehwt.h48
-rw-r--r--drivers/net/sk98lin/h/skgei2c.h210
-rw-r--r--drivers/net/sk98lin/h/skgeinit.h797
-rw-r--r--drivers/net/sk98lin/h/skgepnm2.h334
-rw-r--r--drivers/net/sk98lin/h/skgepnmi.h962
-rw-r--r--drivers/net/sk98lin/h/skgesirq.h110
-rw-r--r--drivers/net/sk98lin/h/ski2c.h174
-rw-r--r--drivers/net/sk98lin/h/skqueue.h94
-rw-r--r--drivers/net/sk98lin/h/skrlmt.h438
-rw-r--r--drivers/net/sk98lin/h/sktimer.h63
-rw-r--r--drivers/net/sk98lin/h/sktypes.h69
-rw-r--r--drivers/net/sk98lin/h/skversion.h38
-rw-r--r--drivers/net/sk98lin/h/skvpd.h248
-rw-r--r--drivers/net/sk98lin/h/xmac_ii.h1579
-rw-r--r--drivers/net/sk98lin/skaddr.c1788
-rw-r--r--drivers/net/sk98lin/skdim.c742
-rw-r--r--drivers/net/sk98lin/skethtool.c628
-rw-r--r--drivers/net/sk98lin/skge.c5211
-rw-r--r--drivers/net/sk98lin/skgehwt.c171
-rw-r--r--drivers/net/sk98lin/skgeinit.c2005
-rw-r--r--drivers/net/sk98lin/skgemib.c1075
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8210
-rw-r--r--drivers/net/sk98lin/skgesirq.c2229
-rw-r--r--drivers/net/sk98lin/ski2c.c1296
-rw-r--r--drivers/net/sk98lin/sklm80.c141
-rw-r--r--drivers/net/sk98lin/skqueue.c179
-rw-r--r--drivers/net/sk98lin/skrlmt.c3257
-rw-r--r--drivers/net/sk98lin/sktimer.c250
-rw-r--r--drivers/net/sk98lin/skvpd.c1091
-rw-r--r--drivers/net/sk98lin/skxmac2.c4160
-rw-r--r--drivers/net/sky2.c449
-rw-r--r--drivers/net/sky2.h4
-rw-r--r--drivers/net/spider_net.c59
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/net/tc35815.c50
-rw-r--r--drivers/net/tokenring/3c359.c2
-rw-r--r--drivers/net/ucc_geth.c2
-rw-r--r--drivers/net/usb/usbnet.c2
-rw-r--r--drivers/power/Kconfig51
-rw-r--r--drivers/power/Makefile22
-rw-r--r--drivers/power/apm_power.c243
-rw-r--r--drivers/power/ds2760_battery.c470
-rw-r--r--drivers/power/olpc_battery.c352
-rw-r--r--drivers/power/pda_power.c261
-rw-r--r--drivers/power/pmu_battery.c215
-rw-r--r--drivers/power/power_supply.h42
-rw-r--r--drivers/power/power_supply_core.c168
-rw-r--r--drivers/power/power_supply_leds.c176
-rw-r--r--drivers/power/power_supply_sysfs.c299
-rw-r--r--drivers/s390/block/dasd_proc.c4
-rw-r--r--drivers/s390/char/sclp.h12
-rw-r--r--drivers/s390/char/sclp_chp.c4
-rw-r--r--drivers/s390/char/sclp_info.c117
-rw-r--r--drivers/s390/char/vmcp.c13
-rw-r--r--drivers/s390/char/vmlogrdr.c4
-rw-r--r--drivers/s390/char/zcore.c2
-rw-r--r--drivers/s390/cio/device_id.c22
-rw-r--r--drivers/s390/crypto/ap_bus.c98
-rw-r--r--drivers/s390/crypto/ap_bus.h11
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c40
-rw-r--r--drivers/tc/zs.c6
-rw-r--r--drivers/w1/slaves/Kconfig13
-rw-r--r--drivers/w1/slaves/Makefile1
-rw-r--r--drivers/w1/slaves/w1_ds2760.c213
-rw-r--r--drivers/w1/slaves/w1_ds2760.h50
-rw-r--r--drivers/w1/w1_family.h1
247 files changed, 10110 insertions, 71445 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 050323fd79e9..7916f4b86d23 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -24,8 +24,6 @@ source "drivers/scsi/Kconfig"
source "drivers/ata/Kconfig"
-source "drivers/cdrom/Kconfig"
-
source "drivers/md/Kconfig"
source "drivers/message/fusion/Kconfig"
@@ -54,6 +52,8 @@ source "drivers/spi/Kconfig"
source "drivers/w1/Kconfig"
+source "drivers/power/Kconfig"
+
source "drivers/hwmon/Kconfig"
source "drivers/mfd/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index adad2f3d438a..503d82569449 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_I2O) += message/
obj-$(CONFIG_RTC_LIB) += rtc/
obj-y += i2c/
obj-$(CONFIG_W1) += w1/
+obj-$(CONFIG_POWER_SUPPLY) += power/
obj-$(CONFIG_HWMON) += hwmon/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index 674bf81c6e66..423ed08fb6f7 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -1246,7 +1246,7 @@ repeat:
del_timer(&motor_off_timer);
ReqCnt = 0;
- ReqCmd = CURRENT->cmd;
+ ReqCmd = rq_data_dir(CURRENT);
ReqBlock = CURRENT->sector;
ReqBuffer = CURRENT->buffer;
setup_req_params(drive);
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 689a4c3542ba..d85520f78e68 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -439,7 +439,7 @@ static void mfm_rw_intr(void)
a choice of command end or some data which is ready to be collected */
/* I think we have to transfer data while the interrupt line is on and its
not any other type of interrupt */
- if (CURRENT->cmd == WRITE) {
+ if (rq_data_dir(CURRENT) == WRITE) {
extern void hdc63463_writedma(void);
if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) {
printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n");
@@ -799,7 +799,7 @@ static void issue_request(unsigned int block, unsigned int nsect,
raw_cmd.head = start_head;
raw_cmd.cylinder = track / p->heads;
raw_cmd.cmdtype = CURRENT->cmd;
- raw_cmd.cmdcode = CURRENT->cmd == WRITE ? CMD_WD : CMD_RD;
+ raw_cmd.cmdcode = rq_data_dir(CURRENT) == WRITE ? CMD_WD : CMD_RD;
raw_cmd.cmddata[0] = dev + 1; /* DAG: +1 to get US */
raw_cmd.cmddata[1] = raw_cmd.head;
raw_cmd.cmddata[2] = raw_cmd.cylinder >> 8;
@@ -830,7 +830,7 @@ static void issue_request(unsigned int block, unsigned int nsect,
hdc63463_dataleft = nsect * 256; /* Better way? */
DBG("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n",
- raw_cmd.dev + 'a', (CURRENT->cmd == READ) ? "read" : "writ",
+ raw_cmd.dev + 'a', rq_data_dir(CURRENT) == READ ? "read" : "writ",
raw_cmd.cylinder,
raw_cmd.head,
raw_cmd.sector, nsect, (unsigned long) Copy_buffer, CURRENT);
@@ -917,13 +917,6 @@ static void mfm_request(void)
DBG("mfm_request: block after offset=%d\n", block);
- if (CURRENT->cmd != READ && CURRENT->cmd != WRITE) {
- printk("unknown mfm-command %d\n", CURRENT->cmd);
- end_request(CURRENT, 0);
- Busy = 0;
- printk("mfm: continue 4\n");
- continue;
- }
issue_request(block, nsect, CURRENT);
break;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ca5229d24d8e..11e4eb9f304e 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -46,7 +46,7 @@
#include <linux/libata.h>
#define DRV_NAME "ahci"
-#define DRV_VERSION "2.2"
+#define DRV_VERSION "2.3"
enum {
@@ -54,7 +54,7 @@ enum {
AHCI_MAX_PORTS = 32,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
- AHCI_USE_CLUSTERING = 0,
+ AHCI_USE_CLUSTERING = 1,
AHCI_MAX_CMDS = 32,
AHCI_CMD_SZ = 32,
AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ,
@@ -81,6 +81,7 @@ enum {
board_ahci_vt8251 = 2,
board_ahci_ign_iferr = 3,
board_ahci_sb600 = 4,
+ board_ahci_mv = 5,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -171,6 +172,8 @@ enum {
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
AHCI_FLAG_32BIT_ONLY = (1 << 28), /* force 32bit */
+ AHCI_FLAG_MV_PATA = (1 << 29), /* PATA port */
+ AHCI_FLAG_NO_MSI = (1 << 30), /* no PCI MSI */
AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
@@ -228,9 +231,12 @@ static void ahci_thaw(struct ata_port *ap);
static void ahci_error_handler(struct ata_port *ap);
static void ahci_vt8251_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
+static int ahci_port_resume(struct ata_port *ap);
+static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
+static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
+ u32 opts);
#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
-static int ahci_port_resume(struct ata_port *ap);
static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int ahci_pci_device_resume(struct pci_dev *pdev);
#endif
@@ -327,14 +333,14 @@ static const struct ata_port_info ahci_port_info[] = {
{
.flags = AHCI_FLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_pi */
{
.flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_vt8251 */
@@ -342,14 +348,14 @@ static const struct ata_port_info ahci_port_info[] = {
.flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
AHCI_FLAG_NO_NCQ,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &ahci_vt8251_ops,
},
/* board_ahci_ign_iferr */
{
.flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* board_ahci_sb600 */
@@ -358,7 +364,19 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_FLAG_IGN_SERR_INTERNAL |
AHCI_FLAG_32BIT_ONLY,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
+ /* board_ahci_mv */
+ {
+ .sht = &ahci_sht,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI |
+ AHCI_FLAG_NO_NCQ | AHCI_FLAG_NO_MSI |
+ AHCI_FLAG_MV_PATA,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
};
@@ -456,6 +474,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
+ /* Marvell */
+ { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
+
/* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
@@ -481,11 +502,17 @@ static inline int ahci_nr_ports(u32 cap)
return (cap & 0x1f) + 1;
}
-static inline void __iomem *ahci_port_base(struct ata_port *ap)
+static inline void __iomem *__ahci_port_base(struct ata_host *host,
+ unsigned int port_no)
{
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+
+ return mmio + 0x100 + (port_no * 0x80);
+}
- return mmio + 0x100 + (ap->port_no * 0x80);
+static inline void __iomem *ahci_port_base(struct ata_port *ap)
+{
+ return __ahci_port_base(ap->host, ap->port_no);
}
/**
@@ -535,6 +562,20 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
hpriv->saved_port_map = port_map;
}
+ /*
+ * Temporary Marvell 6145 hack: PATA port presence
+ * is asserted through the standard AHCI port
+ * presence register, as bit 4 (counting from 0)
+ */
+ if (pi->flags & AHCI_FLAG_MV_PATA) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "MV_AHCI HACK: port_map %x -> %x\n",
+ hpriv->port_map,
+ hpriv->port_map & 0xf);
+
+ port_map &= 0xf;
+ }
+
/* cross check port_map and cap.n_ports */
if (pi->flags & AHCI_FLAG_HONOR_PI) {
u32 tmp_port_map = port_map;
@@ -740,7 +781,7 @@ static void ahci_power_down(struct ata_port *ap)
}
#endif
-static void ahci_init_port(struct ata_port *ap)
+static void ahci_start_port(struct ata_port *ap)
{
/* enable FIS reception */
ahci_start_fis_rx(ap);
@@ -814,39 +855,62 @@ static int ahci_reset_controller(struct ata_host *host)
return 0;
}
+static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap,
+ int port_no, void __iomem *mmio,
+ void __iomem *port_mmio)
+{
+ const char *emsg = NULL;
+ int rc;
+ u32 tmp;
+
+ /* make sure port is not active */
+ rc = ahci_deinit_port(ap, &emsg);
+ if (rc)
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "%s (%d)\n", emsg, rc);
+
+ /* clear SError */
+ tmp = readl(port_mmio + PORT_SCR_ERR);
+ VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
+ writel(tmp, port_mmio + PORT_SCR_ERR);
+
+ /* clear port IRQ */
+ tmp = readl(port_mmio + PORT_IRQ_STAT);
+ VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
+ if (tmp)
+ writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+ writel(1 << port_no, mmio + HOST_IRQ_STAT);
+}
+
static void ahci_init_controller(struct ata_host *host)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
- int i, rc;
+ int i;
+ void __iomem *port_mmio;
u32 tmp;
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- void __iomem *port_mmio = ahci_port_base(ap);
- const char *emsg = NULL;
-
- if (ata_port_is_dummy(ap))
- continue;
-
- /* make sure port is not active */
- rc = ahci_deinit_port(ap, &emsg);
- if (rc)
- dev_printk(KERN_WARNING, &pdev->dev,
- "%s (%d)\n", emsg, rc);
+ if (host->ports[0]->flags & AHCI_FLAG_MV_PATA) {
+ port_mmio = __ahci_port_base(host, 4);
- /* clear SError */
- tmp = readl(port_mmio + PORT_SCR_ERR);
- VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
- writel(tmp, port_mmio + PORT_SCR_ERR);
+ writel(0, port_mmio + PORT_IRQ_MASK);
/* clear port IRQ */
tmp = readl(port_mmio + PORT_IRQ_STAT);
VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
if (tmp)
writel(tmp, port_mmio + PORT_IRQ_STAT);
+ }
- writel(1 << i, mmio + HOST_IRQ_STAT);
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ port_mmio = ahci_port_base(ap);
+ if (ata_port_is_dummy(ap))
+ continue;
+
+ ahci_port_init(pdev, ap, i, mmio, port_mmio);
}
tmp = readl(mmio + HOST_CTL);
@@ -1232,7 +1296,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
ata_port_abort(ap);
}
-static void ahci_host_intr(struct ata_port *ap)
+static void ahci_port_intr(struct ata_port *ap)
{
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
struct ata_eh_info *ehi = &ap->eh_info;
@@ -1358,7 +1422,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
ap = host->ports[i];
if (ap) {
- ahci_host_intr(ap);
+ ahci_port_intr(ap);
VPRINTK("port %u\n", i);
} else {
VPRINTK("port %u (no irq)\n", i);
@@ -1466,7 +1530,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
ahci_power_down(ap);
else {
ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
- ahci_init_port(ap);
+ ahci_start_port(ap);
}
return rc;
@@ -1475,7 +1539,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
static int ahci_port_resume(struct ata_port *ap)
{
ahci_power_up(ap);
- ahci_init_port(ap);
+ ahci_start_port(ap);
return 0;
}
@@ -1573,13 +1637,8 @@ static int ahci_port_start(struct ata_port *ap)
ap->private_data = pp;
- /* power up port */
- ahci_power_up(ap);
-
- /* initialize port */
- ahci_init_port(ap);
-
- return 0;
+ /* engage engines, captain */
+ return ahci_port_resume(ap);
}
static void ahci_port_stop(struct ata_port *ap)
@@ -1724,7 +1783,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- if (pci_enable_msi(pdev))
+ if ((pi.flags & AHCI_FLAG_NO_MSI) || pci_enable_msi(pdev))
pci_intx(pdev, 1);
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
@@ -1745,14 +1804,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
host->private_data = hpriv;
for (i = 0; i < host->n_ports; i++) {
- if (hpriv->port_map & (1 << i)) {
- struct ata_port *ap = host->ports[i];
- void __iomem *port_mmio = ahci_port_base(ap);
+ struct ata_port *ap = host->ports[i];
+ void __iomem *port_mmio = ahci_port_base(ap);
+ /* standard SATA port setup */
+ if (hpriv->port_map & (1 << i)) {
ap->ioaddr.cmd_addr = port_mmio;
ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
- } else
- host->ports[i]->ops = &ata_dummy_port_ops;
+ }
+
+ /* disabled/not-implemented port */
+ else
+ ap->ops = &ata_dummy_port_ops;
}
/* initialize adapter */
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 4c6e95c95e4a..430fcf4f9ef3 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -143,10 +143,10 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
u16 command;
static const struct ata_port_info info = {
.sht = &generic_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &generic_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 9c07b88631be..6a3bfef58e13 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -200,6 +200,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* ICH7/7-R (i945, i975) UDMA 100*/
{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+ /* ICH8 Mobile PATA Controller */
+ { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* NOTE: The following PCI ids must be kept in sync with the
* list in drivers/pci/quirks.c.
@@ -495,7 +497,7 @@ static struct ata_port_info piix_port_info[] = {
.flags = PIIX_SATA_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -505,7 +507,7 @@ static struct ata_port_info piix_port_info[] = {
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -516,7 +518,7 @@ static struct ata_port_info piix_port_info[] = {
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -527,7 +529,7 @@ static struct ata_port_info piix_port_info[] = {
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -538,7 +540,7 @@ static struct ata_port_info piix_port_info[] = {
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -685,8 +687,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
if (adev->class == ATA_DEV_ATA)
control |= 4; /* PPE enable */
+ /* PIO configuration clears DTE unconditionally. It will be
+ * programmed in set_dmamode which is guaranteed to be called
+ * after set_piomode if any DMA mode is available.
+ */
pci_read_config_word(dev, master_port, &master_data);
if (is_slave) {
+ /* clear TIME1|IE1|PPE1|DTE1 */
+ master_data &= 0xff0f;
/* Enable SITRE (seperate slave timing register) */
master_data |= 0x4000;
/* enable PPE1, IE1 and TIME1 as needed */
@@ -694,12 +702,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
pci_read_config_byte(dev, slave_port, &slave_data);
slave_data &= (ap->port_no ? 0x0f : 0xf0);
/* Load the timing nibble for this slave */
- slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1])
+ << (ap->port_no ? 4 : 0);
} else {
- /* Master keeps the bits in a different format */
- master_data &= 0xccf8;
+ /* clear ISP|RCT|TIME0|IE0|PPE0|DTE0 */
+ master_data &= 0xccf0;
/* Enable PPE, IE and TIME as appropriate */
master_data |= control;
+ /* load ISP and RCT */
master_data |=
(timings[pio][0] << 12) |
(timings[pio][1] << 8);
@@ -816,7 +826,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */
master_data |= control << 4;
pci_read_config_byte(dev, 0x44, &slave_data);
- slave_data &= (0x0F + 0xE1 * ap->port_no);
+ slave_data &= (ap->port_no ? 0x0f : 0xf0);
/* Load the matching timing */
slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
pci_write_config_byte(dev, 0x44, slave_data);
@@ -828,8 +838,11 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
(timings[pio][0] << 12) |
(timings[pio][1] << 8);
}
- udma_enable &= ~(1 << devid);
- pci_write_config_word(dev, master_port, master_data);
+
+ if (ap->udma_mask) {
+ udma_enable &= ~(1 << devid);
+ pci_write_config_word(dev, master_port, master_data);
+ }
}
/* Don't scribble on 0x48 if the controller does not support UDMA */
if (ap->udma_mask)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 02236739b40f..c059f78ad944 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -24,15 +24,13 @@
#include <acpi/acmacros.h>
#include <acpi/actypes.h>
-#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff)
-#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */
#define NO_PORT_MULT 0xffff
-#define SATA_ADR_RSVD 0xffffffff
+#define SATA_ADR(root,pmp) (((root) << 16) | (pmp))
#define REGS_PER_GTF 7
-struct taskfile_array {
- u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
-};
+struct ata_acpi_gtf {
+ u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
+} __packed;
/*
* Helper - belongs in the PCI layer somewhere eventually
@@ -42,237 +40,173 @@ static int is_pci_dev(struct device *dev)
return (dev->bus == &pci_bus_type);
}
+static void ata_acpi_associate_sata_port(struct ata_port *ap)
+{
+ acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
+
+ ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr);
+}
+
+static void ata_acpi_associate_ide_port(struct ata_port *ap)
+{
+ int max_devices, i;
+
+ ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
+ if (!ap->acpi_handle)
+ return;
+
+ max_devices = 1;
+ if (ap->flags & ATA_FLAG_SLAVE_POSS)
+ max_devices++;
+
+ for (i = 0; i < max_devices; i++) {
+ struct ata_device *dev = &ap->device[i];
+
+ dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
+ }
+}
+
/**
- * sata_get_dev_handle - finds acpi_handle and PCI device.function
- * @dev: device to locate
- * @handle: returned acpi_handle for @dev
- * @pcidevfn: return PCI device.func for @dev
+ * ata_acpi_associate - associate ATA host with ACPI objects
+ * @host: target ATA host
+ *
+ * Look up ACPI objects associated with @host and initialize
+ * acpi_handle fields of @host, its ports and devices accordingly.
*
- * This function is somewhat SATA-specific. Or at least the
- * PATA & SATA versions of this function are different,
- * so it's not entirely generic code.
+ * LOCKING:
+ * EH context.
*
- * Returns 0 on success, <0 on error.
+ * RETURNS:
+ * 0 on success, -errno on failure.
*/
-static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
- acpi_integer *pcidevfn)
+void ata_acpi_associate(struct ata_host *host)
{
- struct pci_dev *pci_dev;
- acpi_integer addr;
-
- if (!is_pci_dev(dev))
- return -ENODEV;
-
- pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */
- /* Please refer to the ACPI spec for the syntax of _ADR. */
- addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
- *pcidevfn = addr;
- *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
- if (!*handle)
- return -ENODEV;
- return 0;
+ int i;
+
+ if (!is_pci_dev(host->dev) || libata_noacpi)
+ return;
+
+ host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
+ if (!host->acpi_handle)
+ return;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
+ ata_acpi_associate_sata_port(ap);
+ else
+ ata_acpi_associate_ide_port(ap);
+ }
}
/**
- * pata_get_dev_handle - finds acpi_handle and PCI device.function
- * @dev: device to locate
- * @handle: returned acpi_handle for @dev
- * @pcidevfn: return PCI device.func for @dev
+ * ata_acpi_gtm - execute _GTM
+ * @ap: target ATA port
+ * @gtm: out parameter for _GTM result
+ *
+ * Evaluate _GTM and store the result in @gtm.
*
- * The PATA and SATA versions of this function are different.
+ * LOCKING:
+ * EH context.
*
- * Returns 0 on success, <0 on error.
+ * RETURNS:
+ * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
*/
-static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
- acpi_integer *pcidevfn)
+static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
{
- unsigned int bus, devnum, func;
- acpi_integer addr;
- acpi_handle dev_handle, parent_handle;
- struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
- .pointer = NULL};
+ struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
+ union acpi_object *out_obj;
acpi_status status;
- struct acpi_device_info *dinfo = NULL;
- int ret = -ENODEV;
- struct pci_dev *pdev;
-
- if (!is_pci_dev(dev))
- return -ENODEV;
-
- pdev = to_pci_dev(dev);
-
- bus = pdev->bus->number;
- devnum = PCI_SLOT(pdev->devfn);
- func = PCI_FUNC(pdev->devfn);
-
- dev_handle = DEVICE_ACPI_HANDLE(dev);
- parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
-
- status = acpi_get_object_info(parent_handle, &buffer);
- if (ACPI_FAILURE(status))
- goto err;
-
- dinfo = buffer.pointer;
- if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
- dinfo->address == bus) {
- /* ACPI spec for _ADR for PCI bus: */
- addr = (acpi_integer)(devnum << 16 | func);
- *pcidevfn = addr;
- *handle = dev_handle;
- } else {
- goto err;
+ int rc = 0;
+
+ status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
+
+ rc = -ENOENT;
+ if (status == AE_NOT_FOUND)
+ goto out_free;
+
+ rc = -EINVAL;
+ if (ACPI_FAILURE(status)) {
+ ata_port_printk(ap, KERN_ERR,
+ "ACPI get timing mode failed (AE 0x%x)\n",
+ status);
+ goto out_free;
}
- if (!*handle)
- goto err;
- ret = 0;
-err:
- kfree(dinfo);
- return ret;
-}
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ ata_port_printk(ap, KERN_WARNING,
+ "_GTM returned unexpected object type 0x%x\n",
+ out_obj->type);
-struct walk_info { /* can be trimmed some */
- struct device *dev;
- struct acpi_device *adev;
- acpi_handle handle;
- acpi_integer pcidevfn;
- unsigned int drivenum;
- acpi_handle obj_handle;
- struct ata_port *ataport;
- struct ata_device *atadev;
- u32 sata_adr;
- int status;
- char basepath[ACPI_PATHNAME_MAX];
- int basepath_len;
-};
-
-static acpi_status get_devices(acpi_handle handle,
- u32 level, void *context, void **return_value)
-{
- acpi_status status;
- struct walk_info *winfo = context;
- struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
- char *pathname;
- struct acpi_buffer buffer;
- struct acpi_device_info *dinfo;
-
- status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
- if (status)
- goto ret;
- pathname = namebuf.pointer;
-
- buffer.length = ACPI_ALLOCATE_BUFFER;
- buffer.pointer = NULL;
- status = acpi_get_object_info(handle, &buffer);
- if (ACPI_FAILURE(status))
- goto out2;
-
- dinfo = buffer.pointer;
-
- /* find full device path name for pcidevfn */
- if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
- dinfo->address == winfo->pcidevfn) {
- if (ata_msg_probe(winfo->ataport))
- ata_dev_printk(winfo->atadev, KERN_DEBUG,
- ":%s: matches pcidevfn (0x%llx)\n",
- pathname, winfo->pcidevfn);
- strlcpy(winfo->basepath, pathname,
- sizeof(winfo->basepath));
- winfo->basepath_len = strlen(pathname);
- goto out;
+ goto out_free;
}
- /* if basepath is not yet known, ignore this object */
- if (!winfo->basepath_len)
- goto out;
-
- /* if this object is in scope of basepath, maybe use it */
- if (strncmp(pathname, winfo->basepath,
- winfo->basepath_len) == 0) {
- if (!(dinfo->valid & ACPI_VALID_ADR))
- goto out;
- if (ata_msg_probe(winfo->ataport))
- ata_dev_printk(winfo->atadev, KERN_DEBUG,
- "GOT ONE: (%s) root_port = 0x%llx,"
- " port_num = 0x%llx\n", pathname,
- SATA_ROOT_PORT(dinfo->address),
- SATA_PORT_NUMBER(dinfo->address));
- /* heuristics: */
- if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
- if (ata_msg_probe(winfo->ataport))
- ata_dev_printk(winfo->atadev,
- KERN_DEBUG, "warning: don't"
- " know how to handle SATA port"
- " multiplier\n");
- if (SATA_ROOT_PORT(dinfo->address) ==
- winfo->ataport->port_no &&
- SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
- if (ata_msg_probe(winfo->ataport))
- ata_dev_printk(winfo->atadev,
- KERN_DEBUG,
- "THIS ^^^^^ is the requested"
- " SATA drive (handle = 0x%p)\n",
- handle);
- winfo->sata_adr = dinfo->address;
- winfo->obj_handle = handle;
- }
+ if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
+ ata_port_printk(ap, KERN_ERR,
+ "_GTM returned invalid length %d\n",
+ out_obj->buffer.length);
+ goto out_free;
}
-out:
- kfree(dinfo);
-out2:
- kfree(pathname);
-ret:
- return status;
+ memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm));
+ rc = 0;
+ out_free:
+ kfree(output.pointer);
+ return rc;
}
-/* Get the SATA drive _ADR object. */
-static int get_sata_adr(struct device *dev, acpi_handle handle,
- acpi_integer pcidevfn, unsigned int drive,
- struct ata_port *ap,
- struct ata_device *atadev, u32 *dev_adr)
+/**
+ * ata_acpi_stm - execute _STM
+ * @ap: target ATA port
+ * @stm: timing parameter to _STM
+ *
+ * Evaluate _STM with timing parameter @stm.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
+ */
+static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
{
- acpi_status status;
- struct walk_info *winfo;
- int err = -ENOMEM;
-
- winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
- if (!winfo)
- goto out;
-
- winfo->dev = dev;
- winfo->atadev = atadev;
- winfo->ataport = ap;
- if (acpi_bus_get_device(handle, &winfo->adev) < 0)
- if (ata_msg_probe(ap))
- ata_dev_printk(winfo->atadev, KERN_DEBUG,
- "acpi_bus_get_device failed\n");
- winfo->handle = handle;
- winfo->pcidevfn = pcidevfn;
- winfo->drivenum = drive;
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[3];
- status = acpi_get_devices(NULL, get_devices, winfo, NULL);
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
+ in_params[0].buffer.pointer = (u8 *)stm;
+ /* Buffers for id may need byteswapping ? */
+ in_params[1].type = ACPI_TYPE_BUFFER;
+ in_params[1].buffer.length = 512;
+ in_params[1].buffer.pointer = (u8 *)ap->device[0].id;
+ in_params[2].type = ACPI_TYPE_BUFFER;
+ in_params[2].buffer.length = 512;
+ in_params[2].buffer.pointer = (u8 *)ap->device[1].id;
+
+ input.count = 3;
+ input.pointer = in_params;
+
+ status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
+
+ if (status == AE_NOT_FOUND)
+ return -ENOENT;
if (ACPI_FAILURE(status)) {
- if (ata_msg_probe(ap))
- ata_dev_printk(winfo->atadev, KERN_DEBUG,
- "%s: acpi_get_devices failed\n",
- __FUNCTION__);
- err = -ENODEV;
- } else {
- *dev_adr = winfo->sata_adr;
- atadev->obj_handle = winfo->obj_handle;
- err = 0;
+ ata_port_printk(ap, KERN_ERR,
+ "ACPI set timing mode failed (status=0x%x)\n", status);
+ return -EINVAL;
}
- kfree(winfo);
-out:
- return err;
+ return 0;
}
/**
- * do_drive_get_GTF - get the drive bootup default taskfile settings
+ * ata_dev_get_GTF - get the drive bootup default taskfile settings
* @dev: target ATA device
- * @gtf_length: number of bytes of _GTF data returned at @gtf_address
- * @gtf_address: buffer containing _GTF taskfile arrays
+ * @gtf: output parameter for buffer containing _GTF taskfile arrays
+ * @ptr_to_free: pointer which should be freed
*
* This applies to both PATA and SATA drives.
*
@@ -282,121 +216,41 @@ out:
* The <variable number> is not known in advance, so have ACPI-CA
* allocate the buffer as needed and return it, then free it later.
*
- * The returned @gtf_length and @gtf_address are only valid if the
- * function return value is 0.
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
+ * contain valid data. -errno on other errors.
*/
-static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
- unsigned long *gtf_address, unsigned long *obj_loc)
+static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
+ void **ptr_to_free)
{
struct ata_port *ap = dev->ap;
acpi_status status;
- acpi_handle dev_handle = NULL;
- acpi_handle chan_handle, drive_handle;
- acpi_integer pcidevfn = 0;
- u32 dev_adr;
struct acpi_buffer output;
union acpi_object *out_obj;
- struct device *gdev = ap->host->dev;
- int err = -ENODEV;
+ int rc = 0;
- *gtf_length = 0;
- *gtf_address = 0UL;
- *obj_loc = 0UL;
-
- if (libata_noacpi)
- return 0;
+ /* set up output buffer */
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
__FUNCTION__, ap->port_no);
- if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: "
- "ata_dev_present: %d, PORT_DISABLED: %lu\n",
- __FUNCTION__, ata_dev_enabled(dev),
- ap->flags & ATA_FLAG_DISABLED);
- goto out;
- }
-
- /* Don't continue if device has no _ADR method.
- * _GTF is intended for known motherboard devices. */
- if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
- err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
- if (err < 0) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: pata_get_dev_handle failed (%d)\n",
- __FUNCTION__, err);
- goto out;
- }
- } else {
- err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
- if (err < 0) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: sata_get_dev_handle failed (%d\n",
- __FUNCTION__, err);
- goto out;
- }
- }
-
- /* Get this drive's _ADR info. if not already known. */
- if (!dev->obj_handle) {
- if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
- /* get child objects of dev_handle == channel objects,
- * + _their_ children == drive objects */
- /* channel is ap->port_no */
- chan_handle = acpi_get_child(dev_handle,
- ap->port_no);
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: chan adr=%d: chan_handle=0x%p\n",
- __FUNCTION__, ap->port_no,
- chan_handle);
- if (!chan_handle) {
- err = -ENODEV;
- goto out;
- }
- /* TBD: could also check ACPI object VALID bits */
- drive_handle = acpi_get_child(chan_handle, dev->devno);
- if (!drive_handle) {
- err = -ENODEV;
- goto out;
- }
- dev_adr = dev->devno;
- dev->obj_handle = drive_handle;
- } else { /* for SATA mode */
- dev_adr = SATA_ADR_RSVD;
- err = get_sata_adr(gdev, dev_handle, pcidevfn, 0,
- ap, dev, &dev_adr);
- }
- if (err < 0 || dev_adr == SATA_ADR_RSVD ||
- !dev->obj_handle) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: get_sata/pata_adr failed: "
- "err=%d, dev_adr=%u, obj_handle=0x%p\n",
- __FUNCTION__, err, dev_adr,
- dev->obj_handle);
- goto out;
- }
- }
-
- /* Setting up output buffer */
- output.length = ACPI_ALLOCATE_BUFFER;
- output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
-
/* _GTF has no input parameters */
- err = -EIO;
- status = acpi_evaluate_object(dev->obj_handle, "_GTF",
- NULL, &output);
+ status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
+
if (ACPI_FAILURE(status)) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: Run _GTF error: status = 0x%x\n",
- __FUNCTION__, status);
- goto out;
+ if (status != AE_NOT_FOUND) {
+ ata_dev_printk(dev, KERN_WARNING,
+ "_GTF evaluation failed (AE 0x%x)\n",
+ status);
+ rc = -EIO;
+ }
+ goto out_free;
}
if (!output.length || !output.pointer) {
@@ -406,43 +260,39 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
__FUNCTION__,
(unsigned long long)output.length,
output.pointer);
- kfree(output.pointer);
- goto out;
+ goto out_free;
}
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) {
- kfree(output.pointer);
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
- "error: expected object type of "
- " ACPI_TYPE_BUFFER, got 0x%x\n",
- __FUNCTION__, out_obj->type);
- err = -ENOENT;
- goto out;
+ ata_dev_printk(dev, KERN_WARNING,
+ "_GTF unexpected object type 0x%x\n",
+ out_obj->type);
+ rc = -EINVAL;
+ goto out_free;
}
- if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
- out_obj->buffer.length % REGS_PER_GTF) {
- if (ata_msg_drv(ap))
- ata_dev_printk(dev, KERN_ERR,
- "%s: unexpected GTF length (%d) or addr (0x%p)\n",
- __FUNCTION__, out_obj->buffer.length,
- out_obj->buffer.pointer);
- err = -ENOENT;
- goto out;
+ if (out_obj->buffer.length % REGS_PER_GTF) {
+ ata_dev_printk(dev, KERN_WARNING,
+ "unexpected _GTF length (%d)\n",
+ out_obj->buffer.length);
+ rc = -EINVAL;
+ goto out_free;
}
- *gtf_length = out_obj->buffer.length;
- *gtf_address = (unsigned long)out_obj->buffer.pointer;
- *obj_loc = (unsigned long)out_obj;
+ *ptr_to_free = out_obj;
+ *gtf = (void *)out_obj->buffer.pointer;
+ rc = out_obj->buffer.length / REGS_PER_GTF;
+
if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
- "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
- __FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
- err = 0;
-out:
- return err;
+ "gtf=%p, gtf_count=%d, ptr_to_free=%p\n",
+ __FUNCTION__, *gtf, rc, *ptr_to_free);
+ return rc;
+
+ out_free:
+ kfree(output.pointer);
+ return rc;
}
/**
@@ -461,154 +311,99 @@ out:
* function also waits for idle after writing control and before
* writing the remaining registers.
*
- * LOCKING: TBD:
- * Inherited from caller.
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
*/
-static void taskfile_load_raw(struct ata_device *dev,
- const struct taskfile_array *gtf)
+static int taskfile_load_raw(struct ata_device *dev,
+ const struct ata_acpi_gtf *gtf)
{
struct ata_port *ap = dev->ap;
- struct ata_taskfile tf;
- unsigned int err;
+ struct ata_taskfile tf, rtf;
+ unsigned int err_mask;
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
- "%02x %02x %02x %02x %02x %02x %02x\n",
- __FUNCTION__,
- gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
- gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
-
- if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0)
- && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0)
- && (gtf->tfa[6] == 0))
- return;
+ if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
+ && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
+ && (gtf->tf[6] == 0))
+ return 0;
ata_tf_init(dev, &tf);
/* convert gtf to tf */
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
tf.protocol = ATA_PROT_NODATA;
- tf.feature = gtf->tfa[0]; /* 0x1f1 */
- tf.nsect = gtf->tfa[1]; /* 0x1f2 */
- tf.lbal = gtf->tfa[2]; /* 0x1f3 */
- tf.lbam = gtf->tfa[3]; /* 0x1f4 */
- tf.lbah = gtf->tfa[4]; /* 0x1f5 */
- tf.device = gtf->tfa[5]; /* 0x1f6 */
- tf.command = gtf->tfa[6]; /* 0x1f7 */
-
- err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
- if (err && ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_ERR,
- "%s: ata_exec_internal failed: %u\n",
- __FUNCTION__, err);
-}
-
-/**
- * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
- * @dev: target ATA device
- * @gtf_length: total number of bytes of _GTF taskfiles
- * @gtf_address: location of _GTF taskfile arrays
- *
- * This applies to both PATA and SATA drives.
- *
- * Write {gtf_address, length gtf_length} in groups of
- * REGS_PER_GTF bytes.
- */
-static int do_drive_set_taskfiles(struct ata_device *dev,
- unsigned int gtf_length,
- unsigned long gtf_address)
-{
- struct ata_port *ap = dev->ap;
- int err = -ENODEV;
- int gtf_count = gtf_length / REGS_PER_GTF;
- int ix;
- struct taskfile_array *gtf;
+ tf.feature = gtf->tf[0]; /* 0x1f1 */
+ tf.nsect = gtf->tf[1]; /* 0x1f2 */
+ tf.lbal = gtf->tf[2]; /* 0x1f3 */
+ tf.lbam = gtf->tf[3]; /* 0x1f4 */
+ tf.lbah = gtf->tf[4]; /* 0x1f5 */
+ tf.device = gtf->tf[5]; /* 0x1f6 */
+ tf.command = gtf->tf[6]; /* 0x1f7 */
if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
- __FUNCTION__, ap->port_no);
-
- if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA))
- return 0;
-
- if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
- goto out;
- if (!gtf_count) /* shouldn't be here */
- goto out;
-
- if (gtf_length % REGS_PER_GTF) {
- if (ata_msg_drv(ap))
- ata_dev_printk(dev, KERN_ERR,
- "%s: unexpected GTF length (%d)\n",
- __FUNCTION__, gtf_length);
- goto out;
- }
-
- for (ix = 0; ix < gtf_count; ix++) {
- gtf = (struct taskfile_array *)
- (gtf_address + ix * REGS_PER_GTF);
-
- /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
- taskfile_load_raw(dev, gtf);
+ ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd "
+ "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n",
+ tf.command, tf.feature, tf.nsect,
+ tf.lbal, tf.lbam, tf.lbah, tf.device);
+
+ rtf = tf;
+ err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0);
+ if (err_mask) {
+ ata_dev_printk(dev, KERN_ERR,
+ "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "
+ "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n",
+ tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam,
+ tf.lbah, tf.device, err_mask, rtf.command, rtf.feature);
+ return -EIO;
}
- err = 0;
-out:
- return err;
+ return 0;
}
/**
* ata_acpi_exec_tfs - get then write drive taskfile settings
- * @ap: the ata_port for the drive
+ * @dev: target ATA device
*
- * This applies to both PATA and SATA drives.
+ * Evaluate _GTF and excute returned taskfiles.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * Number of executed taskfiles on success, 0 if _GTF doesn't exist or
+ * doesn't contain valid data. -errno on other errors.
*/
-int ata_acpi_exec_tfs(struct ata_port *ap)
+static int ata_acpi_exec_tfs(struct ata_device *dev)
{
- int ix;
- int ret = 0;
- unsigned int gtf_length;
- unsigned long gtf_address;
- unsigned long obj_loc;
-
- if (libata_noacpi)
- return 0;
- /*
- * TBD - implement PATA support. For now,
- * we should not run GTF on PATA devices since some
- * PATA require execution of GTM/STM before GTF.
- */
- if (!(ap->flags & ATA_FLAG_ACPI_SATA))
- return 0;
-
- for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
- struct ata_device *dev = &ap->device[ix];
-
- if (!ata_dev_enabled(dev))
- continue;
-
- ret = do_drive_get_GTF(dev, &gtf_length, &gtf_address,
- &obj_loc);
- if (ret < 0) {
- if (ata_msg_probe(ap))
- ata_port_printk(ap, KERN_DEBUG,
- "%s: get_GTF error (%d)\n",
- __FUNCTION__, ret);
- break;
- }
-
- ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address);
- kfree((void *)obj_loc);
- if (ret < 0) {
- if (ata_msg_probe(ap))
- ata_port_printk(ap, KERN_DEBUG,
- "%s: set_taskfiles error (%d)\n",
- __FUNCTION__, ret);
- break;
- }
+ struct ata_acpi_gtf *gtf = NULL;
+ void *ptr_to_free = NULL;
+ int gtf_count, i, rc;
+
+ /* get taskfiles */
+ rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
+ if (rc < 0)
+ return rc;
+ gtf_count = rc;
+
+ /* execute them */
+ for (i = 0, rc = 0; i < gtf_count; i++) {
+ int tmp;
+
+ /* ACPI errors are eventually ignored. Run till the
+ * end even after errors.
+ */
+ tmp = taskfile_load_raw(dev, gtf++);
+ if (!rc)
+ rc = tmp;
}
- return ret;
+ kfree(ptr_to_free);
+
+ if (rc == 0)
+ return gtf_count;
+ return rc;
}
/**
@@ -620,62 +415,25 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
* ATM this function never returns a failure. It is an optional
* method and if it fails for whatever reason, we should still
* just keep going.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
*/
-int ata_acpi_push_id(struct ata_device *dev)
+static int ata_acpi_push_id(struct ata_device *dev)
{
struct ata_port *ap = dev->ap;
- acpi_handle handle;
- acpi_integer pcidevfn;
int err;
- struct device *gdev = ap->host->dev;
- u32 dev_adr;
acpi_status status;
struct acpi_object_list input;
union acpi_object in_params[1];
- if (libata_noacpi)
- return 0;
-
if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
__FUNCTION__, dev->devno, ap->port_no);
- /* Don't continue if not a SATA device. */
- if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: Not a SATA device\n", __FUNCTION__);
- goto out;
- }
-
- /* Don't continue if device has no _ADR method.
- * _SDD is intended for known motherboard devices. */
- err = sata_get_dev_handle(gdev, &handle, &pcidevfn);
- if (err < 0) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: sata_get_dev_handle failed (%d\n",
- __FUNCTION__, err);
- goto out;
- }
-
- /* Get this drive's _ADR info, if not already known */
- if (!dev->obj_handle) {
- dev_adr = SATA_ADR_RSVD;
- err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev,
- &dev_adr);
- if (err < 0 || dev_adr == SATA_ADR_RSVD ||
- !dev->obj_handle) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s: get_sata_adr failed: "
- "err=%d, dev_adr=%u, obj_handle=0x%p\n",
- __FUNCTION__, err, dev_adr,
- dev->obj_handle);
- goto out;
- }
- }
-
/* Give the drive Identify data to the drive via the _SDD method */
/* _SDD: set up input parameters */
input.count = 1;
@@ -687,20 +445,150 @@ int ata_acpi_push_id(struct ata_device *dev)
/* It's OK for _SDD to be missing too. */
swap_buf_le16(dev->id, ATA_ID_WORDS);
- status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL);
+ status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
swap_buf_le16(dev->id, ATA_ID_WORDS);
err = ACPI_FAILURE(status) ? -EIO : 0;
- if (err < 0) {
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG,
- "%s _SDD error: status = 0x%x\n",
- __FUNCTION__, status);
+ if (err < 0)
+ ata_dev_printk(dev, KERN_WARNING,
+ "ACPI _SDD failed (AE 0x%x)\n", status);
+
+ return err;
+}
+
+/**
+ * ata_acpi_on_suspend - ATA ACPI hook called on suspend
+ * @ap: target ATA port
+ *
+ * This function is called when @ap is about to be suspended. All
+ * devices are already put to sleep but the port_suspend() callback
+ * hasn't been executed yet. Error return from this function aborts
+ * suspend.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int ata_acpi_on_suspend(struct ata_port *ap)
+{
+ unsigned long flags;
+ int rc;
+
+ /* proceed iff per-port acpi_handle is valid */
+ if (!ap->acpi_handle)
+ return 0;
+ BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
+
+ /* store timing parameters */
+ rc = ata_acpi_gtm(ap, &ap->acpi_gtm);
+
+ spin_lock_irqsave(ap->lock, flags);
+ if (rc == 0)
+ ap->pflags |= ATA_PFLAG_GTM_VALID;
+ else
+ ap->pflags &= ~ATA_PFLAG_GTM_VALID;
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ if (rc == -ENOENT)
+ rc = 0;
+ return rc;
+}
+
+/**
+ * ata_acpi_on_resume - ATA ACPI hook called on resume
+ * @ap: target ATA port
+ *
+ * This function is called when @ap is resumed - right after port
+ * itself is resumed but before any EH action is taken.
+ *
+ * LOCKING:
+ * EH context.
+ */
+void ata_acpi_on_resume(struct ata_port *ap)
+{
+ int i;
+
+ if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
+ BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
+
+ /* restore timing parameters */
+ ata_acpi_stm(ap, &ap->acpi_gtm);
}
- /* always return success */
-out:
- return 0;
+ /* schedule _GTF */
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING;
}
+/**
+ * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
+ * @dev: target ATA device
+ *
+ * This function is called when @dev is about to be configured.
+ * IDENTIFY data might have been modified after this hook is run.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * Positive number if IDENTIFY data needs to be refreshed, 0 if not,
+ * -errno on failure.
+ */
+int ata_acpi_on_devcfg(struct ata_device *dev)
+{
+ struct ata_port *ap = dev->ap;
+ struct ata_eh_context *ehc = &ap->eh_context;
+ int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
+ int rc;
+
+ if (!dev->acpi_handle)
+ return 0;
+
+ /* do we need to do _GTF? */
+ if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) &&
+ !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET)))
+ return 0;
+
+ /* do _SDD if SATA */
+ if (acpi_sata) {
+ rc = ata_acpi_push_id(dev);
+ if (rc)
+ goto acpi_err;
+ }
+
+ /* do _GTF */
+ rc = ata_acpi_exec_tfs(dev);
+ if (rc < 0)
+ goto acpi_err;
+
+ dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
+
+ /* refresh IDENTIFY page if any _GTF command has been executed */
+ if (rc > 0) {
+ rc = ata_dev_reread_id(dev, 0);
+ if (rc < 0) {
+ ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
+ "after ACPI commands\n");
+ return rc;
+ }
+ }
+ return 0;
+
+ acpi_err:
+ /* let EH retry on the first failure, disable ACPI on the second */
+ if (dev->flags & ATA_DFLAG_ACPI_FAILED) {
+ ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the "
+ "second time, disabling (errno=%d)\n", rc);
+
+ dev->acpi_handle = NULL;
+
+ /* if port is working, request IDENTIFY reload and continue */
+ if (!(ap->pflags & ATA_PFLAG_FROZEN))
+ rc = 1;
+ }
+ dev->flags |= ATA_DFLAG_ACPI_FAILED;
+ return rc;
+}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 981b397cb46b..5b25311ba885 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1845,7 +1845,8 @@ static void ata_dev_config_ncq(struct ata_device *dev,
int ata_dev_configure(struct ata_device *dev)
{
struct ata_port *ap = dev->ap;
- int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
+ struct ata_eh_context *ehc = &ap->eh_context;
+ int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
const u16 *id = dev->id;
unsigned int xfer_mask;
char revbuf[7]; /* XYZ-99\0 */
@@ -1862,15 +1863,10 @@ int ata_dev_configure(struct ata_device *dev)
if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
- /* set _SDD */
- rc = ata_acpi_push_id(dev);
- if (rc) {
- ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
- rc);
- }
-
- /* retrieve and execute the ATA task file of _GTF */
- ata_acpi_exec_tfs(ap);
+ /* let ACPI work its magic */
+ rc = ata_acpi_on_devcfg(dev);
+ if (rc)
+ return rc;
/* print device capabilities */
if (ata_msg_probe(ap))
@@ -3359,7 +3355,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
return 0;
/* if SATA, resume phy */
- if (ap->cbl == ATA_CBL_SATA) {
+ if (ap->flags & ATA_FLAG_SATA) {
rc = sata_phy_resume(ap, timing, deadline);
/* whine about phy resume failure but proceed */
if (rc && rc != -EOPNOTSUPP)
@@ -4107,6 +4103,68 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
}
/**
+ * ata_fill_sg_dumb - Fill PCI IDE PRD table
+ * @qc: Metadata associated with taskfile to be transferred
+ *
+ * Fill PCI IDE PRD (scatter-gather) table with segments
+ * associated with the current disk command. Perform the fill
+ * so that we avoid writing any length 64K records for
+ * controllers that don't follow the spec.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ */
+static void ata_fill_sg_dumb(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct scatterlist *sg;
+ unsigned int idx;
+
+ WARN_ON(qc->__sg == NULL);
+ WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
+
+ idx = 0;
+ ata_for_each_sg(sg, qc) {
+ u32 addr, offset;
+ u32 sg_len, len, blen;
+
+ /* determine if physical DMA addr spans 64K boundary.
+ * Note h/w doesn't support 64-bit, so we unconditionally
+ * truncate dma_addr_t to u32.
+ */
+ addr = (u32) sg_dma_address(sg);
+ sg_len = sg_dma_len(sg);
+
+ while (sg_len) {
+ offset = addr & 0xffff;
+ len = sg_len;
+ if ((offset + sg_len) > 0x10000)
+ len = 0x10000 - offset;
+
+ blen = len & 0xffff;
+ ap->prd[idx].addr = cpu_to_le32(addr);
+ if (blen == 0) {
+ /* Some PATA chipsets like the CS5530 can't
+ cope with 0x0000 meaning 64K as the spec says */
+ ap->prd[idx].flags_len = cpu_to_le32(0x8000);
+ blen = 0x8000;
+ ap->prd[++idx].addr = cpu_to_le32(addr + 0x8000);
+ }
+ ap->prd[idx].flags_len = cpu_to_le32(blen);
+ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
+
+ idx++;
+ sg_len -= len;
+ addr += len;
+ }
+ }
+
+ if (idx)
+ ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
+/**
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
* @qc: Metadata associated with taskfile to check
*
@@ -4153,6 +4211,23 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
ata_fill_sg(qc);
}
+/**
+ * ata_dumb_qc_prep - Prepare taskfile for submission
+ * @qc: Metadata associated with taskfile to be prepared
+ *
+ * Prepare ATA taskfile for submission.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
+{
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+ return;
+
+ ata_fill_sg_dumb(qc);
+}
+
void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
/**
@@ -5660,7 +5735,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance)
*/
int sata_scr_valid(struct ata_port *ap)
{
- return ap->cbl == ATA_CBL_SATA && ap->ops->scr_read;
+ return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
}
/**
@@ -6293,6 +6368,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
if (rc)
return rc;
+ /* associate with ACPI nodes */
+ ata_acpi_associate(host);
+
/* set cable, sata_spd_limit and report */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
@@ -6324,7 +6402,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
if (!ata_port_is_dummy(ap))
ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
"ctl 0x%p bmdma 0x%p irq %d\n",
- ap->cbl == ATA_CBL_SATA ? 'S' : 'P',
+ (ap->flags & ATA_FLAG_SATA) ? 'S' : 'P',
ata_mode_string(xfer_mask),
ap->ioaddr.cmd_addr,
ap->ioaddr.ctl_addr,
@@ -6822,6 +6900,7 @@ EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer);
EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
EXPORT_SYMBOL_GPL(ata_qc_prep);
+EXPORT_SYMBOL_GPL(ata_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index f7582c9c320e..9ee0a8c08d96 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2154,19 +2154,25 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
+ /* tell ACPI we're suspending */
+ rc = ata_acpi_on_suspend(ap);
+ if (rc)
+ goto out;
+
/* suspend */
ata_eh_freeze_port(ap);
if (ap->ops->port_suspend)
rc = ap->ops->port_suspend(ap, ap->pm_mesg);
+ out:
/* report result */
spin_lock_irqsave(ap->lock, flags);
ap->pflags &= ~ATA_PFLAG_PM_PENDING;
if (rc == 0)
ap->pflags |= ATA_PFLAG_SUSPENDED;
- else
+ else if (ap->pflags & ATA_PFLAG_FROZEN)
ata_port_schedule_eh(ap);
if (ap->pm_result) {
@@ -2207,6 +2213,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
if (ap->ops->port_resume)
rc = ap->ops->port_resume(ap);
+ /* tell ACPI that we're resuming */
+ ata_acpi_on_resume(ap);
+
/* report result */
spin_lock_irqsave(ap->lock, flags);
ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4ddf00c8c5f5..cfde22da07ac 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2620,7 +2620,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
ata_dev_printk(dev, KERN_WARNING,
"invalid multi_count %u ignored\n",
multi_count);
- }
+ }
/* READ/WRITE LONG use a non-standard sect_size */
qc->sect_size = ATA_SECT_SIZE;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 5e2466658420..ba17fc5f2e99 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -98,17 +98,15 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host);
/* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI
-extern int ata_acpi_exec_tfs(struct ata_port *ap);
-extern int ata_acpi_push_id(struct ata_device *dev);
+extern void ata_acpi_associate(struct ata_host *host);
+extern int ata_acpi_on_suspend(struct ata_port *ap);
+extern void ata_acpi_on_resume(struct ata_port *ap);
+extern int ata_acpi_on_devcfg(struct ata_device *adev);
#else
-static inline int ata_acpi_exec_tfs(struct ata_port *ap)
-{
- return 0;
-}
-static inline int ata_acpi_push_id(struct ata_device *dev)
-{
- return 0;
-}
+static inline void ata_acpi_associate(struct ata_host *host) { }
+static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
+static inline void ata_acpi_on_resume(struct ata_port *ap) { }
+static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; }
#endif
/* libata-scsi.c */
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 75e95bdbe02f..30c4276ec882 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -520,14 +520,14 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info_early = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &ali_early_port_ops
};
/* Revision 0x20 added DMA */
static const struct ata_port_info info_20 = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &ali_20_port_ops
@@ -535,7 +535,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Revision 0x20 with support logic added UDMA */
static const struct ata_port_info info_20_udma = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07, /* UDMA33 */
@@ -544,37 +544,37 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Revision 0xC2 adds UDMA66 */
static const struct ata_port_info info_c2 = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f,
+ .udma_mask = ATA_UDMA4,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC3 is UDMA66 for now */
static const struct ata_port_info info_c3 = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f,
+ .udma_mask = ATA_UDMA4,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC4 is UDMA100 */
static const struct ata_port_info info_c4 = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC5 is UDMA133 with LBA48 DMA */
static const struct ata_port_info info_c5 = {
.sht = &ali_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &ali_c5_port_ops
};
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index a16f629b7b38..b9c44c575ce3 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -541,7 +541,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info info[10] = {
{ /* 0: AMD 7401 */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07, /* No SWDMA */
.udma_mask = 0x07, /* UDMA 33 */
@@ -549,74 +549,74 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
},
{ /* 1: Early AMD7409 - no swdma */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f, /* UDMA 66 */
+ .udma_mask = ATA_UDMA4, /* UDMA 66 */
.port_ops = &amd66_port_ops
},
{ /* 2: AMD 7409, no swdma errata */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f, /* UDMA 66 */
+ .udma_mask = ATA_UDMA4, /* UDMA 66 */
.port_ops = &amd66_port_ops
},
{ /* 3: AMD 7411 */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f, /* UDMA 100 */
+ .udma_mask = ATA_UDMA5, /* UDMA 100 */
.port_ops = &amd100_port_ops
},
{ /* 4: AMD 7441 */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f, /* UDMA 100 */
+ .udma_mask = ATA_UDMA5, /* UDMA 100 */
.port_ops = &amd100_port_ops
},
{ /* 5: AMD 8111*/
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f, /* UDMA 133, no swdma */
+ .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
.port_ops = &amd133_port_ops
},
{ /* 6: AMD 8111 UDMA 100 (Serenade) */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f, /* UDMA 100, no swdma */
+ .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */
.port_ops = &amd133_port_ops
},
{ /* 7: Nvidia Nforce */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f, /* UDMA 100 */
+ .udma_mask = ATA_UDMA5, /* UDMA 100 */
.port_ops = &nv100_port_ops
},
{ /* 8: Nvidia Nforce2 and later */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f, /* UDMA 133, no swdma */
+ .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
.port_ops = &nv133_port_ops
},
{ /* 9: AMD CS5536 (Geode companion) */
.sht = &amd_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f, /* UDMA 100 */
+ .udma_mask = ATA_UDMA5, /* UDMA 100 */
.port_ops = &amd100_port_ops
}
};
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 03b6ddd2abd2..ce589d96ca42 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -416,7 +416,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
static const struct ata_port_info info_6210 = {
.sht = &artop_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA2,
@@ -424,7 +424,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
};
static const struct ata_port_info info_626x = {
.sht = &artop_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA4,
@@ -432,7 +432,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
};
static const struct ata_port_info info_626x_fast = {
.sht = &artop_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 844914681a2a..80509be49e7a 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -270,7 +270,7 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &atiixp_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x06, /* No MWDMA0 support */
.udma_mask = 0x3F,
@@ -285,6 +285,7 @@ static const struct pci_device_id atiixp[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
{ },
};
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 31cbf8daa299..0feb5ae8c486 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -251,7 +251,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &cmd640_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &cmd640_port_ops
};
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 320a5b10aa98..dc443e7dc37c 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -380,21 +380,21 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info cmd_info[6] = {
{ /* CMD 643 - no UDMA */
.sht = &cmd64x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with broken UDMA */
.sht = &cmd64x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with working UDMA */
.sht = &cmd64x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA1,
@@ -402,14 +402,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
},
{ /* CMD 646 rev 1 */
.sht = &cmd64x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cmd646r1_port_ops
},
{ /* CMD 648 */
.sht = &cmd64x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA2,
@@ -417,7 +417,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
},
{ /* CMD 649 */
.sht = &cmd64x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA3,
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 00cf0134079c..6bf037d82b5a 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -146,7 +146,7 @@ static struct scsi_host_template cs5520_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -178,7 +178,7 @@ static struct ata_port_operations cs5520_port_ops = {
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
+ .qc_prep = ata_dumb_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 848f0309bf03..3fca5898642b 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -167,7 +167,7 @@ static struct scsi_host_template cs5530_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -201,7 +201,7 @@ static struct ata_port_operations cs5530_port_ops = {
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = ata_cable_40wire,
- .qc_prep = ata_qc_prep,
+ .qc_prep = ata_dumb_qc_prep,
.qc_issue = cs5530_qc_issue_prot,
.data_xfer = ata_data_xfer,
@@ -337,7 +337,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &cs5530_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
@@ -346,7 +346,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
static const struct ata_port_info info_palmax_secondary = {
.sht = &cs5530_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &cs5530_port_ops
};
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index aa3256fb9f7a..360b6f32e17e 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -225,10 +225,10 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &cs5535_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f,
+ .udma_mask = ATA_UDMA4,
.port_ops = &cs5535_port_ops
};
const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index d41a7691dd8e..6cbc8778bf4f 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -167,7 +167,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
{
static const struct ata_port_info info = {
.sht = &cy82c693_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cy82c693_port_ops
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index 079248a9b460..c8ba59c56114 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -303,7 +303,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
static const struct ata_port_info info = {
.sht = &efar_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
.udma_mask = 0x0f, /* UDMA 66 */
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 0c9cb6090711..6f7d34ad19ef 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -393,10 +393,10 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_hpt366 = {
.sht = &hpt36x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f,
+ .udma_mask = ATA_UDMA4,
.port_ops = &hpt366_port_ops
};
struct ata_port_info info = info_hpt366;
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index a8c0cbeca399..b0af65aadde3 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -889,25 +889,25 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370 = {
.sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a = {
.sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370_33 = {
.sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x0f,
@@ -916,7 +916,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a_33 = {
.sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x0f,
@@ -925,19 +925,19 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT371, 372 and friends - UDMA133 */
static const struct ata_port_info info_hpt372 = {
.sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops
};
/* HPT374 - UDMA100 */
static const struct ata_port_info info_hpt374 = {
.sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &hpt374_port_ops
};
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index e947433cb37d..aa29cde09f8b 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -490,10 +490,10 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT372N and friends - UDMA133 */
static const struct ata_port_info info = {
.sht = &hpt3x2n_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &hpt3x2n_port_ops
};
struct ata_port_info port = info;
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 8ce5e23a5f75..d928c9105034 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -173,7 +173,7 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &hpt3x3_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index c791a46df461..321d98b0bed2 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -530,7 +530,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
ap->pio_mask = 0x1f;
ap->mwdma_mask = info->mwdma_mask;
- ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ops = &pata_icside_port_ops;
pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]);
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index 95b0bb61788b..b8af55e89156 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -313,10 +313,10 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static int printed_version;
static const struct ata_port_info info = {
.sht = &it8213_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x1f, /* UDMA 100 */
+ .udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */
.port_ops = &it8213_ops,
};
/* Current IT8213 stuff is single port */
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 12c6e08cc4d1..b67bbf6516ba 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -714,17 +714,17 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info info_smart = {
.sht = &it821x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &it821x_smart_port_ops
};
static const struct ata_port_info info_passthru = {
.sht = &it821x_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &it821x_passthru_port_ops
};
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 8d2bc1e9e871..4ca7fd6118d5 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -1,13 +1,14 @@
/*
* ixp4xx PATA/Compact Flash driver
- * Copyright (c) 2006 Tower Technologies
+ * Copyright (C) 2006-07 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* An ATA driver to handle a Compact Flash connected
* to the ixp4xx expansion bus in TrueIDE mode. The CF
* must have it chip selects connected to two CS lines
- * on the ixp4xx. The interrupt line is optional, if not
- * specified the driver will run in polling mode.
+ * on the ixp4xx. In the irq is not available, you might
+ * want to modify both this driver and libata to run in
+ * polling mode.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,7 +24,7 @@
#include <scsi/scsi_host.h>
#define DRV_NAME "pata_ixp4xx_cf"
-#define DRV_VERSION "0.1.3"
+#define DRV_VERSION "0.2"
static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
{
@@ -42,13 +43,6 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
return 0;
}
-static void ixp4xx_phy_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- ata_port_probe(ap);
- ata_bus_reset(ap);
-}
-
static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
unsigned int buflen, int write_data)
{
@@ -56,7 +50,7 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
unsigned int words = buflen >> 1;
u16 *buf16 = (u16 *) buf;
struct ata_port *ap = adev->ap;
- void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
+ void __iomem *mmio = ap->ioaddr.data_addr;
struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
/* set the expansion bus in 16bit mode and restore
@@ -92,10 +86,6 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
*data->cs0_cfg |= 0x01;
}
-static void ixp4xx_irq_clear(struct ata_port *ap)
-{
-}
-
static struct scsi_host_template ixp4xx_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -115,29 +105,32 @@ static struct scsi_host_template ixp4xx_sht = {
};
static struct ata_port_operations ixp4xx_port_ops = {
- .set_mode = ixp4xx_set_mode,
- .mode_filter = ata_pci_default_filter,
-
- .port_disable = ata_port_disable,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
- .data_xfer = ixp4xx_mmio_data_xfer,
- .cable_detect = ata_cable_40wire,
-
- .irq_clear = ixp4xx_irq_clear,
- .irq_on = ata_irq_on,
- .irq_ack = ata_irq_ack,
-
- .port_start = ata_port_start,
-
- .phy_reset = ixp4xx_phy_reset,
+ .set_mode = ixp4xx_set_mode,
+ .mode_filter = ata_pci_default_filter,
+
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .exec_command = ata_exec_command,
+ .check_status = ata_check_status,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ixp4xx_mmio_data_xfer,
+ .cable_detect = ata_cable_40wire,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
+
+ .port_start = ata_port_start,
};
static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
@@ -178,7 +171,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
struct ata_host *host;
struct ata_port *ap;
struct ixp4xx_pata_data *data = pdev->dev.platform_data;
- int rc;
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -211,10 +203,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
ap->pio_mask = 0x1f; /* PIO4 */
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
- /* run in polling mode if no irq has been assigned */
- if (!irq)
- ap->flags |= ATA_FLAG_PIO_POLLING;
-
ixp4xx_setup_port(&ap->ioaddr, data);
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 2af7ff8256ca..4d67f238eee2 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -193,11 +193,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
{
static const struct ata_port_info info = {
.sht = &jmicron_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &jmicron_ops,
};
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index edbfe0dbbf78..87594c04d3a3 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -163,22 +163,22 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
{
static const struct ata_port_info info = {
.sht = &marvell_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &marvell_ops,
};
static const struct ata_port_info info_sata = {
.sht = &marvell_sht,
/* Slave possible as its magically mapped not real */
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &marvell_ops,
};
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 81f563458666..40eb574828bf 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -94,12 +94,12 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.sht = &netcell_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
/* Actually we don't really care about these as the
firmware deals with it */
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* UDMA 133 */
+ .udma_mask = ATA_UDMA5, /* UDMA 133 */
.port_ops = &netcell_ops,
};
const struct ata_port_info *port_info[] = { &info, NULL };
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index ea70ec744879..2f5d714ebfc4 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -193,7 +193,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &ns87410_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x0F,
.port_ops = &ns87410_port_ops
};
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 29c23ddd6550..091a70a0ef1c 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -291,7 +291,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.sht = &oldpiix_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
.port_ops = &oldpiix_pata_ops,
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index 1c44653e1e06..458bf67f766f 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -218,7 +218,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &opti_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &opti_port_ops
};
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 3093b02286ce..f89bdfde16d0 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -484,14 +484,14 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_82c700 = {
.sht = &optidma_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &optidma_port_ops
};
static const struct ata_port_info info_82c700_udma = {
.sht = &optidma_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index d277246b7337..92447bed5e77 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -320,7 +320,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
static const struct ata_port_info info[3] = {
{
.sht = &pdc202xx_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA2,
@@ -328,7 +328,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
},
{
.sht = &pdc202xx_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA4,
@@ -336,7 +336,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
},
{
.sht = &pdc202xx_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index cbb7866940d6..79f841bca593 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -139,6 +139,7 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
struct resource *io_res, *ctl_res;
struct ata_host *host;
struct ata_port *ap;
+ struct pata_platform_info *pp_info;
unsigned int mmio;
/*
@@ -208,11 +209,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
- pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data);
+ pp_info = (struct pata_platform_info *)(pdev->dev.platform_data);
+ pata_platform_setup_port(&ap->ioaddr, pp_info);
/* activate */
return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
- 0, &pata_platform_sht);
+ pp_info->irq_flags, &pata_platform_sht);
}
/**
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index ba96b54f5b87..7d1aabed422d 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -257,7 +257,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.sht = &radisys_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
.udma_mask = 0x14, /* UDMA33/66 only */
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index a3488b41ad26..7632fcb070ca 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -133,7 +133,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static int printed_version;
static const struct ata_port_info info = {
.sht = &rz1000_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &rz1000_port_ops
};
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 1233063ab9a8..b8b2d11e4180 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -185,7 +185,7 @@ static struct scsi_host_template sc1200_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -219,7 +219,7 @@ static struct ata_port_operations sc1200_port_ops = {
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
+ .qc_prep = ata_dumb_qc_prep,
.qc_issue = sc1200_qc_issue_prot,
.data_xfer = ata_data_xfer,
@@ -245,7 +245,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &sc1200_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 1e8f421963c7..0231aba51ca4 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -478,31 +478,31 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
static const struct ata_port_info info[4] = {
{ /* OSB4 */
.sht = &serverworks_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
.port_ops = &serverworks_osb4_port_ops
}, { /* OSB4 no UDMA */
.sht = &serverworks_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x00,
.port_ops = &serverworks_osb4_port_ops
}, { /* CSB5 */
.sht = &serverworks_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f,
+ .udma_mask = ATA_UDMA4,
.port_ops = &serverworks_csb_port_ops
}, { /* CSB5 - later revisions*/
.sht = &serverworks_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &serverworks_csb_port_ops
}
};
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 440e2cb6ee75..b0cd52d6e3fb 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -35,6 +35,8 @@
#define DRV_NAME "pata_sil680"
#define DRV_VERSION "0.4.6"
+#define SIL680_MMIO_BAR 5
+
/**
* sil680_selreg - return register base
* @hwif: interface
@@ -293,8 +295,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
pci_read_config_byte(pdev, 0x8A, &tmpbyte);
- printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
- tmpbyte & 1, tmpbyte & 0x30);
+ dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
+ tmpbyte & 1, tmpbyte & 0x30);
switch(tmpbyte & 0x30) {
case 0x00:
@@ -315,8 +317,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
}
pci_read_config_byte(pdev, 0x8A, &tmpbyte);
- printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
- tmpbyte & 1, tmpbyte & 0x30);
+ dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
+ tmpbyte & 1, tmpbyte & 0x30);
pci_write_config_byte(pdev, 0xA1, 0x72);
pci_write_config_word(pdev, 0xA2, 0x328A);
@@ -339,22 +341,23 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
return tmpbyte & 0x30;
}
-static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __devinit sil680_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &sil680_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &sil680_port_ops
};
static const struct ata_port_info info_slow = {
.sht = &sil680_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil680_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index cfe4ec6eb3d5..2b4508206a6c 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -732,7 +732,7 @@ static const struct ata_port_operations sis_old_ops = {
static const struct ata_port_info sis_info = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07,
.udma_mask = 0,
@@ -740,7 +740,7 @@ static const struct ata_port_info sis_info = {
};
static const struct ata_port_info sis_info33 = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA2, /* UDMA 33 */
@@ -748,28 +748,28 @@ static const struct ata_port_info sis_info33 = {
};
static const struct ata_port_info sis_info66 = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA4, /* UDMA 66 */
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info100 = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA5,
.port_ops = &sis_100_ops,
};
static const struct ata_port_info sis_info100_early = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.udma_mask = ATA_UDMA5,
.pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info133 = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_ops,
@@ -783,7 +783,7 @@ const struct ata_port_info sis_info133_for_sata = {
};
static const struct ata_port_info sis_info133_early = {
.sht = &sis_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_early_ops,
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index e5aaec43694d..bde734189623 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -303,14 +303,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
{
static const struct ata_port_info info_dma = {
.sht = &sl82c105_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &sl82c105_port_ops
};
static const struct ata_port_info info_early = {
.sht = &sl82c105_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &sl82c105_port_ops
};
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index b1d3076dfe51..af21f443db6e 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -235,7 +235,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.sht = &triflex_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &triflex_port_ops
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 63eca299c62b..f0cadbe6aa11 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -471,7 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7,
+ .udma_mask = ATA_UDMA2,
.port_ops = &via_port_ops
};
/* VIA UDMA 66 devices */
@@ -480,7 +480,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x1f,
+ .udma_mask = ATA_UDMA4,
.port_ops = &via_port_ops
};
/* VIA UDMA 100 devices */
@@ -489,7 +489,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.port_ops = &via_port_ops
};
/* UDMA133 with bad AST (All current 133) */
@@ -498,7 +498,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f, /* FIXME: should check north bridge */
+ .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */
.port_ops = &via_port_ops
};
struct ata_port_info type;
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index f12c2b6ac08e..bec1de594de8 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -145,32 +145,32 @@ static struct scsi_host_template adma_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+ .proc_name = DRV_NAME,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
+ .dma_boundary = ADMA_DMA_BOUNDARY,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
.use_clustering = ENABLE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ADMA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ .emulated = ATA_SHT_EMULATED,
};
static const struct ata_port_operations adma_ata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .check_atapi_dma = adma_check_atapi_dma,
.exec_command = ata_exec_command,
+ .check_status = ata_check_status,
.dev_select = ata_std_dev_select,
.phy_reset = adma_phy_reset,
+ .check_atapi_dma = adma_check_atapi_dma,
+ .data_xfer = ata_data_xfer,
.qc_prep = adma_qc_prep,
.qc_issue = adma_qc_issue,
.eng_timeout = adma_eng_timeout,
- .data_xfer = ata_data_xfer,
.irq_clear = adma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -188,7 +188,7 @@ static struct ata_port_info adma_port_info[] = {
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
.pio_mask = 0x10, /* pio4 */
- .udma_mask = 0x1f, /* udma0-4 */
+ .udma_mask = ATA_UDMA4,
.port_ops = &adma_ata_ops,
},
};
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index dc3bbce04676..3de183461c3c 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -192,7 +192,7 @@ static void inic_reset_port(void __iomem *port_base)
static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
{
- void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->ioaddr.scr_addr;
void __iomem *addr;
u32 val;
@@ -210,7 +210,7 @@ static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{
- void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->ioaddr.scr_addr;
void __iomem *addr;
if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -594,7 +594,7 @@ static struct ata_port_info inic_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &inic_port_ops
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 590f2f92b4e0..3873b29c80d6 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -526,44 +526,44 @@ static const struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
.flags = MV_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_508x */
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_5080 */
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_604x */
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_608x */
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_6042 */
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_7042 */
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
};
@@ -2338,7 +2338,7 @@ static void mv_print_info(struct ata_host *host)
struct pci_dev *pdev = to_pci_dev(host->dev);
struct mv_host_priv *hpriv = host->private_data;
u8 rev_id, scc;
- const char *scc_s;
+ const char *scc_s, *gen;
/* Use this to determine the HW stepping of the chip so we know
* what errata to workaround
@@ -2351,11 +2351,20 @@ static void mv_print_info(struct ata_host *host)
else if (scc == 0x01)
scc_s = "RAID";
else
- scc_s = "unknown";
+ scc_s = "?";
+
+ if (IS_GEN_I(hpriv))
+ gen = "I";
+ else if (IS_GEN_II(hpriv))
+ gen = "II";
+ else if (IS_GEN_IIE(hpriv))
+ gen = "IIE";
+ else
+ gen = "?";
dev_printk(KERN_INFO, &pdev->dev,
- "%u slots %u ports %s mode IRQ via %s\n",
- (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
+ "Gen-%s %u slots %u ports %s mode IRQ via %s\n",
+ gen, (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
}
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 6dc0b011a6b7..2ad5872fe90c 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -45,8 +45,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
-#define DRV_VERSION "2.07"
-
+#define DRV_VERSION "2.08"
enum {
PDC_MAX_PORTS = 4,
@@ -94,7 +93,7 @@ enum {
board_20319 = 2, /* FastTrak S150 TX4 */
board_20619 = 3, /* FastTrak TX4000 */
board_2057x = 4, /* SATAII150 Tx2plus */
- board_2057x_pata = 5, /* SATAII150 Tx2plus */
+ board_2057x_pata = 5, /* SATAII150 Tx2plus PATA port */
board_40518 = 6, /* SATAII150 Tx4 */
PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */
@@ -124,7 +123,6 @@ enum {
PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */
};
-
struct pdc_port_priv {
u8 *pkt;
dma_addr_t pkt_dma;
@@ -252,7 +250,7 @@ static const struct ata_port_info pdc_port_info[] = {
PDC_FLAG_SATA_PATA,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_old_sata_ops,
},
@@ -261,7 +259,7 @@ static const struct ata_port_info pdc_port_info[] = {
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -271,7 +269,7 @@ static const struct ata_port_info pdc_port_info[] = {
PDC_FLAG_4_PORTS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_old_sata_ops,
},
@@ -281,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = {
PDC_FLAG_4_PORTS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -291,7 +289,7 @@ static const struct ata_port_info pdc_port_info[] = {
PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_sata_ops,
},
@@ -301,7 +299,7 @@ static const struct ata_port_info pdc_port_info[] = {
PDC_FLAG_GEN_II,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -311,7 +309,7 @@ static const struct ata_port_info pdc_port_info[] = {
PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_sata_ops,
},
};
@@ -340,7 +338,6 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
{ } /* terminate list */
};
-
static struct pci_driver pdc_ata_pci_driver = {
.name = DRV_NAME,
.id_table = pdc_ata_pci_tbl,
@@ -348,7 +345,6 @@ static struct pci_driver pdc_ata_pci_driver = {
.remove = ata_pci_remove_one,
};
-
static int pdc_common_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
@@ -382,7 +378,7 @@ static int pdc_sata_port_start(struct ata_port *ap)
/* fix up PHYMODE4 align timing */
if (ap->flags & PDC_FLAG_GEN_II) {
- void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
+ void __iomem *mmio = ap->ioaddr.scr_addr;
unsigned int tmp;
tmp = readl(mmio + 0x014);
@@ -418,7 +414,7 @@ static void pdc_reset_port(struct ata_port *ap)
static int pdc_pata_cable_detect(struct ata_port *ap)
{
u8 tmp;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
+ void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
tmp = readb(mmio);
if (tmp & 0x01)
@@ -438,7 +434,6 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
-
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
u32 val)
{
@@ -573,7 +568,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
static void pdc_freeze(struct ata_port *ap)
{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = ap->ioaddr.cmd_addr;
u32 tmp;
tmp = readl(mmio + PDC_CTLSTAT);
@@ -585,7 +580,7 @@ static void pdc_freeze(struct ata_port *ap)
static void pdc_thaw(struct ata_port *ap)
{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = ap->ioaddr.cmd_addr;
u32 tmp;
/* clear IRQ */
@@ -657,8 +652,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
ata_port_abort(ap);
}
-static inline unsigned int pdc_host_intr( struct ata_port *ap,
- struct ata_queued_cmd *qc)
+static inline unsigned int pdc_host_intr(struct ata_port *ap,
+ struct ata_queued_cmd *qc)
{
unsigned int handled = 0;
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
@@ -685,10 +680,10 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
handled = 1;
break;
- default:
+ default:
ap->stats.idle_irq++;
break;
- }
+ }
return handled;
}
@@ -701,6 +696,18 @@ static void pdc_irq_clear(struct ata_port *ap)
readl(mmio + PDC_INT_SEQMASK);
}
+static inline int pdc_is_sataii_tx4(unsigned long flags)
+{
+ const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
+ return (flags & mask) == mask;
+}
+
+static inline unsigned int pdc_port_no_to_ata_no(unsigned int port_no, int is_sataii_tx4)
+{
+ static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
+ return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
+}
+
static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
@@ -807,7 +814,6 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
ata_tf_load(ap, tf);
}
-
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
@@ -867,7 +873,6 @@ static void pdc_ata_setup_port(struct ata_port *ap,
ap->ioaddr.scr_addr = scr_addr;
}
-
static void pdc_host_init(struct ata_host *host)
{
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
@@ -955,10 +960,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
if (pi->flags & PDC_FLAG_SATA_PATA) {
u8 tmp = readb(base + PDC_FLASH_CTL+1);
- if (!(tmp & 0x80)) {
+ if (!(tmp & 0x80))
ppi[n_ports++] = pi + 1;
- dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
- }
}
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
@@ -968,22 +971,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
}
host->iomap = pcim_iomap_table(pdev);
- is_sataii_tx4 = 0;
- if ((pi->flags & (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) == (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) {
- is_sataii_tx4 = 1;
- dev_printk(KERN_INFO, &pdev->dev, "applying SATAII TX4 port numbering workaround\n");
- }
+ is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags);
for (i = 0; i < host->n_ports; i++) {
- static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
- int ata_nr;
-
- ata_nr = i;
- if (is_sataii_tx4)
- ata_nr = sataii_tx4_port_remap[i];
-
+ unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
pdc_ata_setup_port(host->ports[i],
- base + 0x200 + ata_nr * 0x80,
- base + 0x400 + ata_nr * 0x100);
+ base + 0x200 + ata_no * 0x80,
+ base + 0x400 + ata_no * 0x100);
}
/* initialize adapter */
@@ -1002,19 +995,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
&pdc_ata_sht);
}
-
static int __init pdc_ata_init(void)
{
return pci_register_driver(&pdc_ata_pci_driver);
}
-
static void __exit pdc_ata_exit(void)
{
pci_unregister_driver(&pdc_ata_pci_driver);
}
-
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 6688ccb66320..9ab554da89bf 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -176,7 +176,7 @@ static const struct ata_port_info qs_port_info[] = {
//FIXME ATA_FLAG_SRST |
ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
.pio_mask = 0x10, /* pio4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &qs_ata_ops,
},
};
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index a3b339bcf3cf..2a86dc4598d0 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -218,7 +218,7 @@ static const struct ata_port_info sil_port_info[] = {
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3112_no_sata_irq */
@@ -227,7 +227,7 @@ static const struct ata_port_info sil_port_info[] = {
SIL_FLAG_NO_SATA_IRQ,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3512 */
@@ -235,7 +235,7 @@ static const struct ata_port_info sil_port_info[] = {
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3114 */
@@ -243,7 +243,7 @@ static const struct ata_port_info sil_port_info[] = {
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
};
@@ -262,8 +262,9 @@ static const struct {
unsigned long sfis_cfg; /* SATA FIS reception config register */
} sil_port[] = {
/* port 0 ... */
- { 0x80, 0x8A, 0x00, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c },
- { 0xC0, 0xCA, 0x08, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
+ /* tf ctl bmdma bmdma2 fifo scr sien mode sfis */
+ { 0x80, 0x8A, 0x0, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c },
+ { 0xC0, 0xCA, 0x8, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
{ 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c },
{ 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc },
/* ... port 3 */
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 0ddfae9911cd..ac43a30ebe29 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -426,7 +426,7 @@ static const struct ata_port_info sil24_port_info[] = {
SIL24_FLAG_PCIX_IRQ_WOC,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5, /* udma0-5 */
.port_ops = &sil24_ops,
},
/* sil_3132 */
@@ -434,7 +434,7 @@ static const struct ata_port_info sil24_port_info[] = {
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5, /* udma0-5 */
.port_ops = &sil24_ops,
},
/* sil_3131/sil_3531 */
@@ -442,7 +442,7 @@ static const struct ata_port_info sil24_port_info[] = {
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x3f, /* udma0-5 */
+ .udma_mask = ATA_UDMA5, /* udma0-5 */
.port_ops = &sil24_ops,
},
};
@@ -888,7 +888,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
if (status & (1 << i)) {
struct ata_port *ap = host->ports[i];
if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- sil24_host_intr(host->ports[i]);
+ sil24_host_intr(ap);
handled++;
} else
printk(KERN_ERR DRV_NAME
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index f111c984a359..fd80bcf1b236 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -133,7 +133,7 @@ static const struct ata_port_info sis_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0x7,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &sis_ops,
};
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index bcb2cd8b063d..63fe99afd59f 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -107,7 +107,7 @@ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -116,7 +116,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -197,7 +197,8 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 dmactl;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
/* load PRD table addr. */
mb(); /* make sure PRD table writes are visible to controller */
writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
@@ -225,7 +226,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
u8 dmactl;
/* start host DMA transaction */
@@ -253,7 +254,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
static u8 k2_stat_check_status(struct ata_port *ap)
{
- return readl((void __iomem *) ap->ioaddr.status_addr);
+ return readl(ap->ioaddr.status_addr);
}
#ifdef CONFIG_PPC_OF
@@ -360,7 +361,7 @@ static const struct ata_port_info k2_port_info[] = {
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
/* board_svw8 */
@@ -370,7 +371,7 @@ static const struct ata_port_info k2_port_info[] = {
K2_FLAG_SATA_8_PORTS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
};
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 2d14f3d56d92..5193bd8647ba 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -30,6 +30,54 @@
*
*/
+/*
+ Theory of operation
+ -------------------
+
+ The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy
+ engine, DIMM memory, and four ATA engines (one per SATA port).
+ Data is copied to/from DIMM memory by the HDMA engine, before
+ handing off to one (or more) of the ATA engines. The ATA
+ engines operate solely on DIMM memory.
+
+ The SX4 behaves like a PATA chip, with no SATA controls or
+ knowledge whatsoever, leading to the presumption that
+ PATA<->SATA bridges exist on SX4 boards, external to the
+ PDC20621 chip itself.
+
+ The chip is quite capable, supporting an XOR engine and linked
+ hardware commands (permits a string to transactions to be
+ submitted and waited-on as a single unit), and an optional
+ microprocessor.
+
+ The limiting factor is largely software. This Linux driver was
+ written to multiplex the single HDMA engine to copy disk
+ transactions into a fixed DIMM memory space, from where an ATA
+ engine takes over. As a result, each WRITE looks like this:
+
+ submit HDMA packet to hardware
+ hardware copies data from system memory to DIMM
+ hardware raises interrupt
+
+ submit ATA packet to hardware
+ hardware executes ATA WRITE command, w/ data in DIMM
+ hardware raises interrupt
+
+ and each READ looks like this:
+
+ submit ATA packet to hardware
+ hardware executes ATA READ command, w/ data in DIMM
+ hardware raises interrupt
+
+ submit HDMA packet to hardware
+ hardware copies data from DIMM to system memory
+ hardware raises interrupt
+
+ This is a very slow, lock-step way of doing things that can
+ certainly be improved by motivated kernel hackers.
+
+ */
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -58,6 +106,8 @@ enum {
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */
+ PDC_CTLSTAT = 0x60, /* IDEn control / status */
+
PDC_20621_SEQCTL = 0x400,
PDC_20621_SEQMASK = 0x480,
PDC_20621_GENERAL_CTL = 0x484,
@@ -87,48 +137,60 @@ enum {
board_20621 = 0, /* FastTrak S150 SX4 */
- PDC_RESET = (1 << 11), /* HDMA reset */
+ PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */
+ PDC_RESET = (1 << 11), /* HDMA/ATA reset */
+ PDC_DMA_ENABLE = (1 << 7), /* DMA start/stop */
PDC_MAX_HDMA = 32,
PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1),
- PDC_DIMM0_SPD_DEV_ADDRESS = 0x50,
- PDC_DIMM1_SPD_DEV_ADDRESS = 0x51,
- PDC_MAX_DIMM_MODULE = 0x02,
- PDC_I2C_CONTROL_OFFSET = 0x48,
- PDC_I2C_ADDR_DATA_OFFSET = 0x4C,
- PDC_DIMM0_CONTROL_OFFSET = 0x80,
- PDC_DIMM1_CONTROL_OFFSET = 0x84,
- PDC_SDRAM_CONTROL_OFFSET = 0x88,
- PDC_I2C_WRITE = 0x00000000,
- PDC_I2C_READ = 0x00000040,
- PDC_I2C_START = 0x00000080,
- PDC_I2C_MASK_INT = 0x00000020,
- PDC_I2C_COMPLETE = 0x00010000,
- PDC_I2C_NO_ACK = 0x00100000,
- PDC_DIMM_SPD_SUBADDRESS_START = 0x00,
- PDC_DIMM_SPD_SUBADDRESS_END = 0x7F,
- PDC_DIMM_SPD_ROW_NUM = 3,
- PDC_DIMM_SPD_COLUMN_NUM = 4,
- PDC_DIMM_SPD_MODULE_ROW = 5,
- PDC_DIMM_SPD_TYPE = 11,
- PDC_DIMM_SPD_FRESH_RATE = 12,
- PDC_DIMM_SPD_BANK_NUM = 17,
- PDC_DIMM_SPD_CAS_LATENCY = 18,
- PDC_DIMM_SPD_ATTRIBUTE = 21,
- PDC_DIMM_SPD_ROW_PRE_CHARGE = 27,
- PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28,
- PDC_DIMM_SPD_RAS_CAS_DELAY = 29,
- PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30,
- PDC_DIMM_SPD_SYSTEM_FREQ = 126,
- PDC_CTL_STATUS = 0x08,
- PDC_DIMM_WINDOW_CTLR = 0x0C,
- PDC_TIME_CONTROL = 0x3C,
- PDC_TIME_PERIOD = 0x40,
- PDC_TIME_COUNTER = 0x44,
- PDC_GENERAL_CTLR = 0x484,
- PCI_PLL_INIT = 0x8A531824,
- PCI_X_TCOUNT = 0xEE1E5CFF
+ PDC_DIMM0_SPD_DEV_ADDRESS = 0x50,
+ PDC_DIMM1_SPD_DEV_ADDRESS = 0x51,
+ PDC_I2C_CONTROL = 0x48,
+ PDC_I2C_ADDR_DATA = 0x4C,
+ PDC_DIMM0_CONTROL = 0x80,
+ PDC_DIMM1_CONTROL = 0x84,
+ PDC_SDRAM_CONTROL = 0x88,
+ PDC_I2C_WRITE = 0, /* master -> slave */
+ PDC_I2C_READ = (1 << 6), /* master <- slave */
+ PDC_I2C_START = (1 << 7), /* start I2C proto */
+ PDC_I2C_MASK_INT = (1 << 5), /* mask I2C interrupt */
+ PDC_I2C_COMPLETE = (1 << 16), /* I2C normal compl. */
+ PDC_I2C_NO_ACK = (1 << 20), /* slave no-ack addr */
+ PDC_DIMM_SPD_SUBADDRESS_START = 0x00,
+ PDC_DIMM_SPD_SUBADDRESS_END = 0x7F,
+ PDC_DIMM_SPD_ROW_NUM = 3,
+ PDC_DIMM_SPD_COLUMN_NUM = 4,
+ PDC_DIMM_SPD_MODULE_ROW = 5,
+ PDC_DIMM_SPD_TYPE = 11,
+ PDC_DIMM_SPD_FRESH_RATE = 12,
+ PDC_DIMM_SPD_BANK_NUM = 17,
+ PDC_DIMM_SPD_CAS_LATENCY = 18,
+ PDC_DIMM_SPD_ATTRIBUTE = 21,
+ PDC_DIMM_SPD_ROW_PRE_CHARGE = 27,
+ PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28,
+ PDC_DIMM_SPD_RAS_CAS_DELAY = 29,
+ PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30,
+ PDC_DIMM_SPD_SYSTEM_FREQ = 126,
+ PDC_CTL_STATUS = 0x08,
+ PDC_DIMM_WINDOW_CTLR = 0x0C,
+ PDC_TIME_CONTROL = 0x3C,
+ PDC_TIME_PERIOD = 0x40,
+ PDC_TIME_COUNTER = 0x44,
+ PDC_GENERAL_CTLR = 0x484,
+ PCI_PLL_INIT = 0x8A531824,
+ PCI_X_TCOUNT = 0xEE1E5CFF,
+
+ /* PDC_TIME_CONTROL bits */
+ PDC_TIMER_BUZZER = (1 << 10),
+ PDC_TIMER_MODE_PERIODIC = 0, /* bits 9:8 == 00 */
+ PDC_TIMER_MODE_ONCE = (1 << 8), /* bits 9:8 == 01 */
+ PDC_TIMER_ENABLE = (1 << 7),
+ PDC_TIMER_MASK_INT = (1 << 5),
+ PDC_TIMER_SEQ_MASK = 0x1f, /* SEQ ID for timer */
+ PDC_TIMER_DEFAULT = PDC_TIMER_MODE_ONCE |
+ PDC_TIMER_ENABLE |
+ PDC_TIMER_MASK_INT,
};
@@ -217,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = {
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc_20621_ops,
},
@@ -999,17 +1061,17 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
i2creg |= subaddr << 16;
/* Set the device and subaddress */
- writel(i2creg, mmio + PDC_I2C_ADDR_DATA_OFFSET);
- readl(mmio + PDC_I2C_ADDR_DATA_OFFSET);
+ writel(i2creg, mmio + PDC_I2C_ADDR_DATA);
+ readl(mmio + PDC_I2C_ADDR_DATA);
/* Write Control to perform read operation, mask int */
writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT,
- mmio + PDC_I2C_CONTROL_OFFSET);
+ mmio + PDC_I2C_CONTROL);
for (count = 0; count <= 1000; count ++) {
- status = readl(mmio + PDC_I2C_CONTROL_OFFSET);
+ status = readl(mmio + PDC_I2C_CONTROL);
if (status & PDC_I2C_COMPLETE) {
- status = readl(mmio + PDC_I2C_ADDR_DATA_OFFSET);
+ status = readl(mmio + PDC_I2C_ADDR_DATA);
break;
} else if (count == 1000)
return 0;
@@ -1099,8 +1161,8 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
data |= (((size / 16) - 1) << 16);
data |= (0 << 23);
data |= 8;
- writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET);
- readl(mmio + PDC_DIMM0_CONTROL_OFFSET);
+ writel(data, mmio + PDC_DIMM0_CONTROL);
+ readl(mmio + PDC_DIMM0_CONTROL);
return size;
}
@@ -1122,27 +1184,27 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
*/
data = 0x022259F1;
- writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET);
- readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
+ writel(data, mmio + PDC_SDRAM_CONTROL);
+ readl(mmio + PDC_SDRAM_CONTROL);
/* Turn on for ECC */
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
PDC_DIMM_SPD_TYPE, &spd0);
if (spd0 == 0x02) {
data |= (0x01 << 16);
- writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET);
- readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
+ writel(data, mmio + PDC_SDRAM_CONTROL);
+ readl(mmio + PDC_SDRAM_CONTROL);
printk(KERN_ERR "Local DIMM ECC Enabled\n");
}
/* DIMM Initialization Select/Enable (bit 18/19) */
data &= (~(1<<18));
data |= (1<<19);
- writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET);
+ writel(data, mmio + PDC_SDRAM_CONTROL);
error = 1;
for (i = 1; i <= 10; i++) { /* polling ~5 secs */
- data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
+ data = readl(mmio + PDC_SDRAM_CONTROL);
if (!(data & (1<<19))) {
error = 0;
break;
@@ -1176,7 +1238,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
VPRINTK("Time Period Register (0x40): 0x%x\n", time_period);
/* Enable timer */
- writel(0x00001a0, mmio + PDC_TIME_CONTROL);
+ writel(PDC_TIMER_DEFAULT, mmio + PDC_TIME_CONTROL);
readl(mmio + PDC_TIME_CONTROL);
/* Wait 3 seconds */
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 6815de7cca79..aca71819f6e8 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -129,7 +129,7 @@ static const struct ata_port_info uli_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_IGN_SIMPLEX,
.pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = 0x7f, /* udma0-6 */
+ .udma_mask = ATA_UDMA6,
.port_ops = &uli_ops,
};
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index e8b90e7b42dd..a4c0832033d8 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -223,7 +223,7 @@ static const struct ata_port_info vt6420_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &vt6420_sata_ops,
};
@@ -231,7 +231,7 @@ static struct ata_port_info vt6421_sport_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &vt6421_sata_ops,
};
@@ -239,7 +239,7 @@ static struct ata_port_info vt6421_pport_info = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &vt6421_pata_ops,
};
@@ -303,9 +303,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
if (!(ap->pflags & ATA_PFLAG_LOADING))
goto skip_scr;
- /* Resume phy. This is the old resume sequence from
- * __sata_phy_reset().
- */
+ /* Resume phy. This is the old SATA resume sequence */
svia_scr_write(ap, SCR_CONTROL, 0x300);
svia_scr_read(ap, SCR_CONTROL); /* flush */
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 81330175fc89..1b5d81faa102 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -371,7 +371,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
ATA_FLAG_MMIO,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .udma_mask = ATA_UDMA6,
.port_ops = &vsc_sata_ops,
};
const struct ata_port_info *ppi[] = { &pi, NULL };
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index b4c8319138b2..6e23af1ecbdb 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -2,9 +2,12 @@
# Block device driver configuration
#
-if BLOCK
+menuconfig BLK_DEV
+ bool "Block devices"
+ depends on BLOCK
+ default y
-menu "Block devices"
+if BLK_DEV
config BLK_DEV_FD
tristate "Normal floppy disk support"
@@ -56,40 +59,9 @@ config AMIGA_Z2RAM
To compile this driver as a module, choose M here: the
module will be called z2ram.
-config ATARI_ACSI
- tristate "Atari ACSI support"
- depends on ATARI && BROKEN
- ---help---
- This enables support for the Atari ACSI interface. The driver
- supports hard disks and CD-ROMs, which have 512-byte sectors, or can
- be switched to that mode. Due to the ACSI command format, only disks
- up to 1 GB are supported. Special support for certain ACSI to SCSI
- adapters, which could relax that, isn't included yet. The ACSI
- driver is also the basis for certain other drivers for devices
- attached to the ACSI bus: Atari SLM laser printer, BioNet-100
- Ethernet, and PAMsNet Ethernet. If you want to use one of these
- devices, you need ACSI support, too.
-
- To compile this driver as a module, choose M here: the
- module will be called acsi.
-
-comment "Some devices (e.g. CD jukebox) support multiple LUNs"
- depends on ATARI && ATARI_ACSI
-
-config ACSI_MULTI_LUN
- bool "Probe all LUNs on each ACSI device"
- depends on ATARI_ACSI
- help
- If you have a ACSI device that supports more than one LUN (Logical
- Unit Number), e.g. a CD jukebox, you should say Y here so that all
- will be found by the ACSI driver. An ACSI device with multiple LUNs
- acts logically like multiple ACSI devices. The vast majority of ACSI
- devices have only one LUN, and so most people can say N here and
- should in fact do so, because it is safer.
-
config ATARI_SLM
tristate "Atari SLM laser printer support"
- depends on ATARI && ATARI_ACSI!=n
+ depends on ATARI
help
If you have an Atari SLM laser printer, say Y to include support for
it in the kernel. Otherwise, say N. This driver is also available as
@@ -453,6 +425,4 @@ config ATA_OVER_ETH
source "drivers/s390/block/Kconfig"
-endmenu
-
-endif
+endif # BLK_DEV
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index dd88e33c1eb1..e5f98acc5d52 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
-obj-$(CONFIG_ATARI_ACSI) += acsi.o
obj-$(CONFIG_ATARI_SLM) += acsi_slm.o
obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
obj-$(CONFIG_BLK_DEV_RAM) += rd.o
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
deleted file mode 100644
index e3d9152e231a..000000000000
--- a/drivers/block/acsi.c
+++ /dev/null
@@ -1,1825 +0,0 @@
-/*
- * acsi.c -- Device driver for Atari ACSI hard disks
- *
- * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
- *
- * Some parts are based on hd.c by Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- */
-
-/*
- * Still to in this file:
- * - If a command ends with an error status (!= 0), the following
- * REQUEST SENSE commands (4 to fill the ST-DMA FIFO) are done by
- * polling the _IRQ signal (not interrupt-driven). This should be
- * avoided in future because it takes up a non-neglectible time in
- * the interrupt service routine while interrupts are disabled.
- * Maybe a timer interrupt will get lost :-(
- */
-
-/*
- * General notes:
- *
- * - All ACSI devices (disks, CD-ROMs, ...) use major number 28.
- * Minors are organized like it is with SCSI: The upper 4 bits
- * identify the device, the lower 4 bits the partition.
- * The device numbers (the upper 4 bits) are given in the same
- * order as the devices are found on the bus.
- * - Up to 8 LUNs are supported for each target (if CONFIG_ACSI_MULTI_LUN
- * is defined), but only a total of 16 devices (due to minor
- * numbers...). Note that Atari allows only a maximum of 4 targets
- * (i.e. controllers, not devices) on the ACSI bus!
- * - A optimizing scheme similar to SCSI scatter-gather is implemented.
- * - Removable media are supported. After a medium change to device
- * is reinitialized (partition check etc.). Also, if the device
- * knows the PREVENT/ALLOW MEDIUM REMOVAL command, the door should
- * be locked and unlocked when mounting the first or unmounting the
- * last filesystem on the device. The code is untested, because I
- * don't have a removable hard disk.
- *
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/genhd.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */
-#include <scsi/scsi_ioctl.h>
-#include <linux/hdreg.h> /* for HDIO_GETGEO */
-#include <linux/blkpg.h>
-#include <linux/buffer_head.h>
-#include <linux/blkdev.h>
-
-#include <asm/setup.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/atarihw.h>
-#include <asm/atariints.h>
-#include <asm/atari_acsi.h>
-#include <asm/atari_stdma.h>
-#include <asm/atari_stram.h>
-
-static void (*do_acsi)(void) = NULL;
-static struct request_queue *acsi_queue;
-#define QUEUE (acsi_queue)
-#define CURRENT elv_next_request(acsi_queue)
-
-#define DEBUG
-#undef DEBUG_DETECT
-#undef NO_WRITE
-
-#define MAX_ERRORS 8 /* Max read/write errors/sector */
-#define MAX_LUN 8 /* Max LUNs per target */
-#define MAX_DEV 16
-
-#define ACSI_BUFFER_SIZE (16*1024) /* "normal" ACSI buffer size */
-#define ACSI_BUFFER_MINSIZE (2048) /* min. buf size if ext. DMA */
-#define ACSI_BUFFER_SIZE_ORDER 2 /* order size for above */
-#define ACSI_BUFFER_MINSIZE_ORDER 0 /* order size for above */
-#define ACSI_BUFFER_SECTORS (ACSI_BUFFER_SIZE/512)
-
-#define ACSI_BUFFER_ORDER \
- (ATARIHW_PRESENT(EXTD_DMA) ? \
- ACSI_BUFFER_MINSIZE_ORDER : \
- ACSI_BUFFER_SIZE_ORDER)
-
-#define ACSI_TIMEOUT (4*HZ)
-
-/* minimum delay between two commands */
-
-#define COMMAND_DELAY 500
-
-typedef enum {
- NONE, HARDDISK, CDROM
-} ACSI_TYPE;
-
-struct acsi_info_struct {
- ACSI_TYPE type; /* type of device */
- unsigned target; /* target number */
- unsigned lun; /* LUN in target controller */
- unsigned removable : 1; /* Flag for removable media */
- unsigned read_only : 1; /* Flag for read only devices */
- unsigned old_atari_disk : 1; /* Is an old Atari disk */
- unsigned changed : 1; /* Medium has been changed */
- unsigned long size; /* #blocks */
- int access_count;
-} acsi_info[MAX_DEV];
-
-/*
- * SENSE KEYS
- */
-
-#define NO_SENSE 0x00
-#define RECOVERED_ERROR 0x01
-#define NOT_READY 0x02
-#define MEDIUM_ERROR 0x03
-#define HARDWARE_ERROR 0x04
-#define ILLEGAL_REQUEST 0x05
-#define UNIT_ATTENTION 0x06
-#define DATA_PROTECT 0x07
-#define BLANK_CHECK 0x08
-#define COPY_ABORTED 0x0a
-#define ABORTED_COMMAND 0x0b
-#define VOLUME_OVERFLOW 0x0d
-#define MISCOMPARE 0x0e
-
-
-/*
- * DEVICE TYPES
- */
-
-#define TYPE_DISK 0x00
-#define TYPE_TAPE 0x01
-#define TYPE_WORM 0x04
-#define TYPE_ROM 0x05
-#define TYPE_MOD 0x07
-#define TYPE_NO_LUN 0x7f
-
-/* The data returned by MODE SENSE differ between the old Atari
- * hard disks and SCSI disks connected to ACSI. In the following, both
- * formats are defined and some macros to operate on them potably.
- */
-
-typedef struct {
- unsigned long dummy[2];
- unsigned long sector_size;
- unsigned char format_code;
-#define ATARI_SENSE_FORMAT_FIX 1
-#define ATARI_SENSE_FORMAT_CHNG 2
- unsigned char cylinders_h;
- unsigned char cylinders_l;
- unsigned char heads;
- unsigned char reduced_h;
- unsigned char reduced_l;
- unsigned char precomp_h;
- unsigned char precomp_l;
- unsigned char landing_zone;
- unsigned char steprate;
- unsigned char type;
-#define ATARI_SENSE_TYPE_FIXCHNG_MASK 4
-#define ATARI_SENSE_TYPE_SOFTHARD_MASK 8
-#define ATARI_SENSE_TYPE_FIX 4
-#define ATARI_SENSE_TYPE_CHNG 0
-#define ATARI_SENSE_TYPE_SOFT 0
-#define ATARI_SENSE_TYPE_HARD 8
- unsigned char sectors;
-} ATARI_SENSE_DATA;
-
-#define ATARI_CAPACITY(sd) \
- (((int)((sd).cylinders_h<<8)|(sd).cylinders_l) * \
- (sd).heads * (sd).sectors)
-
-
-typedef struct {
- unsigned char dummy1;
- unsigned char medium_type;
- unsigned char dummy2;
- unsigned char descriptor_size;
- unsigned long block_count;
- unsigned long sector_size;
- /* Page 0 data */
- unsigned char page_code;
- unsigned char page_size;
- unsigned char page_flags;
- unsigned char qualifier;
-} SCSI_SENSE_DATA;
-
-#define SCSI_CAPACITY(sd) ((sd).block_count & 0xffffff)
-
-
-typedef union {
- ATARI_SENSE_DATA atari;
- SCSI_SENSE_DATA scsi;
-} SENSE_DATA;
-
-#define SENSE_TYPE_UNKNOWN 0
-#define SENSE_TYPE_ATARI 1
-#define SENSE_TYPE_SCSI 2
-
-#define SENSE_TYPE(sd) \
- (((sd).atari.dummy[0] == 8 && \
- ((sd).atari.format_code == 1 || \
- (sd).atari.format_code == 2)) ? SENSE_TYPE_ATARI : \
- ((sd).scsi.dummy1 >= 11) ? SENSE_TYPE_SCSI : \
- SENSE_TYPE_UNKNOWN)
-
-#define CAPACITY(sd) \
- (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \
- ATARI_CAPACITY((sd).atari) : \
- SCSI_CAPACITY((sd).scsi))
-
-#define SECTOR_SIZE(sd) \
- (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \
- (sd).atari.sector_size : \
- (sd).scsi.sector_size & 0xffffff)
-
-/* Default size if capacity cannot be determined (1 GByte) */
-#define DEFAULT_SIZE 0x1fffff
-
-#define CARTRCH_STAT(aip,buf) \
- (aip->old_atari_disk ? \
- (((buf)[0] & 0x7f) == 0x28) : \
- ((((buf)[0] & 0x70) == 0x70) ? \
- (((buf)[2] & 0x0f) == 0x06) : \
- (((buf)[0] & 0x0f) == 0x06))) \
-
-/* These two are also exported to other drivers that work on the ACSI bus and
- * need an ST-RAM buffer. */
-char *acsi_buffer;
-unsigned long phys_acsi_buffer;
-
-static int NDevices;
-
-static int CurrentNReq;
-static int CurrentNSect;
-static char *CurrentBuffer;
-
-static DEFINE_SPINLOCK(acsi_lock);
-
-
-#define SET_TIMER() mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT)
-#define CLEAR_TIMER() del_timer(&acsi_timer)
-
-static unsigned long STramMask;
-#define STRAM_ADDR(a) (((a) & STramMask) == 0)
-
-
-
-/* ACSI commands */
-
-static char tur_cmd[6] = { 0x00, 0, 0, 0, 0, 0 };
-static char modesense_cmd[6] = { 0x1a, 0, 0, 0, 24, 0 };
-static char modeselect_cmd[6] = { 0x15, 0, 0, 0, 12, 0 };
-static char inquiry_cmd[6] = { 0x12, 0, 0, 0,255, 0 };
-static char reqsense_cmd[6] = { 0x03, 0, 0, 0, 4, 0 };
-static char read_cmd[6] = { 0x08, 0, 0, 0, 0, 0 };
-static char write_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 };
-static char pa_med_rem_cmd[6] = { 0x1e, 0, 0, 0, 0, 0 };
-
-#define CMDSET_TARG_LUN(cmd,targ,lun) \
- do { \
- cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \
- cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \
- } while(0)
-
-#define CMDSET_BLOCK(cmd,blk) \
- do { \
- unsigned long __blk = (blk); \
- cmd[3] = __blk; __blk >>= 8; \
- cmd[2] = __blk; __blk >>= 8; \
- cmd[1] = (cmd[1] & 0xe0) | (__blk & 0x1f); \
- } while(0)
-
-#define CMDSET_LEN(cmd,len) \
- do { \
- cmd[4] = (len); \
- } while(0)
-
-/* ACSI errors (from REQUEST SENSE); There are two tables, one for the
- * old Atari disks and one for SCSI on ACSI disks.
- */
-
-struct acsi_error {
- unsigned char code;
- const char *text;
-} atari_acsi_errors[] = {
- { 0x00, "No error (??)" },
- { 0x01, "No index pulses" },
- { 0x02, "Seek not complete" },
- { 0x03, "Write fault" },
- { 0x04, "Drive not ready" },
- { 0x06, "No Track 00 signal" },
- { 0x10, "ECC error in ID field" },
- { 0x11, "Uncorrectable data error" },
- { 0x12, "ID field address mark not found" },
- { 0x13, "Data field address mark not found" },
- { 0x14, "Record not found" },
- { 0x15, "Seek error" },
- { 0x18, "Data check in no retry mode" },
- { 0x19, "ECC error during verify" },
- { 0x1a, "Access to bad block" },
- { 0x1c, "Unformatted or bad format" },
- { 0x20, "Invalid command" },
- { 0x21, "Invalid block address" },
- { 0x23, "Volume overflow" },
- { 0x24, "Invalid argument" },
- { 0x25, "Invalid drive number" },
- { 0x26, "Byte zero parity check" },
- { 0x28, "Cartride changed" },
- { 0x2c, "Error count overflow" },
- { 0x30, "Controller selftest failed" }
-},
-
- scsi_acsi_errors[] = {
- { 0x00, "No error (??)" },
- { 0x01, "Recovered error" },
- { 0x02, "Drive not ready" },
- { 0x03, "Uncorrectable medium error" },
- { 0x04, "Hardware error" },
- { 0x05, "Illegal request" },
- { 0x06, "Unit attention (Reset or cartridge changed)" },
- { 0x07, "Data protection" },
- { 0x08, "Blank check" },
- { 0x0b, "Aborted Command" },
- { 0x0d, "Volume overflow" }
-};
-
-
-
-/***************************** Prototypes *****************************/
-
-static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
- rwflag, int enable);
-static int acsi_reqsense( char *buffer, int targ, int lun);
-static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip);
-static irqreturn_t acsi_interrupt (int irq, void *data);
-static void unexpected_acsi_interrupt( void );
-static void bad_rw_intr( void );
-static void read_intr( void );
-static void write_intr( void);
-static void acsi_times_out( unsigned long dummy );
-static void copy_to_acsibuffer( void );
-static void copy_from_acsibuffer( void );
-static void do_end_requests( void );
-static void do_acsi_request( request_queue_t * );
-static void redo_acsi_request( void );
-static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int
- cmd, unsigned long arg );
-static int acsi_open( struct inode * inode, struct file * filp );
-static int acsi_release( struct inode * inode, struct file * file );
-static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag );
-static int acsi_change_blk_size( int target, int lun);
-static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
-static int acsi_revalidate (struct gendisk *disk);
-
-/************************* End of Prototypes **************************/
-
-
-DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0);
-
-
-#ifdef CONFIG_ATARI_SLM
-
-extern int attach_slm( int target, int lun );
-extern int slm_init( void );
-
-#endif
-
-
-
-/***********************************************************************
- *
- * ACSI primitives
- *
- **********************************************************************/
-
-
-/*
- * The following two functions wait for _IRQ to become Low or High,
- * resp., with a timeout. The 'timeout' parameter is in jiffies
- * (10ms).
- * If the functions are called with timer interrupts on (int level <
- * 6), the timeout is based on the 'jiffies' variable to provide exact
- * timeouts for device probing etc.
- * If interrupts are disabled, the number of tries is based on the
- * 'loops_per_jiffy' variable. A rough estimation is sufficient here...
- */
-
-#define INT_LEVEL \
- ({ unsigned __sr; \
- __asm__ __volatile__ ( "movew %/sr,%0" : "=dm" (__sr) ); \
- (__sr >> 8) & 7; \
- })
-
-int acsi_wait_for_IRQ( unsigned timeout )
-
-{
- if (INT_LEVEL < 6) {
- unsigned long maxjif = jiffies + timeout;
- while (time_before(jiffies, maxjif))
- if (!(mfp.par_dt_reg & 0x20)) return( 1 );
- }
- else {
- long tries = loops_per_jiffy / 8 * timeout;
- while( --tries >= 0 )
- if (!(mfp.par_dt_reg & 0x20)) return( 1 );
- }
- return( 0 ); /* timeout! */
-}
-
-
-int acsi_wait_for_noIRQ( unsigned timeout )
-
-{
- if (INT_LEVEL < 6) {
- unsigned long maxjif = jiffies + timeout;
- while (time_before(jiffies, maxjif))
- if (mfp.par_dt_reg & 0x20) return( 1 );
- }
- else {
- long tries = loops_per_jiffy * timeout / 8;
- while( tries-- >= 0 )
- if (mfp.par_dt_reg & 0x20) return( 1 );
- }
- return( 0 ); /* timeout! */
-}
-
-static struct timeval start_time;
-
-void
-acsi_delay_start(void)
-{
- do_gettimeofday(&start_time);
-}
-
-/* wait from acsi_delay_start to now usec (<1E6) usec */
-
-void
-acsi_delay_end(long usec)
-{
- struct timeval end_time;
- long deltau,deltas;
- do_gettimeofday(&end_time);
- deltau=end_time.tv_usec - start_time.tv_usec;
- deltas=end_time.tv_sec - start_time.tv_sec;
- if (deltas > 1 || deltas < 0)
- return;
- if (deltas > 0)
- deltau += 1000*1000;
- if (deltau >= usec)
- return;
- udelay(usec-deltau);
-}
-
-/* acsicmd_dma() sends an ACSI command and sets up the DMA to transfer
- * 'blocks' blocks of 512 bytes from/to 'buffer'.
- * Because the _IRQ signal is used for handshaking the command bytes,
- * the ACSI interrupt has to be disabled in this function. If the end
- * of the operation should be signalled by a real interrupt, it has to be
- * reenabled afterwards.
- */
-
-static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag, int enable)
-
-{ unsigned long flags, paddr;
- int i;
-
-#ifdef NO_WRITE
- if (rwflag || *cmd == 0x0a) {
- printk( "ACSI: Write commands disabled!\n" );
- return( 0 );
- }
-#endif
-
- rwflag = rwflag ? 0x100 : 0;
- paddr = virt_to_phys( buffer );
-
- acsi_delay_end(COMMAND_DELAY);
- DISABLE_IRQ();
-
- local_irq_save(flags);
- /* Low on A1 */
- dma_wd.dma_mode_status = 0x88 | rwflag;
- MFPDELAY();
-
- /* set DMA address */
- dma_wd.dma_lo = (unsigned char)paddr;
- paddr >>= 8;
- MFPDELAY();
- dma_wd.dma_md = (unsigned char)paddr;
- paddr >>= 8;
- MFPDELAY();
- if (ATARIHW_PRESENT(EXTD_DMA))
- st_dma_ext_dmahi = (unsigned short)paddr;
- else
- dma_wd.dma_hi = (unsigned char)paddr;
- MFPDELAY();
- local_irq_restore(flags);
-
- /* send the command bytes except the last */
- for( i = 0; i < 5; ++i ) {
- DMA_LONG_WRITE( *cmd++, 0x8a | rwflag );
- udelay(20);
- if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
- }
-
- /* Clear FIFO and switch DMA to correct direction */
- dma_wd.dma_mode_status = 0x92 | (rwflag ^ 0x100);
- MFPDELAY();
- dma_wd.dma_mode_status = 0x92 | rwflag;
- MFPDELAY();
-
- /* How many sectors for DMA */
- dma_wd.fdc_acces_seccount = blocks;
- MFPDELAY();
-
- /* send last command byte */
- dma_wd.dma_mode_status = 0x8a | rwflag;
- MFPDELAY();
- DMA_LONG_WRITE( *cmd++, 0x0a | rwflag );
- if (enable)
- ENABLE_IRQ();
- udelay(80);
-
- return( 1 );
-}
-
-
-/*
- * acsicmd_nodma() sends an ACSI command that requires no DMA.
- */
-
-int acsicmd_nodma( const char *cmd, int enable)
-
-{ int i;
-
- acsi_delay_end(COMMAND_DELAY);
- DISABLE_IRQ();
-
- /* send first command byte */
- dma_wd.dma_mode_status = 0x88;
- MFPDELAY();
- DMA_LONG_WRITE( *cmd++, 0x8a );
- udelay(20);
- if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
-
- /* send the intermediate command bytes */
- for( i = 0; i < 4; ++i ) {
- DMA_LONG_WRITE( *cmd++, 0x8a );
- udelay(20);
- if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
- }
-
- /* send last command byte */
- DMA_LONG_WRITE( *cmd++, 0x0a );
- if (enable)
- ENABLE_IRQ();
- udelay(80);
-
- return( 1 );
- /* Note that the ACSI interrupt is still disabled after this
- * function. If you want to get the IRQ delivered, enable it manually!
- */
-}
-
-
-static int acsi_reqsense( char *buffer, int targ, int lun)
-
-{
- CMDSET_TARG_LUN( reqsense_cmd, targ, lun);
- if (!acsicmd_dma( reqsense_cmd, buffer, 1, 0, 0 )) return( 0 );
- if (!acsi_wait_for_IRQ( 10 )) return( 0 );
- acsi_getstatus();
- if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
- if (!acsi_wait_for_IRQ( 10 )) return( 0 );
- acsi_getstatus();
- if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
- if (!acsi_wait_for_IRQ( 10 )) return( 0 );
- acsi_getstatus();
- if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
- if (!acsi_wait_for_IRQ( 10 )) return( 0 );
- acsi_getstatus();
- dma_cache_maintenance( virt_to_phys(buffer), 16, 0 );
-
- return( 1 );
-}
-
-
-/*
- * ACSI status phase: get the status byte from the bus
- *
- * I've seen several times that a 0xff status is read, propably due to
- * a timing error. In this case, the procedure is repeated after the
- * next _IRQ edge.
- */
-
-int acsi_getstatus( void )
-
-{ int status;
-
- DISABLE_IRQ();
- for(;;) {
- if (!acsi_wait_for_IRQ( 100 )) {
- acsi_delay_start();
- return( -1 );
- }
- dma_wd.dma_mode_status = 0x8a;
- MFPDELAY();
- status = dma_wd.fdc_acces_seccount;
- if (status != 0xff) break;
-#ifdef DEBUG
- printk("ACSI: skipping 0xff status byte\n" );
-#endif
- udelay(40);
- acsi_wait_for_noIRQ( 20 );
- }
- dma_wd.dma_mode_status = 0x80;
- udelay(40);
- acsi_wait_for_noIRQ( 20 );
-
- acsi_delay_start();
- return( status & 0x1f ); /* mask of the device# */
-}
-
-
-#if (defined(CONFIG_ATARI_SLM) || defined(CONFIG_ATARI_SLM_MODULE))
-
-/* Receive data in an extended status phase. Needed by SLM printer. */
-
-int acsi_extstatus( char *buffer, int cnt )
-
-{ int status;
-
- DISABLE_IRQ();
- udelay(80);
- while( cnt-- > 0 ) {
- if (!acsi_wait_for_IRQ( 40 )) return( 0 );
- dma_wd.dma_mode_status = 0x8a;
- MFPDELAY();
- status = dma_wd.fdc_acces_seccount;
- MFPDELAY();
- *buffer++ = status & 0xff;
- udelay(40);
- }
- return( 1 );
-}
-
-
-/* Finish an extended status phase */
-
-void acsi_end_extstatus( void )
-
-{
- dma_wd.dma_mode_status = 0x80;
- udelay(40);
- acsi_wait_for_noIRQ( 20 );
- acsi_delay_start();
-}
-
-
-/* Send data in an extended command phase */
-
-int acsi_extcmd( unsigned char *buffer, int cnt )
-
-{
- while( cnt-- > 0 ) {
- DMA_LONG_WRITE( *buffer++, 0x8a );
- udelay(20);
- if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
- }
- return( 1 );
-}
-
-#endif
-
-
-static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip)
-
-{ int atari_err, i, errcode;
- struct acsi_error *arr;
-
- atari_err = aip->old_atari_disk;
- if (atari_err)
- errcode = errblk[0] & 0x7f;
- else
- if ((errblk[0] & 0x70) == 0x70)
- errcode = errblk[2] & 0x0f;
- else
- errcode = errblk[0] & 0x0f;
-
- printk( KERN_ERR "ACSI error 0x%02x", errcode );
-
- if (errblk[0] & 0x80)
- printk( " for sector %d",
- ((errblk[1] & 0x1f) << 16) |
- (errblk[2] << 8) | errblk[0] );
-
- arr = atari_err ? atari_acsi_errors : scsi_acsi_errors;
- i = atari_err ? sizeof(atari_acsi_errors)/sizeof(*atari_acsi_errors) :
- sizeof(scsi_acsi_errors)/sizeof(*scsi_acsi_errors);
-
- for( --i; i >= 0; --i )
- if (arr[i].code == errcode) break;
- if (i >= 0)
- printk( ": %s\n", arr[i].text );
-}
-
-/*******************************************************************
- *
- * ACSI interrupt routine
- * Test, if this is a ACSI interrupt and call the irq handler
- * Otherwise ignore this interrupt.
- *
- *******************************************************************/
-
-static irqreturn_t acsi_interrupt(int irq, void *data )
-
-{ void (*acsi_irq_handler)(void) = do_acsi;
-
- do_acsi = NULL;
- CLEAR_TIMER();
-
- if (!acsi_irq_handler)
- acsi_irq_handler = unexpected_acsi_interrupt;
- acsi_irq_handler();
- return IRQ_HANDLED;
-}
-
-
-/******************************************************************
- *
- * The Interrupt handlers
- *
- *******************************************************************/
-
-
-static void unexpected_acsi_interrupt( void )
-
-{
- printk( KERN_WARNING "Unexpected ACSI interrupt\n" );
-}
-
-
-/* This function is called in case of errors. Because we cannot reset
- * the ACSI bus or a single device, there is no other choice than
- * retrying several times :-(
- */
-
-static void bad_rw_intr( void )
-
-{
- if (!CURRENT)
- return;
-
- if (++CURRENT->errors >= MAX_ERRORS)
- end_request(CURRENT, 0);
- /* Otherwise just retry */
-}
-
-
-static void read_intr( void )
-
-{ int status;
-
- status = acsi_getstatus();
- if (status != 0) {
- struct gendisk *disk = CURRENT->rq_disk;
- struct acsi_info_struct *aip = disk->private_data;
- printk(KERN_ERR "%s: ", disk->disk_name);
- if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun))
- printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
- else {
- acsi_print_error(acsi_buffer, aip);
- if (CARTRCH_STAT(aip, acsi_buffer))
- aip->changed = 1;
- }
- ENABLE_IRQ();
- bad_rw_intr();
- redo_acsi_request();
- return;
- }
-
- dma_cache_maintenance( virt_to_phys(CurrentBuffer), CurrentNSect*512, 0 );
- if (CurrentBuffer == acsi_buffer)
- copy_from_acsibuffer();
-
- do_end_requests();
- redo_acsi_request();
-}
-
-
-static void write_intr(void)
-
-{ int status;
-
- status = acsi_getstatus();
- if (status != 0) {
- struct gendisk *disk = CURRENT->rq_disk;
- struct acsi_info_struct *aip = disk->private_data;
- printk( KERN_ERR "%s: ", disk->disk_name);
- if (!acsi_reqsense( acsi_buffer, aip->target, aip->lun))
- printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
- else {
- acsi_print_error(acsi_buffer, aip);
- if (CARTRCH_STAT(aip, acsi_buffer))
- aip->changed = 1;
- }
- bad_rw_intr();
- redo_acsi_request();
- return;
- }
-
- do_end_requests();
- redo_acsi_request();
-}
-
-
-static void acsi_times_out( unsigned long dummy )
-
-{
- DISABLE_IRQ();
- if (!do_acsi) return;
-
- do_acsi = NULL;
- printk( KERN_ERR "ACSI timeout\n" );
- if (!CURRENT)
- return;
- if (++CURRENT->errors >= MAX_ERRORS) {
-#ifdef DEBUG
- printk( KERN_ERR "ACSI: too many errors.\n" );
-#endif
- end_request(CURRENT, 0);
- }
-
- redo_acsi_request();
-}
-
-
-
-/***********************************************************************
- *
- * Scatter-gather utility functions
- *
- ***********************************************************************/
-
-
-static void copy_to_acsibuffer( void )
-
-{ int i;
- char *src, *dst;
- struct buffer_head *bh;
-
- src = CURRENT->buffer;
- dst = acsi_buffer;
- bh = CURRENT->bh;
-
- if (!bh)
- memcpy( dst, src, CurrentNSect*512 );
- else
- for( i = 0; i < CurrentNReq; ++i ) {
- memcpy( dst, src, bh->b_size );
- dst += bh->b_size;
- if ((bh = bh->b_reqnext))
- src = bh->b_data;
- }
-}
-
-
-static void copy_from_acsibuffer( void )
-
-{ int i;
- char *src, *dst;
- struct buffer_head *bh;
-
- dst = CURRENT->buffer;
- src = acsi_buffer;
- bh = CURRENT->bh;
-
- if (!bh)
- memcpy( dst, src, CurrentNSect*512 );
- else
- for( i = 0; i < CurrentNReq; ++i ) {
- memcpy( dst, src, bh->b_size );
- src += bh->b_size;
- if ((bh = bh->b_reqnext))
- dst = bh->b_data;
- }
-}
-
-
-static void do_end_requests( void )
-
-{ int i, n;
-
- if (!CURRENT->bh) {
- CURRENT->nr_sectors -= CurrentNSect;
- CURRENT->current_nr_sectors -= CurrentNSect;
- CURRENT->sector += CurrentNSect;
- if (CURRENT->nr_sectors == 0)
- end_request(CURRENT, 1);
- }
- else {
- for( i = 0; i < CurrentNReq; ++i ) {
- n = CURRENT->bh->b_size >> 9;
- CURRENT->nr_sectors -= n;
- CURRENT->current_nr_sectors -= n;
- CURRENT->sector += n;
- end_request(CURRENT, 1);
- }
- }
-}
-
-
-
-
-/***********************************************************************
- *
- * do_acsi_request and friends
- *
- ***********************************************************************/
-
-static void do_acsi_request( request_queue_t * q )
-
-{
- stdma_lock( acsi_interrupt, NULL );
- redo_acsi_request();
-}
-
-
-static void redo_acsi_request( void )
-{
- unsigned block, target, lun, nsect;
- char *buffer;
- unsigned long pbuffer;
- struct buffer_head *bh;
- struct gendisk *disk;
- struct acsi_info_struct *aip;
-
- repeat:
- CLEAR_TIMER();
-
- if (do_acsi)
- return;
-
- if (!CURRENT) {
- do_acsi = NULL;
- ENABLE_IRQ();
- stdma_release();
- return;
- }
-
- disk = CURRENT->rq_disk;
- aip = disk->private_data;
- if (CURRENT->bh) {
- if (!CURRENT->bh && !buffer_locked(CURRENT->bh))
- panic("ACSI: block not locked");
- }
-
- block = CURRENT->sector;
- if (block+CURRENT->nr_sectors >= get_capacity(disk)) {
-#ifdef DEBUG
- printk( "%s: attempted access for blocks %d...%ld past end of device at block %ld.\n",
- disk->disk_name,
- block, block + CURRENT->nr_sectors - 1,
- get_capacity(disk));
-#endif
- end_request(CURRENT, 0);
- goto repeat;
- }
- if (aip->changed) {
- printk( KERN_NOTICE "%s: request denied because cartridge has "
- "been changed.\n", disk->disk_name);
- end_request(CURRENT, 0);
- goto repeat;
- }
-
- target = aip->target;
- lun = aip->lun;
-
- /* Find out how many sectors should be transferred from/to
- * consecutive buffers and thus can be done with a single command.
- */
- buffer = CURRENT->buffer;
- pbuffer = virt_to_phys(buffer);
- nsect = CURRENT->current_nr_sectors;
- CurrentNReq = 1;
-
- if ((bh = CURRENT->bh) && bh != CURRENT->bhtail) {
- if (!STRAM_ADDR(pbuffer)) {
- /* If transfer is done via the ACSI buffer anyway, we can
- * assemble as much bh's as fit in the buffer.
- */
- while( (bh = bh->b_reqnext) ) {
- if (nsect + (bh->b_size>>9) > ACSI_BUFFER_SECTORS) break;
- nsect += bh->b_size >> 9;
- ++CurrentNReq;
- if (bh == CURRENT->bhtail) break;
- }
- buffer = acsi_buffer;
- pbuffer = phys_acsi_buffer;
- }
- else {
- unsigned long pendadr, pnewadr;
- pendadr = pbuffer + nsect*512;
- while( (bh = bh->b_reqnext) ) {
- pnewadr = virt_to_phys(bh->b_data);
- if (!STRAM_ADDR(pnewadr) || pendadr != pnewadr) break;
- nsect += bh->b_size >> 9;
- pendadr = pnewadr + bh->b_size;
- ++CurrentNReq;
- if (bh == CURRENT->bhtail) break;
- }
- }
- }
- else {
- if (!STRAM_ADDR(pbuffer)) {
- buffer = acsi_buffer;
- pbuffer = phys_acsi_buffer;
- if (nsect > ACSI_BUFFER_SECTORS)
- nsect = ACSI_BUFFER_SECTORS;
- }
- }
- CurrentBuffer = buffer;
- CurrentNSect = nsect;
-
- if (rq_data_dir(CURRENT) == WRITE) {
- CMDSET_TARG_LUN( write_cmd, target, lun );
- CMDSET_BLOCK( write_cmd, block );
- CMDSET_LEN( write_cmd, nsect );
- if (buffer == acsi_buffer)
- copy_to_acsibuffer();
- dma_cache_maintenance( pbuffer, nsect*512, 1 );
- do_acsi = write_intr;
- if (!acsicmd_dma( write_cmd, buffer, nsect, 1, 1)) {
- do_acsi = NULL;
- printk( KERN_ERR "ACSI (write): Timeout in command block\n" );
- bad_rw_intr();
- goto repeat;
- }
- SET_TIMER();
- return;
- }
- if (rq_data_dir(CURRENT) == READ) {
- CMDSET_TARG_LUN( read_cmd, target, lun );
- CMDSET_BLOCK( read_cmd, block );
- CMDSET_LEN( read_cmd, nsect );
- do_acsi = read_intr;
- if (!acsicmd_dma( read_cmd, buffer, nsect, 0, 1)) {
- do_acsi = NULL;
- printk( KERN_ERR "ACSI (read): Timeout in command block\n" );
- bad_rw_intr();
- goto repeat;
- }
- SET_TIMER();
- return;
- }
- panic("unknown ACSI command");
-}
-
-
-
-/***********************************************************************
- *
- * Misc functions: ioctl, open, release, check_change, ...
- *
- ***********************************************************************/
-
-static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
- struct acsi_info_struct *aip = bdev->bd_disk->private_data;
-
- /*
- * Just fake some geometry here, it's nonsense anyway
- * To make it easy, use Adaptec's usual 64/32 mapping
- */
- geo->heads = 64;
- geo->sectors = 32;
- geo->cylinders = aip->size >> 11;
- return 0;
-}
-
-static int acsi_ioctl( struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg )
-{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct acsi_info_struct *aip = disk->private_data;
- switch (cmd) {
- case SCSI_IOCTL_GET_IDLUN:
- /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
- put_user( aip->target | (aip->lun << 8),
- &((Scsi_Idlun *) arg)->dev_id );
- put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-/*
- * Open a device, check for read-only and lock the medium if it is
- * removable.
- *
- * Changes by Martin Rogge, 9th Aug 1995:
- * Check whether check_disk_change (and therefore revalidate_acsidisk)
- * was successful. They fail when there is no medium in the drive.
- *
- * The problem of media being changed during an operation can be
- * ignored because of the prevent_removal code.
- *
- * Added check for the validity of the device number.
- *
- */
-
-static int acsi_open( struct inode * inode, struct file * filp )
-{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct acsi_info_struct *aip = disk->private_data;
-
- if (aip->access_count == 0 && aip->removable) {
-#if 0
- aip->changed = 1; /* safety first */
-#endif
- check_disk_change( inode->i_bdev );
- if (aip->changed) /* revalidate was not successful (no medium) */
- return -ENXIO;
- acsi_prevent_removal(aip, 1);
- }
- aip->access_count++;
-
- if (filp && filp->f_mode) {
- check_disk_change( inode->i_bdev );
- if (filp->f_mode & 2) {
- if (aip->read_only) {
- acsi_release( inode, filp );
- return -EROFS;
- }
- }
- }
-
- return 0;
-}
-
-/*
- * Releasing a block device means we sync() it, so that it can safely
- * be forgotten about...
- */
-
-static int acsi_release( struct inode * inode, struct file * file )
-{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct acsi_info_struct *aip = disk->private_data;
- if (--aip->access_count == 0 && aip->removable)
- acsi_prevent_removal(aip, 0);
- return( 0 );
-}
-
-/*
- * Prevent or allow a media change for removable devices.
- */
-
-static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag)
-{
- stdma_lock( NULL, NULL );
-
- CMDSET_TARG_LUN(pa_med_rem_cmd, aip->target, aip->lun);
- CMDSET_LEN( pa_med_rem_cmd, flag );
-
- if (acsicmd_nodma(pa_med_rem_cmd, 0) && acsi_wait_for_IRQ(3*HZ))
- acsi_getstatus();
- /* Do not report errors -- some devices may not know this command. */
-
- ENABLE_IRQ();
- stdma_release();
-}
-
-static int acsi_media_change(struct gendisk *disk)
-{
- struct acsi_info_struct *aip = disk->private_data;
-
- if (!aip->removable)
- return 0;
-
- if (aip->changed)
- /* We can be sure that the medium has been changed -- REQUEST
- * SENSE has reported this earlier.
- */
- return 1;
-
- /* If the flag isn't set, make a test by reading block 0.
- * If errors happen, it seems to be better to say "changed"...
- */
- stdma_lock( NULL, NULL );
- CMDSET_TARG_LUN(read_cmd, aip->target, aip->lun);
- CMDSET_BLOCK( read_cmd, 0 );
- CMDSET_LEN( read_cmd, 1 );
- if (acsicmd_dma(read_cmd, acsi_buffer, 1, 0, 0) &&
- acsi_wait_for_IRQ(3*HZ)) {
- if (acsi_getstatus()) {
- if (acsi_reqsense(acsi_buffer, aip->target, aip->lun)) {
- if (CARTRCH_STAT(aip, acsi_buffer))
- aip->changed = 1;
- }
- else {
- printk( KERN_ERR "%s: REQUEST SENSE failed in test for "
- "medium change; assuming a change\n", disk->disk_name );
- aip->changed = 1;
- }
- }
- }
- else {
- printk( KERN_ERR "%s: Test for medium changed timed out; "
- "assuming a change\n", disk->disk_name);
- aip->changed = 1;
- }
- ENABLE_IRQ();
- stdma_release();
-
- /* Now, after reading a block, the changed status is surely valid. */
- return aip->changed;
-}
-
-
-static int acsi_change_blk_size( int target, int lun)
-
-{ int i;
-
- for (i=0; i<12; i++)
- acsi_buffer[i] = 0;
-
- acsi_buffer[3] = 8;
- acsi_buffer[10] = 2;
- CMDSET_TARG_LUN( modeselect_cmd, target, lun);
-
- if (!acsicmd_dma( modeselect_cmd, acsi_buffer, 1,1,0) ||
- !acsi_wait_for_IRQ( 3*HZ ) ||
- acsi_getstatus() != 0 ) {
- return(0);
- }
- return(1);
-}
-
-
-static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd )
-
-{
- int page;
-
- CMDSET_TARG_LUN( modesense_cmd, target, lun );
- for (page=0; page<4; page++) {
- modesense_cmd[2] = page;
- if (!acsicmd_dma( modesense_cmd, acsi_buffer, 1, 0, 0 ) ||
- !acsi_wait_for_IRQ( 3*HZ ) ||
- acsi_getstatus())
- continue;
-
- /* read twice to jump over the second 16-byte border! */
- udelay(300);
- if (acsi_wait_for_noIRQ( 20 ) &&
- acsicmd_nodma( modesense_cmd, 0 ) &&
- acsi_wait_for_IRQ( 3*HZ ) &&
- acsi_getstatus() == 0)
- break;
- }
- if (page == 4) {
- return(0);
- }
-
- dma_cache_maintenance( phys_acsi_buffer, sizeof(SENSE_DATA), 0 );
- *sd = *(SENSE_DATA *)acsi_buffer;
-
- /* Validity check, depending on type of data */
-
- switch( SENSE_TYPE(*sd) ) {
-
- case SENSE_TYPE_ATARI:
- if (CAPACITY(*sd) == 0)
- goto invalid_sense;
- break;
-
- case SENSE_TYPE_SCSI:
- if (sd->scsi.descriptor_size != 8)
- goto invalid_sense;
- break;
-
- case SENSE_TYPE_UNKNOWN:
-
- printk( KERN_ERR "ACSI target %d, lun %d: Cannot interpret "
- "sense data\n", target, lun );
-
- invalid_sense:
-
-#ifdef DEBUG
- { int i;
- printk( "Mode sense data for ACSI target %d, lun %d seem not valid:",
- target, lun );
- for( i = 0; i < sizeof(SENSE_DATA); ++i )
- printk( "%02x ", (unsigned char)acsi_buffer[i] );
- printk( "\n" );
- }
-#endif
- return( 0 );
- }
-
- return( 1 );
-}
-
-
-
-/*******************************************************************
- *
- * Initialization
- *
- ********************************************************************/
-
-
-extern struct block_device_operations acsi_fops;
-
-static struct gendisk *acsi_gendisk[MAX_DEV];
-
-#define MAX_SCSI_DEVICE_CODE 10
-
-static const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
-{
- "Direct-Access ",
- "Sequential-Access",
- "Printer ",
- "Processor ",
- "WORM ",
- "CD-ROM ",
- "Scanner ",
- "Optical Device ",
- "Medium Changer ",
- "Communications "
-};
-
-static void print_inquiry(unsigned char *data)
-{
- int i;
-
- printk(KERN_INFO " Vendor: ");
- for (i = 8; i < 16; i++)
- {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk(" Model: ");
- for (i = 16; i < 32; i++)
- {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk(" Rev: ");
- for (i = 32; i < 36; i++)
- {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk("\n");
-
- i = data[0] & 0x1f;
-
- printk(KERN_INFO " Type: %s ", (i < MAX_SCSI_DEVICE_CODE
- ? scsi_device_types[i]
- : "Unknown "));
- printk(" ANSI SCSI revision: %02x", data[2] & 0x07);
- if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
- printk(" CCS\n");
- else
- printk("\n");
-}
-
-
-/*
- * Changes by Martin Rogge, 9th Aug 1995:
- * acsi_devinit has been taken out of acsi_geninit, because it needs
- * to be called from revalidate_acsidisk. The result of request sense
- * is now checked for DRIVE NOT READY.
- *
- * The structure *aip is only valid when acsi_devinit returns
- * DEV_SUPPORTED.
- *
- */
-
-#define DEV_NONE 0
-#define DEV_UNKNOWN 1
-#define DEV_SUPPORTED 2
-#define DEV_SLM 3
-
-static int acsi_devinit(struct acsi_info_struct *aip)
-{
- int status, got_inquiry;
- SENSE_DATA sense;
- unsigned char reqsense, extsense;
-
- /*****************************************************************/
- /* Do a TEST UNIT READY command to test the presence of a device */
- /*****************************************************************/
-
- CMDSET_TARG_LUN(tur_cmd, aip->target, aip->lun);
- if (!acsicmd_nodma(tur_cmd, 0)) {
- /* timed out -> no device here */
-#ifdef DEBUG_DETECT
- printk("target %d lun %d: timeout\n", aip->target, aip->lun);
-#endif
- return DEV_NONE;
- }
-
- /*************************/
- /* Read the ACSI status. */
- /*************************/
-
- status = acsi_getstatus();
- if (status) {
- if (status == 0x12) {
- /* The SLM printer should be the only device that
- * responds with the error code in the status byte. In
- * correct status bytes, bit 4 is never set.
- */
- printk( KERN_INFO "Detected SLM printer at id %d lun %d\n",
- aip->target, aip->lun);
- return DEV_SLM;
- }
- /* ignore CHECK CONDITION, since some devices send a
- UNIT ATTENTION */
- if ((status & 0x1e) != 0x2) {
-#ifdef DEBUG_DETECT
- printk("target %d lun %d: status %d\n",
- aip->target, aip->lun, status);
-#endif
- return DEV_UNKNOWN;
- }
- }
-
- /*******************************/
- /* Do a REQUEST SENSE command. */
- /*******************************/
-
- if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) {
- printk( KERN_WARNING "acsi_reqsense failed\n");
- acsi_buffer[0] = 0;
- acsi_buffer[2] = UNIT_ATTENTION;
- }
- reqsense = acsi_buffer[0];
- extsense = acsi_buffer[2] & 0xf;
- if (status) {
- if ((reqsense & 0x70) == 0x70) { /* extended sense */
- if (extsense != UNIT_ATTENTION &&
- extsense != NOT_READY) {
-#ifdef DEBUG_DETECT
- printk("target %d lun %d: extended sense %d\n",
- aip->target, aip->lun, extsense);
-#endif
- return DEV_UNKNOWN;
- }
- }
- else {
- if (reqsense & 0x7f) {
-#ifdef DEBUG_DETECT
- printk("target %d lun %d: sense %d\n",
- aip->target, aip->lun, reqsense);
-#endif
- return DEV_UNKNOWN;
- }
- }
- }
- else
- if (reqsense == 0x4) { /* SH204 Bug workaround */
-#ifdef DEBUG_DETECT
- printk("target %d lun %d status=0 sense=4\n",
- aip->target, aip->lun);
-#endif
- return DEV_UNKNOWN;
- }
-
- /***********************************************************/
- /* Do an INQUIRY command to get more infos on this device. */
- /***********************************************************/
-
- /* Assume default values */
- aip->removable = 1;
- aip->read_only = 0;
- aip->old_atari_disk = 0;
- aip->changed = (extsense == NOT_READY); /* medium inserted? */
- aip->size = DEFAULT_SIZE;
- got_inquiry = 0;
- /* Fake inquiry result for old atari disks */
- memcpy(acsi_buffer, "\000\000\001\000 Adaptec 40xx"
- " ", 40);
- CMDSET_TARG_LUN(inquiry_cmd, aip->target, aip->lun);
- if (acsicmd_dma(inquiry_cmd, acsi_buffer, 1, 0, 0) &&
- acsi_getstatus() == 0) {
- acsicmd_nodma(inquiry_cmd, 0);
- acsi_getstatus();
- dma_cache_maintenance( phys_acsi_buffer, 256, 0 );
- got_inquiry = 1;
- aip->removable = !!(acsi_buffer[1] & 0x80);
- }
- if (aip->type == NONE) /* only at boot time */
- print_inquiry(acsi_buffer);
- switch(acsi_buffer[0]) {
- case TYPE_DISK:
- aip->type = HARDDISK;
- break;
- case TYPE_ROM:
- aip->type = CDROM;
- aip->read_only = 1;
- break;
- default:
- return DEV_UNKNOWN;
- }
- /****************************/
- /* Do a MODE SENSE command. */
- /****************************/
-
- if (!acsi_mode_sense(aip->target, aip->lun, &sense)) {
- printk( KERN_WARNING "No mode sense data.\n" );
- return DEV_UNKNOWN;
- }
- if ((SECTOR_SIZE(sense) != 512) &&
- ((aip->type != CDROM) ||
- !acsi_change_blk_size(aip->target, aip->lun) ||
- !acsi_mode_sense(aip->target, aip->lun, &sense) ||
- (SECTOR_SIZE(sense) != 512))) {
- printk( KERN_WARNING "Sector size != 512 not supported.\n" );
- return DEV_UNKNOWN;
- }
- /* There are disks out there that claim to have 0 sectors... */
- if (CAPACITY(sense))
- aip->size = CAPACITY(sense); /* else keep DEFAULT_SIZE */
- if (!got_inquiry && SENSE_TYPE(sense) == SENSE_TYPE_ATARI) {
- /* If INQUIRY failed and the sense data suggest an old
- * Atari disk (SH20x, Megafile), the disk is not removable
- */
- aip->removable = 0;
- aip->old_atari_disk = 1;
- }
-
- /******************/
- /* We've done it. */
- /******************/
-
- return DEV_SUPPORTED;
-}
-
-EXPORT_SYMBOL(acsi_delay_start);
-EXPORT_SYMBOL(acsi_delay_end);
-EXPORT_SYMBOL(acsi_wait_for_IRQ);
-EXPORT_SYMBOL(acsi_wait_for_noIRQ);
-EXPORT_SYMBOL(acsicmd_nodma);
-EXPORT_SYMBOL(acsi_getstatus);
-EXPORT_SYMBOL(acsi_buffer);
-EXPORT_SYMBOL(phys_acsi_buffer);
-
-#ifdef CONFIG_ATARI_SLM_MODULE
-void acsi_attach_SLMs( int (*attach_func)( int, int ) );
-
-EXPORT_SYMBOL(acsi_extstatus);
-EXPORT_SYMBOL(acsi_end_extstatus);
-EXPORT_SYMBOL(acsi_extcmd);
-EXPORT_SYMBOL(acsi_attach_SLMs);
-
-/* to remember IDs of SLM devices, SLM module is loaded later
- * (index is target#, contents is lun#, -1 means "no SLM") */
-int SLM_devices[8];
-#endif
-
-static struct block_device_operations acsi_fops = {
- .owner = THIS_MODULE,
- .open = acsi_open,
- .release = acsi_release,
- .ioctl = acsi_ioctl,
- .getgeo = acsi_getgeo,
- .media_changed = acsi_media_change,
- .revalidate_disk= acsi_revalidate,
-};
-
-#ifdef CONFIG_ATARI_SLM_MODULE
-/* call attach_slm() for each device that is a printer; needed for init of SLM
- * driver as a module, since it's not yet present if acsi.c is inited and thus
- * the bus gets scanned. */
-void acsi_attach_SLMs( int (*attach_func)( int, int ) )
-{
- int i, n = 0;
-
- for( i = 0; i < 8; ++i )
- if (SLM_devices[i] >= 0)
- n += (*attach_func)( i, SLM_devices[i] );
- printk( KERN_INFO "Found %d SLM printer(s) total.\n", n );
-}
-#endif /* CONFIG_ATARI_SLM_MODULE */
-
-
-int acsi_init( void )
-{
- int err = 0;
- int i, target, lun;
- struct acsi_info_struct *aip;
-#ifdef CONFIG_ATARI_SLM
- int n_slm = 0;
-#endif
- if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI))
- return 0;
- if (register_blkdev(ACSI_MAJOR, "ad")) {
- err = -EBUSY;
- goto out1;
- }
- if (!(acsi_buffer =
- (char *)atari_stram_alloc(ACSI_BUFFER_SIZE, "acsi"))) {
- err = -ENOMEM;
- printk( KERN_ERR "Unable to get ACSI ST-Ram buffer.\n" );
- goto out2;
- }
- phys_acsi_buffer = virt_to_phys( acsi_buffer );
- STramMask = ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000;
-
- acsi_queue = blk_init_queue(do_acsi_request, &acsi_lock);
- if (!acsi_queue) {
- err = -ENOMEM;
- goto out2a;
- }
-#ifdef CONFIG_ATARI_SLM
- err = slm_init();
-#endif
- if (err)
- goto out3;
-
- printk( KERN_INFO "Probing ACSI devices:\n" );
- NDevices = 0;
-#ifdef CONFIG_ATARI_SLM_MODULE
- for( i = 0; i < 8; ++i )
- SLM_devices[i] = -1;
-#endif
- stdma_lock(NULL, NULL);
-
- for (target = 0; target < 8 && NDevices < MAX_DEV; ++target) {
- lun = 0;
- do {
- aip = &acsi_info[NDevices];
- aip->type = NONE;
- aip->target = target;
- aip->lun = lun;
- i = acsi_devinit(aip);
- switch (i) {
- case DEV_SUPPORTED:
- printk( KERN_INFO "Detected ");
- switch (aip->type) {
- case HARDDISK:
- printk("disk");
- break;
- case CDROM:
- printk("cdrom");
- break;
- default:
- }
- printk(" ad%c at id %d lun %d ",
- 'a' + NDevices, target, lun);
- if (aip->removable)
- printk("(removable) ");
- if (aip->read_only)
- printk("(read-only) ");
- if (aip->size == DEFAULT_SIZE)
- printk(" unkown size, using default ");
- printk("%ld MByte\n",
- (aip->size*512+1024*1024/2)/(1024*1024));
- NDevices++;
- break;
- case DEV_SLM:
-#ifdef CONFIG_ATARI_SLM
- n_slm += attach_slm( target, lun );
- break;
-#endif
-#ifdef CONFIG_ATARI_SLM_MODULE
- SLM_devices[target] = lun;
- break;
-#endif
- /* neither of the above: fall through to unknown device */
- case DEV_UNKNOWN:
- printk( KERN_INFO "Detected unsupported device at "
- "id %d lun %d\n", target, lun);
- break;
- }
- }
-#ifdef CONFIG_ACSI_MULTI_LUN
- while (i != DEV_NONE && ++lun < MAX_LUN);
-#else
- while (0);
-#endif
- }
-
- /* reenable interrupt */
- ENABLE_IRQ();
- stdma_release();
-
-#ifndef CONFIG_ATARI_SLM
- printk( KERN_INFO "Found %d ACSI device(s) total.\n", NDevices );
-#else
- printk( KERN_INFO "Found %d ACSI device(s) and %d SLM printer(s) total.\n",
- NDevices, n_slm );
-#endif
- err = -ENOMEM;
- for( i = 0; i < NDevices; ++i ) {
- acsi_gendisk[i] = alloc_disk(16);
- if (!acsi_gendisk[i])
- goto out4;
- }
-
- for( i = 0; i < NDevices; ++i ) {
- struct gendisk *disk = acsi_gendisk[i];
- sprintf(disk->disk_name, "ad%c", 'a'+i);
- aip = &acsi_info[NDevices];
- disk->major = ACSI_MAJOR;
- disk->first_minor = i << 4;
- if (acsi_info[i].type != HARDDISK)
- disk->minors = 1;
- disk->fops = &acsi_fops;
- disk->private_data = &acsi_info[i];
- set_capacity(disk, acsi_info[i].size);
- disk->queue = acsi_queue;
- add_disk(disk);
- }
- return 0;
-out4:
- while (i--)
- put_disk(acsi_gendisk[i]);
-out3:
- blk_cleanup_queue(acsi_queue);
-out2a:
- atari_stram_free( acsi_buffer );
-out2:
- unregister_blkdev( ACSI_MAJOR, "ad" );
-out1:
- return err;
-}
-
-
-#ifdef MODULE
-
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- int err;
-
- if ((err = acsi_init()))
- return( err );
- printk( KERN_INFO "ACSI driver loaded as module.\n");
- return( 0 );
-}
-
-void cleanup_module(void)
-{
- int i;
- del_timer( &acsi_timer );
- blk_cleanup_queue(acsi_queue);
- atari_stram_free( acsi_buffer );
-
- if (unregister_blkdev( ACSI_MAJOR, "ad" ) != 0)
- printk( KERN_ERR "acsi: cleanup_module failed\n");
-
- for (i = 0; i < NDevices; i++) {
- del_gendisk(acsi_gendisk[i]);
- put_disk(acsi_gendisk[i]);
- }
-}
-#endif
-
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed scsi disk, and then re-read the new partition table.
- * If we are revalidating a disk because of a media change, then we
- * enter with usage == 0. If we are using an ioctl, we automatically have
- * usage == 1 (we need an open channel to use an ioctl :-), so this
- * is our limit.
- *
- * Changes by Martin Rogge, 9th Aug 1995:
- * got cd-roms to work by calling acsi_devinit. There are only two problems:
- * First, if there is no medium inserted, the status will remain "changed".
- * That is no problem at all, but our design of three-valued logic (medium
- * changed, medium not changed, no medium inserted).
- * Secondly the check could fail completely and the drive could deliver
- * nonsensical data, which could mess up the acsi_info[] structure. In
- * that case we try to make the entry safe.
- *
- */
-
-static int acsi_revalidate(struct gendisk *disk)
-{
- struct acsi_info_struct *aip = disk->private_data;
- stdma_lock( NULL, NULL );
- if (acsi_devinit(aip) != DEV_SUPPORTED) {
- printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n",
- aip->target, aip->lun);
- aip->size = 0;
- aip->read_only = 1;
- aip->removable = 1;
- aip->changed = 1; /* next acsi_open will try again... */
- }
-
- ENABLE_IRQ();
- stdma_release();
- set_capacity(disk, aip->size);
- return 0;
-}
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 27a139025ced..6ce8b897e262 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1363,7 +1363,7 @@ static void redo_fd_request(void)
#ifdef DEBUG
printk("fd: sector %ld + %d requested for %s\n",
CURRENT->sector,cnt,
- (CURRENT->cmd==READ)?"read":"write");
+ (rq_data_dir(CURRENT) == READ) ? "read" : "write");
#endif
block = CURRENT->sector + cnt;
if ((int)block > floppy->blocks) {
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 5acc6c44aead..0fcad430474e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -87,6 +87,7 @@ static const struct pci_device_id cciss_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D},
{PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
@@ -119,6 +120,7 @@ static struct board_type products[] = {
{0x3214103C, "Smart Array E200i", &SA5_access, 120},
{0x3215103C, "Smart Array E200i", &SA5_access, 120},
{0x3237103C, "Smart Array E500", &SA5_access, 512},
+ {0x323D103C, "Smart Array P700m", &SA5_access, 512},
{0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
};
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0ed5470d2533..4503290da407 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -74,6 +74,7 @@
#include <linux/highmem.h>
#include <linux/gfp.h>
#include <linux/kthread.h>
+#include <linux/splice.h>
#include <asm/uaccess.h>
@@ -401,50 +402,73 @@ struct lo_read_data {
};
static int
-lo_read_actor(read_descriptor_t *desc, struct page *page,
- unsigned long offset, unsigned long size)
+lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ struct splice_desc *sd)
{
- unsigned long count = desc->count;
- struct lo_read_data *p = desc->arg.data;
+ struct lo_read_data *p = sd->u.data;
struct loop_device *lo = p->lo;
+ struct page *page = buf->page;
sector_t IV;
+ size_t size;
+ int ret;
- IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
+ ret = buf->ops->confirm(pipe, buf);
+ if (unlikely(ret))
+ return ret;
- if (size > count)
- size = count;
+ IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
+ (buf->offset >> 9);
+ size = sd->len;
+ if (size > p->bsize)
+ size = p->bsize;
- if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) {
- size = 0;
+ if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) {
printk(KERN_ERR "loop: transfer error block %ld\n",
page->index);
- desc->error = -EINVAL;
+ size = -EINVAL;
}
flush_dcache_page(p->page);
- desc->count = count - size;
- desc->written += size;
- p->offset += size;
+ if (size > 0)
+ p->offset += size;
+
return size;
}
static int
+lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
+{
+ return __splice_from_pipe(pipe, sd, lo_splice_actor);
+}
+
+static int
do_lo_receive(struct loop_device *lo,
struct bio_vec *bvec, int bsize, loff_t pos)
{
struct lo_read_data cookie;
+ struct splice_desc sd;
struct file *file;
- int retval;
+ long retval;
cookie.lo = lo;
cookie.page = bvec->bv_page;
cookie.offset = bvec->bv_offset;
cookie.bsize = bsize;
+
+ sd.len = 0;
+ sd.total_len = bvec->bv_len;
+ sd.flags = 0;
+ sd.pos = pos;
+ sd.u.data = &cookie;
+
file = lo->lo_backing_file;
- retval = file->f_op->sendfile(file, &pos, bvec->bv_len,
- lo_read_actor, &cookie);
- return (retval < 0)? retval: 0;
+ retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
+
+ if (retval < 0)
+ return retval;
+
+ return 0;
}
static int
@@ -679,8 +703,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
goto out_putf;
- /* new backing store needs to support loop (eg sendfile) */
- if (!inode->i_fop->sendfile)
+ /* new backing store needs to support loop (eg splice_read) */
+ if (!inode->i_fop->splice_read)
goto out_putf;
/* size of the new backing store needs to be the same */
@@ -760,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
* If we can't read - sorry. If we only can't write - well,
* it's going to be read-only.
*/
- if (!file->f_op->sendfile)
+ if (!file->f_op->splice_read)
goto out_putf;
if (aops->prepare_write && aops->commit_write)
lo_flags |= LO_FLAGS_USE_AOPS;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 069ae39a9cd9..c575fb1d585f 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -416,7 +416,7 @@ static void nbd_clear_que(struct nbd_device *lo)
/*
* We always wait for result of write, for now. It would be nice to make it optional
* in future
- * if ((req->cmd == WRITE) && (lo->flags & NBD_WRITE_NOCHK))
+ * if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_WRITE_NOCHK))
* { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); }
*/
diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
deleted file mode 100644
index 4b12e9031fb3..000000000000
--- a/drivers/cdrom/Kconfig
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# CDROM driver configuration
-#
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
- depends on ISA && BLOCK
-
-config CD_NO_IDESCSI
- bool "Support non-SCSI/IDE/ATAPI CDROM drives"
- ---help---
- If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
- here, otherwise N. Read the CD-ROM-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about these CD-ROM drives. If you are unsure what you
- have, say Y and find out whether you have one of the following
- drives.
-
- For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
- exists. Especially in cases where you do not know exactly which kind
- of drive you have you should read there. Most of these drivers use a
- file drivers/cdrom/{driver_name}.h where you can define your
- interface parameters and switch some internal goodies.
-
- To compile these CD-ROM drivers as a module, choose M instead of Y.
-
- If you want to use any of these CD-ROM drivers, you also have to
- answer Y or M to "ISO 9660 CD-ROM file system support" below (this
- answer will get "defaulted" for you if you enable any of the Linux
- CD-ROM drivers).
-
-config AZTCD
- tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM CDROM support"
- depends on CD_NO_IDESCSI
- ---help---
- This is your driver if you have an Aztech CDA268-01A, Orchid
- CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCD-ROM CR520 or
- CR540 CD-ROM drive. This driver -- just like all these CD-ROM
- drivers -- is NOT for CD-ROM drives with IDE/ATAPI interfaces, such
- as Aztech CDA269-031SE. Please read the file
- <file:Documentation/cdrom/aztcd>.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called aztcd.
-
-config GSCD
- tristate "Goldstar R420 CDROM support"
- depends on CD_NO_IDESCSI
- ---help---
- If this is your CD-ROM drive, say Y here. As described in the file
- <file:Documentation/cdrom/gscd>, you might have to change a setting
- in the file <file:drivers/cdrom/gscd.h> before compiling the
- kernel. Please read the file <file:Documentation/cdrom/gscd>.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called gscd.
-
-config SBPCD
- tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support"
- depends on CD_NO_IDESCSI && BROKEN_ON_SMP
- ---help---
- This driver supports most of the drives which use the Panasonic or
- Sound Blaster interface. Please read the file
- <file:Documentation/cdrom/sbpcd>.
-
- The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
- (sometimes labeled "Creative"), the Creative Labs CD200, the
- Longshine LCS-7260, the "IBM External ISA CD-ROM" (in fact a CR-56x
- model), the TEAC CD-55A fall under this category. Some other
- "electrically compatible" drives (Vertos, Genoa, some Funai models)
- are currently not supported; for the Sanyo H94A drive currently a
- separate driver (asked later) is responsible. Most drives have a
- uniquely shaped faceplate, with a caddyless motorized drawer, but
- without external brand markings. The older CR-52x drives have a
- caddy and manual loading/eject, but still no external markings. The
- driver is able to do an extended auto-probing for interface
- addresses and drive types; this can help to find facts in cases you
- are not sure, but can consume some time during the boot process if
- none of the supported drives gets found. Once your drive got found,
- you should enter the reported parameters into
- <file:drivers/cdrom/sbpcd.h> and set "DISTRIBUTION 0" there.
-
- This driver can support up to four CD-ROM controller cards, and each
- card can support up to four CD-ROM drives; if you say Y here, you
- will be asked how many controller cards you have. If compiled as a
- module, only one controller card (but with up to four drives) is
- usable.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called sbpcd.
-
-config MCDX
- tristate "Mitsumi CDROM support"
- depends on CD_NO_IDESCSI
- ---help---
- Use this driver if you want to be able to use your Mitsumi LU-005,
- FX-001 or FX-001D CD-ROM drive.
-
- Please read the file <file:Documentation/cdrom/mcdx>.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called mcdx.
-
-config OPTCD
- tristate "Optics Storage DOLPHIN 8000AT CDROM support"
- depends on CD_NO_IDESCSI
- ---help---
- This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
- compatible interface. It also works with the Lasermate CR328A. If
- you have one of those, say Y. This driver does not work for the
- Optics Storage 8001 drive; use the IDE-ATAPI CD-ROM driver for that
- one. Please read the file <file:Documentation/cdrom/optcd>.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called optcd.
-
-config CM206
- tristate "Philips/LMS CM206 CDROM support"
- depends on CD_NO_IDESCSI && BROKEN_ON_SMP
- ---help---
- If you have a Philips/LMS CD-ROM drive cm206 in combination with a
- cm260 host adapter card, say Y here. Please also read the file
- <file:Documentation/cdrom/cm206>.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called cm206.
-
-config SJCD
- tristate "Sanyo CDR-H94A CDROM support"
- depends on CD_NO_IDESCSI
- help
- If this is your CD-ROM drive, say Y here and read the file
- <file:Documentation/cdrom/sjcd>. You should then also say Y or M to
- "ISO 9660 CD-ROM file system support" below, because that's the
- file system used on CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called sjcd.
-
-config ISP16_CDI
- tristate "ISP16/MAD16/Mozart soft configurable cdrom interface support"
- depends on CD_NO_IDESCSI
- ---help---
- These are sound cards with built-in cdrom interfaces using the OPTi
- 82C928 or 82C929 chips. Say Y here to have them detected and
- possibly configured at boot time. In addition, You'll have to say Y
- to a driver for the particular cdrom drive you have attached to the
- card. Read <file:Documentation/cdrom/isp16> for details.
-
- To compile this driver as a module, choose M here: the
- module will be called isp16.
-
-config CDU31A
- tristate "Sony CDU31A/CDU33A CDROM support"
- depends on CD_NO_IDESCSI && BROKEN_ON_SMP
- ---help---
- These CD-ROM drives have a spring-pop-out caddyless drawer, and a
- rectangular green LED centered beneath it. NOTE: these CD-ROM
- drives will not be auto detected by the kernel at boot time; you
- have to provide the interface address as an option to the kernel at
- boot time as described in <file:Documentation/cdrom/cdu31a> or fill
- in your parameters into <file:drivers/cdrom/cdu31a.c>. Try "man
- bootparam" or see the documentation of your boot loader (lilo or
- loadlin) about how to pass options to the kernel.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called cdu31a.
-
-config CDU535
- tristate "Sony CDU535 CDROM support"
- depends on CD_NO_IDESCSI
- ---help---
- This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
- drives. Please read the file <file:Documentation/cdrom/sonycd535>.
-
- If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
- file system support" below, because that's the file system used on
- CD-ROMs.
-
- To compile this driver as a module, choose M here: the
- module will be called sonycd535.
-
-endmenu
diff --git a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile
index d1d1e5a4be73..774c180a4e11 100644
--- a/drivers/cdrom/Makefile
+++ b/drivers/cdrom/Makefile
@@ -10,14 +10,4 @@ obj-$(CONFIG_BLK_DEV_SR) += cdrom.o
obj-$(CONFIG_PARIDE_PCD) += cdrom.o
obj-$(CONFIG_CDROM_PKTCDVD) += cdrom.o
-obj-$(CONFIG_AZTCD) += aztcd.o
-obj-$(CONFIG_CDU31A) += cdu31a.o cdrom.o
-obj-$(CONFIG_CM206) += cm206.o cdrom.o
-obj-$(CONFIG_GSCD) += gscd.o
-obj-$(CONFIG_ISP16_CDI) += isp16.o
-obj-$(CONFIG_MCDX) += mcdx.o cdrom.o
-obj-$(CONFIG_OPTCD) += optcd.o
-obj-$(CONFIG_SBPCD) += sbpcd.o cdrom.o
-obj-$(CONFIG_SJCD) += sjcd.o
-obj-$(CONFIG_CDU535) += sonycd535.o
obj-$(CONFIG_VIOCD) += viocd.o cdrom.o
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
deleted file mode 100644
index 1f9fb7a96703..000000000000
--- a/drivers/cdrom/aztcd.c
+++ /dev/null
@@ -1,2492 +0,0 @@
-#define AZT_VERSION "2.60"
-
-/* $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
- linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
-
- Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
-
- based on Mitsumi CDROM driver by Martin Hariss and preworks by
- Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
- Schirmer.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- HISTORY
- V0.0 Adaption to Aztech CD268-01A Version 1.3
- Version is PRE_ALPHA, unresolved points:
- 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
- thus driver causes CPU overhead and is very slow
- 2. could not find a way to stop the drive, when it is
- in data read mode, therefore I had to set
- msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
- frame can be read in sequence, this is also the reason for
- 3. getting 'timeout in state 4' messages, but nevertheless
- it works
- W.Zimmermann, Oct. 31, 1994
- V0.1 Version is ALPHA, problems #2 and #3 resolved.
- W.Zimmermann, Nov. 3, 1994
- V0.2 Modification to some comments, debugging aids for partial test
- with Borland C under DOS eliminated. Timer interrupt wait
- STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented;
- use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
- SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy
- waiting seems better to me than interrupt rescheduling.
- Besides that, when used in the wrong place, STEN_LOW_WAIT causes
- kernel panic.
- In function aztPlay command ACMD_PLAY_AUDIO added, should make
- audio functions work. The Aztech drive needs different commands
- to read data tracks and play audio tracks.
- W.Zimmermann, Nov. 8, 1994
- V0.3 Recognition of missing drive during boot up improved (speeded up).
- W.Zimmermann, Nov. 13, 1994
- V0.35 Rewrote the control mechanism in azt_poll (formerly mcd_poll)
- including removal of all 'goto' commands. :-);
- J. Nardone, Nov. 14, 1994
- V0.4 Renamed variables and constants to 'azt' instead of 'mcd'; had
- to make some "compatibility" defines in azt.h; please note,
- that the source file was renamed to azt.c, the include file to
- azt.h
- Speeded up drive recognition during init (will be a little bit
- slower than before if no drive is installed!); suggested by
- Robby Schirmer.
- read_count declared volatile and set to AZT_BUF_SIZ to make
- drive faster (now 300kB/sec, was 60kB/sec before, measured
- by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
- different AZT_BUF_SIZes were test, above 16 no further im-
- provement seems to be possible; suggested by E.Moenkeberg.
- W.Zimmermann, Nov. 18, 1994
- V0.42 Included getAztStatus command in GetQChannelInfo() to allow
- reading Q-channel info on audio disks, if drive is stopped,
- and some other bug fixes in the audio stuff, suggested by
- Robby Schirmer.
- Added more ioctls (reading data in mode 1 and mode 2).
- Completely removed the old azt_poll() routine.
- Detection of ORCHID CDS-3110 in aztcd_init implemented.
- Additional debugging aids (see the readme file).
- W.Zimmermann, Dec. 9, 1994
- V0.50 Autodetection of drives implemented.
- W.Zimmermann, Dec. 12, 1994
- V0.52 Prepared for including in the standard kernel, renamed most
- variables to contain 'azt', included autoconf.h
- W.Zimmermann, Dec. 16, 1994
- V0.6 Version for being included in the standard Linux kernel.
- Renamed source and header file to aztcd.c and aztcd.h
- W.Zimmermann, Dec. 24, 1994
- V0.7 Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
- CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
- which causes kernel crashes when playing audio, changed
- include-files (config.h instead of autoconf.h, removed
- delay.h)
- W.Zimmermann, Jan. 8, 1995
- V0.72 Some more modifications for adaption to the standard kernel.
- W.Zimmermann, Jan. 16, 1995
- V0.80 aztcd is now part of the standard kernel since version 1.1.83.
- Modified the SET_TIMER and CLEAR_TIMER macros to comply with
- the new timer scheme.
- W.Zimmermann, Jan. 21, 1995
- V0.90 Included CDROMVOLCTRL, but with my Aztech drive I can only turn
- the channels on and off. If it works better with your drive,
- please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
- W.Zimmermann, Jan. 24, 1995
- V1.00 Implemented close and lock tray commands. Patches supplied by
- Frank Racis
- Added support for loadable MODULEs, so aztcd can now also be
- loaded by insmod and removed by rmmod during run time
- Werner Zimmermann, Mar. 24, 95
- V1.10 Implemented soundcard configuration for Orchid CDS-3110 drives
- connected to Soundwave32 cards. Release for LST 2.1.
- (still experimental)
- Werner Zimmermann, May 8, 95
- V1.20 Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
- sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
- sion needs an update of Dosemu0.60's cdrom.c, which will come with the
- next revision of Dosemu.
- Also Soundwave32 support now works.
- Werner Zimmermann, May 22, 95
- V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
- Werner Zimmermann, July 4, 95
- V1.40 Started multisession support. Implementation copied from mcdx.c
- by Heiko Schlittermann. Not tested yet.
- Werner Zimmermann, July 15, 95
- V1.50 Implementation of ioctl CDROMRESET, continued multisession, began
- XA, but still untested. Heavy modifications to drive status de-
- tection.
- Werner Zimmermann, July 25, 95
- V1.60 XA support now should work. Speeded up drive recognition in cases,
- where no drive is installed.
- Werner Zimmermann, August 8, 1995
- V1.70 Multisession support now is completed, but there is still not
- enough testing done. If you can test it, please contact me. For
- details please read Documentation/cdrom/aztcd
- Werner Zimmermann, August 19, 1995
- V1.80 Modification to suit the new kernel boot procedure introduced
- with kernel 1.3.33. Will definitely not work with older kernels.
- Programming done by Linus himself.
- Werner Zimmermann, October 11, 1995
- V1.90 Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
- Werner Zimmermann, October 21, 1995
- V2.00 Changed #include "blk.h" to <linux/blk.h> as the directory
- structure was changed. README.aztcd is now /usr/src/docu-
- mentation/cdrom/aztcd
- Werner Zimmermann, November 10, 95
- V2.10 Started to modify azt_poll to prevent reading beyond end of
- tracks.
- Werner Zimmermann, December 3, 95
- V2.20 Changed some comments
- Werner Zimmermann, April 1, 96
- V2.30 Implemented support for CyCDROM CR520, CR940, Code for CR520
- delivered by H.Berger with preworks by E.Moenkeberg.
- Werner Zimmermann, April 29, 96
- V2.40 Reorganized the placement of functions in the source code file
- to reflect the layered approach; did not actually change code
- Werner Zimmermann, May 1, 96
- V2.50 Heiko Eissfeldt suggested to remove some VERIFY_READs in
- aztcd_ioctl; check_aztcd_media_change modified
- Werner Zimmermann, May 16, 96
- V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
- Adaption to linux kernel > 2.1.0
- Werner Zimmermann, Nov 29, 97
-
- November 1999 -- Make kernel-parameter implementation work with 2.3.x
- Removed init_module & cleanup_module in favor of
- module_init & module_exit.
- Torben Mathiasen <tmm@image.dk>
-*/
-
-#include <linux/blkdev.h>
-#include "aztcd.h"
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/major.h>
-
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include <asm/uaccess.h>
-
-/*###########################################################################
- Defines
- ###########################################################################
-*/
-
-#define MAJOR_NR AZTECH_CDROM_MAJOR
-#define QUEUE (azt_queue)
-#define CURRENT elv_next_request(azt_queue)
-#define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
- delay_timer.function = (void *) (func); \
- add_timer(&delay_timer);
-
-#define CLEAR_TIMER del_timer(&delay_timer);
-
-#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
- return value;}
-#define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
- return;}
-
-/* Macros to switch the IDE-interface to the slave device and back to the master*/
-#define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
- outb_p(0x10,azt_port+6); \
- outb_p(0x00,azt_port+7); \
- outb_p(0x10,azt_port+6);
-#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
-
-
-#if 0
-#define AZT_TEST
-#define AZT_TEST1 /* <int-..> */
-#define AZT_TEST2 /* do_aztcd_request */
-#define AZT_TEST3 /* AZT_S_state */
-#define AZT_TEST4 /* QUICK_LOOP-counter */
-#define AZT_TEST5 /* port(1) state */
-#define AZT_DEBUG
-#define AZT_DEBUG_MULTISESSION
-#endif
-
-static struct request_queue *azt_queue;
-
-static int current_valid(void)
-{
- return CURRENT &&
- CURRENT->cmd == READ &&
- CURRENT->sector != -1;
-}
-
-#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
-#define AZT_BUF_SIZ 16
-
-#define READ_TIMEOUT 3000
-
-#define azt_port aztcd /*needed for the modutils */
-
-/*##########################################################################
- Type Definitions
- ##########################################################################
-*/
-enum azt_state_e { AZT_S_IDLE, /* 0 */
- AZT_S_START, /* 1 */
- AZT_S_MODE, /* 2 */
- AZT_S_READ, /* 3 */
- AZT_S_DATA, /* 4 */
- AZT_S_STOP, /* 5 */
- AZT_S_STOPPING /* 6 */
-};
-enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
- AZT_MODE_1, /*read mode for normal CD-ROMs */
- AZT_MODE_2 /*read mode for XA CD-ROMs */
-};
-
-/*##########################################################################
- Global Variables
- ##########################################################################
-*/
-static int aztPresent = 0;
-
-static volatile int azt_transfer_is_active = 0;
-
-static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
-#if AZT_PRIVATE_IOCTLS
-static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
-#endif
-
-static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
-static volatile int azt_buf_in, azt_buf_out = -1;
-static volatile int azt_error = 0;
-static int azt_open_count = 0;
-static volatile enum azt_state_e azt_state = AZT_S_IDLE;
-#ifdef AZT_TEST3
-static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
-static volatile int azt_st_old = 0;
-#endif
-static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
-
-static int azt_mode = -1;
-static volatile int azt_read_count = 1;
-
-static int azt_port = AZT_BASE_ADDR;
-
-module_param(azt_port, int, 0);
-
-static int azt_port_auto[16] = AZT_BASE_AUTO;
-
-static char azt_cont = 0;
-static char azt_init_end = 0;
-static char azt_auto_eject = AZT_AUTO_EJECT;
-
-static int AztTimeout, AztTries;
-static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
-static DEFINE_TIMER(delay_timer, NULL, 0, 0);
-
-static struct azt_DiskInfo DiskInfo;
-static struct azt_Toc Toc[MAX_TRACKS];
-static struct azt_Play_msf azt_Play;
-
-static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-static char aztDiskChanged = 1;
-static char aztTocUpToDate = 0;
-
-static unsigned char aztIndatum;
-static unsigned long aztTimeOutCount;
-static int aztCmd = 0;
-
-static DEFINE_SPINLOCK(aztSpin);
-
-/*###########################################################################
- Function Prototypes
- ###########################################################################
-*/
-/* CDROM Drive Low Level I/O Functions */
-static void aztStatTimer(void);
-
-/* CDROM Drive Command Functions */
-static int aztGetDiskInfo(void);
-#if AZT_MULTISESSION
-static int aztGetMultiDiskInfo(void);
-#endif
-static int aztGetToc(int multi);
-
-/* Kernel Interface Functions */
-static int check_aztcd_media_change(struct gendisk *disk);
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
- unsigned long arg);
-static int aztcd_open(struct inode *ip, struct file *fp);
-static int aztcd_release(struct inode *inode, struct file *file);
-
-static struct block_device_operations azt_fops = {
- .owner = THIS_MODULE,
- .open = aztcd_open,
- .release = aztcd_release,
- .ioctl = aztcd_ioctl,
- .media_changed = check_aztcd_media_change,
-};
-
-/* Aztcd State Machine: Controls Drive Operating State */
-static void azt_poll(void);
-
-/* Miscellaneous support functions */
-static void azt_hsg2msf(long hsg, struct msf *msf);
-static long azt_msf2hsg(struct msf *mp);
-static void azt_bin2bcd(unsigned char *p);
-static int azt_bcd2bin(unsigned char bcd);
-
-/*##########################################################################
- CDROM Drive Low Level I/O Functions
- ##########################################################################
-*/
-/* Macros for the drive hardware interface handshake, these macros use
- busy waiting */
-/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
-# define OP_OK op_ok()
-static void op_ok(void)
-{
- aztTimeOutCount = 0;
- do {
- aztIndatum = inb(DATA_PORT);
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_TIMEOUT) {
- printk("aztcd: Error Wait OP_OK\n");
- break;
- }
- } while (aztIndatum != AFL_OP_OK);
-}
-
-/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
-#if 0
-# define PA_OK pa_ok()
-static void pa_ok(void)
-{
- aztTimeOutCount = 0;
- do {
- aztIndatum = inb(DATA_PORT);
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_TIMEOUT) {
- printk("aztcd: Error Wait PA_OK\n");
- break;
- }
- } while (aztIndatum != AFL_PA_OK);
-}
-#endif
-
-/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
-# define STEN_LOW sten_low()
-static void sten_low(void)
-{
- aztTimeOutCount = 0;
- do {
- aztIndatum = inb(STATUS_PORT);
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_TIMEOUT) {
- if (azt_init_end)
- printk
- ("aztcd: Error Wait STEN_LOW commands:%x\n",
- aztCmd);
- break;
- }
- } while (aztIndatum & AFL_STATUS);
-}
-
-/* Wait for DTEN=Low = handshake signal 'Data available'*/
-# define DTEN_LOW dten_low()
-static void dten_low(void)
-{
- aztTimeOutCount = 0;
- do {
- aztIndatum = inb(STATUS_PORT);
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_TIMEOUT) {
- printk("aztcd: Error Wait DTEN_OK\n");
- break;
- }
- } while (aztIndatum & AFL_DATA);
-}
-
-/*
- * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
- * may cause kernel panic when used in the wrong place
-*/
-#define STEN_LOW_WAIT statusAzt()
-static void statusAzt(void)
-{
- AztTimeout = AZT_STATUS_DELAY;
- SET_TIMER(aztStatTimer, HZ / 100);
- sleep_on(&azt_waitq);
- if (AztTimeout <= 0)
- printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
- aztCmd);
- return;
-}
-
-static void aztStatTimer(void)
-{
- if (!(inb(STATUS_PORT) & AFL_STATUS)) {
- wake_up(&azt_waitq);
- return;
- }
- AztTimeout--;
- if (AztTimeout <= 0) {
- wake_up(&azt_waitq);
- printk("aztcd: Error aztStatTimer: Timeout\n");
- return;
- }
- SET_TIMER(aztStatTimer, HZ / 100);
-}
-
-/*##########################################################################
- CDROM Drive Command Functions
- ##########################################################################
-*/
-/*
- * Send a single command, return -1 on error, else 0
-*/
-static int aztSendCmd(int cmd)
-{
- unsigned char data;
- int retry;
-
-#ifdef AZT_DEBUG
- printk("aztcd: Executing command %x\n", cmd);
-#endif
-
- if ((azt_port == 0x1f0) || (azt_port == 0x170))
- SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
-
- aztCmd = cmd;
- outb(POLLED, MODE_PORT);
- do {
- if (inb(STATUS_PORT) & AFL_STATUS)
- break;
- inb(DATA_PORT); /* if status left from last command, read and */
- } while (1); /* discard it */
- do {
- if (inb(STATUS_PORT) & AFL_DATA)
- break;
- inb(DATA_PORT); /* if data left from last command, read and */
- } while (1); /* discard it */
- for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
- outb((unsigned char) cmd, CMD_PORT);
- STEN_LOW;
- data = inb(DATA_PORT);
- if (data == AFL_OP_OK) {
- return 0;
- } /*OP_OK? */
- if (data == AFL_OP_ERR) {
- STEN_LOW;
- data = inb(DATA_PORT);
- printk
- ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
- cmd, data);
- }
- }
- if (retry >= AZT_RETRY_ATTEMPTS) {
- printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
- azt_error = 0xA5;
- }
- RETURNM("aztSendCmd", -1);
-}
-
-/*
- * Send a play or read command to the drive, return -1 on error, else 0
-*/
-static int sendAztCmd(int cmd, struct azt_Play_msf *params)
-{
- unsigned char data;
- int retry;
-
-#ifdef AZT_DEBUG
- printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
- params->start.min, params->start.sec, params->start.frame,
- params->end.min, params->end.sec, params->end.frame);
-#endif
- for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
- aztSendCmd(cmd);
- outb(params->start.min, CMD_PORT);
- outb(params->start.sec, CMD_PORT);
- outb(params->start.frame, CMD_PORT);
- outb(params->end.min, CMD_PORT);
- outb(params->end.sec, CMD_PORT);
- outb(params->end.frame, CMD_PORT);
- STEN_LOW;
- data = inb(DATA_PORT);
- if (data == AFL_PA_OK) {
- return 0;
- } /*PA_OK ? */
- if (data == AFL_PA_ERR) {
- STEN_LOW;
- data = inb(DATA_PORT);
- printk
- ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
- cmd, data);
- }
- }
- if (retry >= AZT_RETRY_ATTEMPTS) {
- printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
- azt_error = 0xA5;
- }
- RETURNM("sendAztCmd", -1);
-}
-
-/*
- * Send a seek command to the drive, return -1 on error, else 0
-*/
-static int aztSeek(struct azt_Play_msf *params)
-{
- unsigned char data;
- int retry;
-
-#ifdef AZT_DEBUG
- printk("aztcd: aztSeek %02x:%02x:%02x\n",
- params->start.min, params->start.sec, params->start.frame);
-#endif
- for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
- aztSendCmd(ACMD_SEEK);
- outb(params->start.min, CMD_PORT);
- outb(params->start.sec, CMD_PORT);
- outb(params->start.frame, CMD_PORT);
- STEN_LOW;
- data = inb(DATA_PORT);
- if (data == AFL_PA_OK) {
- return 0;
- } /*PA_OK ? */
- if (data == AFL_PA_ERR) {
- STEN_LOW;
- data = inb(DATA_PORT);
- printk("### Error 1 aztcd: aztSeek\n");
- }
- }
- if (retry >= AZT_RETRY_ATTEMPTS) {
- printk("### Error 2 aztcd: aztSeek\n ");
- azt_error = 0xA5;
- }
- RETURNM("aztSeek", -1);
-}
-
-/* Send a Set Disk Type command
- does not seem to work with Aztech drives, behavior is completely indepen-
- dent on which mode is set ???
-*/
-static int aztSetDiskType(int type)
-{
- unsigned char data;
- int retry;
-
-#ifdef AZT_DEBUG
- printk("aztcd: set disk type command: type= %i\n", type);
-#endif
- for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
- aztSendCmd(ACMD_SET_DISK_TYPE);
- outb(type, CMD_PORT);
- STEN_LOW;
- data = inb(DATA_PORT);
- if (data == AFL_PA_OK) { /*PA_OK ? */
- azt_read_mode = type;
- return 0;
- }
- if (data == AFL_PA_ERR) {
- STEN_LOW;
- data = inb(DATA_PORT);
- printk
- ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
- type, data);
- }
- }
- if (retry >= AZT_RETRY_ATTEMPTS) {
- printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
- azt_error = 0xA5;
- }
- RETURNM("aztSetDiskType", -1);
-}
-
-
-/* used in azt_poll to poll the status, expects another program to issue a
- * ACMD_GET_STATUS directly before
- */
-static int aztStatus(void)
-{
- int st;
-/* int i;
-
- i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
- if (!i)
-*/ STEN_LOW;
- if (aztTimeOutCount < AZT_TIMEOUT) {
- st = inb(DATA_PORT) & 0xFF;
- return st;
- } else
- RETURNM("aztStatus", -1);
-}
-
-/*
- * Get the drive status
- */
-static int getAztStatus(void)
-{
- int st;
-
- if (aztSendCmd(ACMD_GET_STATUS))
- RETURNM("getAztStatus 1", -1);
- STEN_LOW;
- st = inb(DATA_PORT) & 0xFF;
-#ifdef AZT_DEBUG
- printk("aztcd: Status = %x\n", st);
-#endif
- if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
- printk
- ("aztcd: AST_CMD_CHECK error or no status available\n");
- return -1;
- }
-
- if (((st & AST_MODE_BITS) != AST_BUSY)
- && (aztAudioStatus == CDROM_AUDIO_PLAY))
- /* XXX might be an error? look at q-channel? */
- aztAudioStatus = CDROM_AUDIO_COMPLETED;
-
- if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
- aztDiskChanged = 1;
- aztTocUpToDate = 0;
- aztAudioStatus = CDROM_AUDIO_NO_STATUS;
- }
- return st;
-}
-
-
-/*
- * Send a 'Play' command and get the status. Use only from the top half.
- */
-static int aztPlay(struct azt_Play_msf *arg)
-{
- if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
- RETURNM("aztPlay", -1);
- return 0;
-}
-
-/*
- * Subroutines to automatically close the door (tray) and
- * lock it closed when the cd is mounted. Leave the tray
- * locking as an option
- */
-static void aztCloseDoor(void)
-{
- aztSendCmd(ACMD_CLOSE);
- STEN_LOW;
- return;
-}
-
-static void aztLockDoor(void)
-{
-#if AZT_ALLOW_TRAY_LOCK
- aztSendCmd(ACMD_LOCK);
- STEN_LOW;
-#endif
- return;
-}
-
-static void aztUnlockDoor(void)
-{
-#if AZT_ALLOW_TRAY_LOCK
- aztSendCmd(ACMD_UNLOCK);
- STEN_LOW;
-#endif
- return;
-}
-
-/*
- * Read a value from the drive. Should return quickly, so a busy wait
- * is used to avoid excessive rescheduling. The read command itself must
- * be issued with aztSendCmd() directly before
- */
-static int aztGetValue(unsigned char *result)
-{
- int s;
-
- STEN_LOW;
- if (aztTimeOutCount >= AZT_TIMEOUT) {
- printk("aztcd: aztGetValue timeout\n");
- return -1;
- }
- s = inb(DATA_PORT) & 0xFF;
- *result = (unsigned char) s;
- return 0;
-}
-
-/*
- * Read the current Q-channel info. Also used for reading the
- * table of contents.
- */
-static int aztGetQChannelInfo(struct azt_Toc *qp)
-{
- unsigned char notUsed;
- int st;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
-#endif
- if ((st = getAztStatus()) == -1)
- RETURNM("aztGetQChannelInfo 1", -1);
- if (aztSendCmd(ACMD_GET_Q_CHANNEL))
- RETURNM("aztGetQChannelInfo 2", -1);
- /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
- if (aztGetValue(&notUsed))
- RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
- if ((st & AST_MODE_BITS) == AST_INITIAL) {
- qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
- qp->track = 0; /* only one byte with Aztech drives */
- qp->pointIndex = 0;
- qp->trackTime.min = 0;
- qp->trackTime.sec = 0;
- qp->trackTime.frame = 0;
- qp->diskTime.min = 0;
- qp->diskTime.sec = 0;
- qp->diskTime.frame = 0;
- return 0;
- } else {
- if (aztGetValue(&qp->ctrl_addr) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->track) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->pointIndex) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->trackTime.min) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->trackTime.sec) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->trackTime.frame) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&notUsed) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->diskTime.min) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->diskTime.sec) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- if (aztGetValue(&qp->diskTime.frame) < 0)
- RETURNM("aztGetQChannelInfo 4", -1);
- }
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
-#endif
- return 0;
-}
-
-/*
- * Read the table of contents (TOC) and TOC header if necessary
- */
-static int aztUpdateToc(void)
-{
- int st;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
-#endif
- if (aztTocUpToDate)
- return 0;
-
- if (aztGetDiskInfo() < 0)
- return -EIO;
-
- if (aztGetToc(0) < 0)
- return -EIO;
-
- /*audio disk detection
- with my Aztech drive there is no audio status bit, so I use the copy
- protection bit of the first track. If this track is copy protected
- (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
- if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
- DiskInfo.audio = 1;
- else
- DiskInfo.audio = 0;
-
- /* XA detection */
- if (!DiskInfo.audio) {
- azt_Play.start.min = 0; /*XA detection only seems to work */
- azt_Play.start.sec = 2; /*when we play a track */
- azt_Play.start.frame = 0;
- azt_Play.end.min = 0;
- azt_Play.end.sec = 0;
- azt_Play.end.frame = 1;
- if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
- return -1;
- DTEN_LOW;
- for (st = 0; st < CD_FRAMESIZE; st++)
- inb(DATA_PORT);
- }
- DiskInfo.xa = getAztStatus() & AST_MODE;
- if (DiskInfo.xa) {
- printk
- ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
- }
-
- /*multisession detection
- support for multisession CDs is done automatically with Aztech drives,
- we don't have to take care about TOC redirection; if we want the isofs
- to take care about redirection, we have to set AZT_MULTISESSION to 1 */
- DiskInfo.multi = 0;
-#if AZT_MULTISESSION
- if (DiskInfo.xa) {
- aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
- }
-#endif
- if (DiskInfo.multi) {
- DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
- DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
- DiskInfo.lastSession.frame =
- Toc[DiskInfo.next].diskTime.frame;
- printk("aztcd: Multisession support experimental\n");
- } else {
- DiskInfo.lastSession.min =
- Toc[DiskInfo.first].diskTime.min;
- DiskInfo.lastSession.sec =
- Toc[DiskInfo.first].diskTime.sec;
- DiskInfo.lastSession.frame =
- Toc[DiskInfo.first].diskTime.frame;
- }
-
- aztTocUpToDate = 1;
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
-#endif
- return 0;
-}
-
-
-/* Read the table of contents header, i.e. no. of tracks and start of first
- * track
- */
-static int aztGetDiskInfo(void)
-{
- int limit;
- unsigned char test;
- struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
-#endif
- if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
- RETURNM("aztGetDiskInfo 1", -1);
- STEN_LOW_WAIT;
- test = 0;
- for (limit = 300; limit > 0; limit--) {
- if (aztGetQChannelInfo(&qInfo) < 0)
- RETURNM("aztGetDiskInfo 2", -1);
- if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
- DiskInfo.first = qInfo.diskTime.min;
- DiskInfo.first = azt_bcd2bin(DiskInfo.first);
- test = test | 0x01;
- }
- if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
- DiskInfo.last = qInfo.diskTime.min;
- DiskInfo.last = azt_bcd2bin(DiskInfo.last);
- test = test | 0x02;
- }
- if (qInfo.pointIndex == 0xA2) { /*DiskLength */
- DiskInfo.diskLength.min = qInfo.diskTime.min;
- DiskInfo.diskLength.sec = qInfo.diskTime.sec;
- DiskInfo.diskLength.frame = qInfo.diskTime.frame;
- test = test | 0x04;
- }
- if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
- DiskInfo.firstTrack.min = qInfo.diskTime.min;
- DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
- DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
- test = test | 0x08;
- }
- if (test == 0x0F)
- break;
- }
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
- printk
- ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
- DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
- DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
- DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
- DiskInfo.firstTrack.frame);
-#endif
- if (test != 0x0F)
- return -1;
- return 0;
-}
-
-#if AZT_MULTISESSION
-/*
- * Get Multisession Disk Info
- */
-static int aztGetMultiDiskInfo(void)
-{
- int limit, k = 5;
- unsigned char test;
- struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztGetMultiDiskInfo\n");
-#endif
-
- do {
- azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
- azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
- azt_Play.start.frame =
- Toc[DiskInfo.last + 1].diskTime.frame;
- test = 0;
-
- for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
- if (aztSeek(&azt_Play))
- RETURNM("aztGetMultiDiskInfo 1", -1);
- if (aztGetQChannelInfo(&qInfo) < 0)
- RETURNM("aztGetMultiDiskInfo 2", -1);
- if ((qInfo.track == 0) && (qInfo.pointIndex))
- break; /*LeadIn found */
- if ((azt_Play.start.sec += 10) > 59) {
- azt_Play.start.sec = 0;
- azt_Play.start.min++;
- }
- }
- if (!limit)
- break; /*Check, if a leadin track was found, if not we're
- at the end of the disk */
-#ifdef AZT_DEBUG_MULTISESSION
- printk("leadin found track %d pointIndex %x limit %d\n",
- qInfo.track, qInfo.pointIndex, limit);
-#endif
- for (limit = 300; limit > 0; limit--) {
- if (++azt_Play.start.frame > 74) {
- azt_Play.start.frame = 0;
- if (azt_Play.start.sec > 59) {
- azt_Play.start.sec = 0;
- azt_Play.start.min++;
- }
- }
- if (aztSeek(&azt_Play))
- RETURNM("aztGetMultiDiskInfo 3", -1);
- if (aztGetQChannelInfo(&qInfo) < 0)
- RETURNM("aztGetMultiDiskInfo 4", -1);
- if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
- DiskInfo.next = qInfo.diskTime.min;
- DiskInfo.next = azt_bcd2bin(DiskInfo.next);
- test = test | 0x01;
- }
- if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
- DiskInfo.last = qInfo.diskTime.min;
- DiskInfo.last = azt_bcd2bin(DiskInfo.last);
- test = test | 0x02;
- }
- if (qInfo.pointIndex == 0xA2) { /*DiskLength */
- DiskInfo.diskLength.min =
- qInfo.diskTime.min;
- DiskInfo.diskLength.sec =
- qInfo.diskTime.sec;
- DiskInfo.diskLength.frame =
- qInfo.diskTime.frame;
- test = test | 0x04;
- }
- if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
- DiskInfo.nextSession.min =
- qInfo.diskTime.min;
- DiskInfo.nextSession.sec =
- qInfo.diskTime.sec;
- DiskInfo.nextSession.frame =
- qInfo.diskTime.frame;
- test = test | 0x08;
- }
- if (test == 0x0F)
- break;
- }
-#ifdef AZT_DEBUG_MULTISESSION
- printk
- ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
- DiskInfo.first, DiskInfo.next, DiskInfo.last,
- DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
- DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
- DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
- DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
- DiskInfo.nextSession.frame);
-#endif
- if (test != 0x0F)
- break;
- else
- DiskInfo.multi = 1; /*found TOC of more than one session */
- aztGetToc(1);
- } while (--k);
-
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
-#endif
- return 0;
-}
-#endif
-
-/*
- * Read the table of contents (TOC)
- */
-static int aztGetToc(int multi)
-{
- int i, px;
- int limit;
- struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
-#endif
- if (!multi) {
- for (i = 0; i < MAX_TRACKS; i++)
- Toc[i].pointIndex = 0;
- i = DiskInfo.last + 3;
- } else {
- for (i = DiskInfo.next; i < MAX_TRACKS; i++)
- Toc[i].pointIndex = 0;
- i = DiskInfo.last + 4 - DiskInfo.next;
- }
-
-/*Is there a good reason to stop motor before TOC read?
- if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
- STEN_LOW_WAIT;
-*/
-
- if (!multi) {
- azt_mode = 0x05;
- if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
- RETURNM("aztGetToc 2", -1);
- STEN_LOW_WAIT;
- }
- for (limit = 300; limit > 0; limit--) {
- if (multi) {
- if (++azt_Play.start.sec > 59) {
- azt_Play.start.sec = 0;
- azt_Play.start.min++;
- }
- if (aztSeek(&azt_Play))
- RETURNM("aztGetToc 3", -1);
- }
- if (aztGetQChannelInfo(&qInfo) < 0)
- break;
-
- px = azt_bcd2bin(qInfo.pointIndex);
-
- if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
- if (Toc[px].pointIndex == 0) {
- Toc[px] = qInfo;
- i--;
- }
-
- if (i <= 0)
- break;
- }
-
- Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
- Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
-
-#ifdef AZT_DEBUG_MULTISESSION
- printk("aztcd: exiting aztGetToc\n");
- for (i = 1; i <= DiskInfo.last + 1; i++)
- printk
- ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
- i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
- Toc[i].trackTime.min, Toc[i].trackTime.sec,
- Toc[i].trackTime.frame, Toc[i].diskTime.min,
- Toc[i].diskTime.sec, Toc[i].diskTime.frame);
- for (i = 100; i < 103; i++)
- printk
- ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
- i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
- Toc[i].trackTime.min, Toc[i].trackTime.sec,
- Toc[i].trackTime.frame, Toc[i].diskTime.min,
- Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-#endif
-
- return limit > 0 ? 0 : -1;
-}
-
-
-/*##########################################################################
- Kernel Interface Functions
- ##########################################################################
-*/
-
-#ifndef MODULE
-static int __init aztcd_setup(char *str)
-{
- int ints[4];
-
- (void) get_options(str, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0)
- azt_port = ints[1];
- if (ints[1] > 1)
- azt_cont = ints[2];
- return 1;
-}
-
-__setup("aztcd=", aztcd_setup);
-
-#endif /* !MODULE */
-
-/*
- * Checking if the media has been changed
-*/
-static int check_aztcd_media_change(struct gendisk *disk)
-{
- if (aztDiskChanged) { /* disk changed */
- aztDiskChanged = 0;
- return 1;
- } else
- return 0; /* no change */
-}
-
-/*
- * Kernel IO-controls
-*/
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- int i;
- struct azt_Toc qInfo;
- struct cdrom_ti ti;
- struct cdrom_tochdr tocHdr;
- struct cdrom_msf msf;
- struct cdrom_tocentry entry;
- struct azt_Toc *tocPtr;
- struct cdrom_subchnl subchnl;
- struct cdrom_volctrl volctrl;
- void __user *argp = (void __user *)arg;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
- cmd, jiffies);
- printk("aztcd Status %x\n", getAztStatus());
-#endif
- if (!ip)
- RETURNM("aztcd_ioctl 1", -EINVAL);
- if (getAztStatus() < 0)
- RETURNM("aztcd_ioctl 2", -EIO);
- if ((!aztTocUpToDate) || (aztDiskChanged)) {
- if ((i = aztUpdateToc()) < 0)
- RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
- }
-
- switch (cmd) {
- case CDROMSTART: /* Spin up the drive. Don't know, what to do,
- at least close the tray */
-#if AZT_PRIVATE_IOCTLS
- if (aztSendCmd(ACMD_CLOSE))
- RETURNM("aztcd_ioctl 4", -1);
- STEN_LOW_WAIT;
-#endif
- break;
- case CDROMSTOP: /* Spin down the drive */
- if (aztSendCmd(ACMD_STOP))
- RETURNM("aztcd_ioctl 5", -1);
- STEN_LOW_WAIT;
- /* should we do anything if it fails? */
- aztAudioStatus = CDROM_AUDIO_NO_STATUS;
- break;
- case CDROMPAUSE: /* Pause the drive */
- if (aztAudioStatus != CDROM_AUDIO_PLAY)
- return -EINVAL;
-
- if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
- aztAudioStatus = CDROM_AUDIO_NO_STATUS;
- RETURNM("aztcd_ioctl 7", 0);
- }
- azt_Play.start = qInfo.diskTime; /* remember restart point */
-
- if (aztSendCmd(ACMD_PAUSE))
- RETURNM("aztcd_ioctl 8", -1);
- STEN_LOW_WAIT;
- aztAudioStatus = CDROM_AUDIO_PAUSED;
- break;
- case CDROMRESUME: /* Play it again, Sam */
- if (aztAudioStatus != CDROM_AUDIO_PAUSED)
- return -EINVAL;
- /* restart the drive at the saved position. */
- i = aztPlay(&azt_Play);
- if (i < 0) {
- aztAudioStatus = CDROM_AUDIO_ERROR;
- return -EIO;
- }
- aztAudioStatus = CDROM_AUDIO_PLAY;
- break;
- case CDROMMULTISESSION: /*multisession support -- experimental */
- {
- struct cdrom_multisession ms;
-#ifdef AZT_DEBUG
- printk("aztcd ioctl MULTISESSION\n");
-#endif
- if (copy_from_user(&ms, argp,
- sizeof(struct cdrom_multisession)))
- return -EFAULT;
- if (ms.addr_format == CDROM_MSF) {
- ms.addr.msf.minute =
- azt_bcd2bin(DiskInfo.lastSession.min);
- ms.addr.msf.second =
- azt_bcd2bin(DiskInfo.lastSession.sec);
- ms.addr.msf.frame =
- azt_bcd2bin(DiskInfo.lastSession.
- frame);
- } else if (ms.addr_format == CDROM_LBA)
- ms.addr.lba =
- azt_msf2hsg(&DiskInfo.lastSession);
- else
- return -EINVAL;
- ms.xa_flag = DiskInfo.xa;
- if (copy_to_user(argp, &ms,
- sizeof(struct cdrom_multisession)))
- return -EFAULT;
-#ifdef AZT_DEBUG
- if (ms.addr_format == CDROM_MSF)
- printk
- ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
- ms.xa_flag, ms.addr.msf.minute,
- ms.addr.msf.second, ms.addr.msf.frame,
- DiskInfo.lastSession.min,
- DiskInfo.lastSession.sec,
- DiskInfo.lastSession.frame);
- else
- printk
- ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
- ms.xa_flag, ms.addr.lba,
- DiskInfo.lastSession.min,
- DiskInfo.lastSession.sec,
- DiskInfo.lastSession.frame);
-#endif
- return 0;
- }
- case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- if (copy_from_user(&ti, argp, sizeof ti))
- return -EFAULT;
- if (ti.cdti_trk0 < DiskInfo.first
- || ti.cdti_trk0 > DiskInfo.last
- || ti.cdti_trk1 < ti.cdti_trk0) {
- return -EINVAL;
- }
- if (ti.cdti_trk1 > DiskInfo.last)
- ti.cdti_trk1 = DiskInfo.last;
- azt_Play.start = Toc[ti.cdti_trk0].diskTime;
- azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
-#ifdef AZT_DEBUG
- printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
- azt_Play.start.min, azt_Play.start.sec,
- azt_Play.start.frame, azt_Play.end.min,
- azt_Play.end.sec, azt_Play.end.frame);
-#endif
- i = aztPlay(&azt_Play);
- if (i < 0) {
- aztAudioStatus = CDROM_AUDIO_ERROR;
- return -EIO;
- }
- aztAudioStatus = CDROM_AUDIO_PLAY;
- break;
- case CDROMPLAYMSF: /* Play starting at the given MSF address. */
-/* if (aztAudioStatus == CDROM_AUDIO_PLAY)
- { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
- STEN_LOW;
- aztAudioStatus = CDROM_AUDIO_NO_STATUS;
- }
-*/
- if (copy_from_user(&msf, argp, sizeof msf))
- return -EFAULT;
- /* convert to bcd */
- azt_bin2bcd(&msf.cdmsf_min0);
- azt_bin2bcd(&msf.cdmsf_sec0);
- azt_bin2bcd(&msf.cdmsf_frame0);
- azt_bin2bcd(&msf.cdmsf_min1);
- azt_bin2bcd(&msf.cdmsf_sec1);
- azt_bin2bcd(&msf.cdmsf_frame1);
- azt_Play.start.min = msf.cdmsf_min0;
- azt_Play.start.sec = msf.cdmsf_sec0;
- azt_Play.start.frame = msf.cdmsf_frame0;
- azt_Play.end.min = msf.cdmsf_min1;
- azt_Play.end.sec = msf.cdmsf_sec1;
- azt_Play.end.frame = msf.cdmsf_frame1;
-#ifdef AZT_DEBUG
- printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
- azt_Play.start.min, azt_Play.start.sec,
- azt_Play.start.frame, azt_Play.end.min,
- azt_Play.end.sec, azt_Play.end.frame);
-#endif
- i = aztPlay(&azt_Play);
- if (i < 0) {
- aztAudioStatus = CDROM_AUDIO_ERROR;
- return -EIO;
- }
- aztAudioStatus = CDROM_AUDIO_PLAY;
- break;
-
- case CDROMREADTOCHDR: /* Read the table of contents header */
- tocHdr.cdth_trk0 = DiskInfo.first;
- tocHdr.cdth_trk1 = DiskInfo.last;
- if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
- return -EFAULT;
- break;
- case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
- if (copy_from_user(&entry, argp, sizeof entry))
- return -EFAULT;
- if ((!aztTocUpToDate) || aztDiskChanged)
- aztUpdateToc();
- if (entry.cdte_track == CDROM_LEADOUT)
- tocPtr = &Toc[DiskInfo.last + 1];
- else if (entry.cdte_track > DiskInfo.last
- || entry.cdte_track < DiskInfo.first) {
- return -EINVAL;
- } else
- tocPtr = &Toc[entry.cdte_track];
- entry.cdte_adr = tocPtr->ctrl_addr;
- entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
- if (entry.cdte_format == CDROM_LBA)
- entry.cdte_addr.lba =
- azt_msf2hsg(&tocPtr->diskTime);
- else if (entry.cdte_format == CDROM_MSF) {
- entry.cdte_addr.msf.minute =
- azt_bcd2bin(tocPtr->diskTime.min);
- entry.cdte_addr.msf.second =
- azt_bcd2bin(tocPtr->diskTime.sec);
- entry.cdte_addr.msf.frame =
- azt_bcd2bin(tocPtr->diskTime.frame);
- } else {
- return -EINVAL;
- }
- if (copy_to_user(argp, &entry, sizeof entry))
- return -EFAULT;
- break;
- case CDROMSUBCHNL: /* Get subchannel info */
- if (copy_from_user
- (&subchnl, argp, sizeof(struct cdrom_subchnl)))
- return -EFAULT;
- if (aztGetQChannelInfo(&qInfo) < 0) {
-#ifdef AZT_DEBUG
- printk
- ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
- cmd);
-#endif
- return -EIO;
- }
- subchnl.cdsc_audiostatus = aztAudioStatus;
- subchnl.cdsc_adr = qInfo.ctrl_addr;
- subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
- subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
- subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
- if (subchnl.cdsc_format == CDROM_LBA) {
- subchnl.cdsc_absaddr.lba =
- azt_msf2hsg(&qInfo.diskTime);
- subchnl.cdsc_reladdr.lba =
- azt_msf2hsg(&qInfo.trackTime);
- } else { /*default */
- subchnl.cdsc_format = CDROM_MSF;
- subchnl.cdsc_absaddr.msf.minute =
- azt_bcd2bin(qInfo.diskTime.min);
- subchnl.cdsc_absaddr.msf.second =
- azt_bcd2bin(qInfo.diskTime.sec);
- subchnl.cdsc_absaddr.msf.frame =
- azt_bcd2bin(qInfo.diskTime.frame);
- subchnl.cdsc_reladdr.msf.minute =
- azt_bcd2bin(qInfo.trackTime.min);
- subchnl.cdsc_reladdr.msf.second =
- azt_bcd2bin(qInfo.trackTime.sec);
- subchnl.cdsc_reladdr.msf.frame =
- azt_bcd2bin(qInfo.trackTime.frame);
- }
- if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
- return -EFAULT;
- break;
- case CDROMVOLCTRL: /* Volume control
- * With my Aztech CD268-01A volume control does not work, I can only
- turn the channels on (any value !=0) or off (value==0). Maybe it
- works better with your drive */
- if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
- return -EFAULT;
- azt_Play.start.min = 0x21;
- azt_Play.start.sec = 0x84;
- azt_Play.start.frame = volctrl.channel0;
- azt_Play.end.min = volctrl.channel1;
- azt_Play.end.sec = volctrl.channel2;
- azt_Play.end.frame = volctrl.channel3;
- sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
- STEN_LOW_WAIT;
- break;
- case CDROMEJECT:
- aztUnlockDoor(); /* Assume user knows what they're doing */
- /* all drives can at least stop! */
- if (aztAudioStatus == CDROM_AUDIO_PLAY) {
- if (aztSendCmd(ACMD_STOP))
- RETURNM("azt_ioctl 10", -1);
- STEN_LOW_WAIT;
- }
- if (aztSendCmd(ACMD_EJECT))
- RETURNM("azt_ioctl 11", -1);
- STEN_LOW_WAIT;
- aztAudioStatus = CDROM_AUDIO_NO_STATUS;
- break;
- case CDROMEJECT_SW:
- azt_auto_eject = (char) arg;
- break;
- case CDROMRESET:
- outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
- STEN_LOW;
- if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
- printk
- ("aztcd: AZTECH CD-ROM drive does not respond\n");
- }
- break;
-/*Take care, the following code is not compatible with other CD-ROM drivers,
- use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
- if you do not want to use it!
-*/
-#if AZT_PRIVATE_IOCTLS
- case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
- case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
- {
- if (copy_from_user(&msf, argp, sizeof msf))
- return -EFAULT;
- /* convert to bcd */
- azt_bin2bcd(&msf.cdmsf_min0);
- azt_bin2bcd(&msf.cdmsf_sec0);
- azt_bin2bcd(&msf.cdmsf_frame0);
- msf.cdmsf_min1 = 0;
- msf.cdmsf_sec1 = 0;
- msf.cdmsf_frame1 = 1; /*read only one frame */
- azt_Play.start.min = msf.cdmsf_min0;
- azt_Play.start.sec = msf.cdmsf_sec0;
- azt_Play.start.frame = msf.cdmsf_frame0;
- azt_Play.end.min = msf.cdmsf_min1;
- azt_Play.end.sec = msf.cdmsf_sec1;
- azt_Play.end.frame = msf.cdmsf_frame1;
- if (cmd == CDROMREADRAW) {
- if (DiskInfo.xa) {
- return -1; /*XA Disks can't be read raw */
- } else {
- if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
- return -1;
- DTEN_LOW;
- insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
- if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
- return -EFAULT;
- }
- } else
- /*CDROMREADCOOKED*/ {
- if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
- return -1;
- DTEN_LOW;
- insb(DATA_PORT, buf, CD_FRAMESIZE);
- if (copy_to_user(argp, &buf, CD_FRAMESIZE))
- return -EFAULT;
- }
- }
- break;
- case CDROMSEEK: /*seek msf address */
- if (copy_from_user(&msf, argp, sizeof msf))
- return -EFAULT;
- /* convert to bcd */
- azt_bin2bcd(&msf.cdmsf_min0);
- azt_bin2bcd(&msf.cdmsf_sec0);
- azt_bin2bcd(&msf.cdmsf_frame0);
- azt_Play.start.min = msf.cdmsf_min0;
- azt_Play.start.sec = msf.cdmsf_sec0;
- azt_Play.start.frame = msf.cdmsf_frame0;
- if (aztSeek(&azt_Play))
- return -1;
- break;
-#endif /*end of incompatible code */
- case CDROMREADMODE1: /*set read data in mode 1 */
- return aztSetDiskType(AZT_MODE_1);
- case CDROMREADMODE2: /*set read data in mode 2 */
- return aztSetDiskType(AZT_MODE_2);
- default:
- return -EINVAL;
- }
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
- jiffies);
-#endif
- return 0;
-}
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-static void azt_transfer(void)
-{
-#ifdef AZT_TEST
- printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
-#endif
- if (!current_valid())
- return;
-
- while (CURRENT->nr_sectors) {
- int bn = CURRENT->sector / 4;
- int i;
- for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
- if (i < AZT_BUF_SIZ) {
- int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
- int nr_sectors = 4 - (CURRENT->sector & 3);
- if (azt_buf_out != i) {
- azt_buf_out = i;
- if (azt_buf_bn[i] != bn) {
- azt_buf_out = -1;
- continue;
- }
- }
- if (nr_sectors > CURRENT->nr_sectors)
- nr_sectors = CURRENT->nr_sectors;
- memcpy(CURRENT->buffer, azt_buf + offs,
- nr_sectors * 512);
- CURRENT->nr_sectors -= nr_sectors;
- CURRENT->sector += nr_sectors;
- CURRENT->buffer += nr_sectors * 512;
- } else {
- azt_buf_out = -1;
- break;
- }
- }
-}
-
-static void do_aztcd_request(request_queue_t * q)
-{
-#ifdef AZT_TEST
- printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
- CURRENT->nr_sectors, jiffies);
-#endif
- if (DiskInfo.audio) {
- printk("aztcd: Error, tried to mount an Audio CD\n");
- end_request(CURRENT, 0);
- return;
- }
- azt_transfer_is_active = 1;
- while (current_valid()) {
- azt_transfer();
- if (CURRENT->nr_sectors == 0) {
- end_request(CURRENT, 1);
- } else {
- azt_buf_out = -1; /* Want to read a block not in buffer */
- if (azt_state == AZT_S_IDLE) {
- if ((!aztTocUpToDate) || aztDiskChanged) {
- if (aztUpdateToc() < 0) {
- while (current_valid())
- end_request(CURRENT, 0);
- break;
- }
- }
- azt_state = AZT_S_START;
- AztTries = 5;
- SET_TIMER(azt_poll, HZ / 100);
- }
- break;
- }
- }
- azt_transfer_is_active = 0;
-#ifdef AZT_TEST2
- printk
- ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
- azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
- printk(" do_aztcd_request ends Time:%li\n", jiffies);
-#endif
-}
-
-
-static void azt_invalidate_buffers(void)
-{
- int i;
-
-#ifdef AZT_DEBUG
- printk("aztcd: executing azt_invalidate_buffers\n");
-#endif
- for (i = 0; i < AZT_BUF_SIZ; ++i)
- azt_buf_bn[i] = -1;
- azt_buf_out = -1;
-}
-
-/*
- * Open the device special file. Check that a disk is in.
- */
-static int aztcd_open(struct inode *ip, struct file *fp)
-{
- int st;
-
-#ifdef AZT_DEBUG
- printk("aztcd: starting aztcd_open\n");
-#endif
-
- if (aztPresent == 0)
- return -ENXIO; /* no hardware */
-
- if (!azt_open_count && azt_state == AZT_S_IDLE) {
- azt_invalidate_buffers();
-
- st = getAztStatus(); /* check drive status */
- if (st == -1)
- goto err_out; /* drive doesn't respond */
-
- if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
- printk("aztcd: Door Open?\n");
- aztCloseDoor();
- st = getAztStatus();
- }
-
- if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
- printk
- ("aztcd: Disk Changed or No Disk in Drive?\n");
- aztTocUpToDate = 0;
- }
- if (aztUpdateToc())
- goto err_out;
-
- }
- ++azt_open_count;
- aztLockDoor();
-
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztcd_open\n");
-#endif
- return 0;
-
- err_out:
- return -EIO;
-}
-
-
-/*
- * On close, we flush all azt blocks from the buffer cache.
- */
-static int aztcd_release(struct inode *inode, struct file *file)
-{
-#ifdef AZT_DEBUG
- printk("aztcd: executing aztcd_release\n");
- printk("inode: %p, device: %s file: %p\n", inode,
- inode->i_bdev->bd_disk->disk_name, file);
-#endif
- if (!--azt_open_count) {
- azt_invalidate_buffers();
- aztUnlockDoor();
- if (azt_auto_eject)
- aztSendCmd(ACMD_EJECT);
- CLEAR_TIMER;
- }
- return 0;
-}
-
-static struct gendisk *azt_disk;
-
-/*
- * Test for presence of drive and initialize it. Called at boot time.
- */
-
-static int __init aztcd_init(void)
-{
- long int count, max_count;
- unsigned char result[50];
- int st;
- void* status = NULL;
- int i = 0;
- int ret = 0;
-
- if (azt_port == 0) {
- printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
- return -EIO;
- }
-
- printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
- "CD-ROM Driver\n");
- printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
- if (azt_port == -1) {
- printk
- ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
- AZT_VERSION);
- } else
- printk
- ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
- AZT_VERSION, azt_port);
- printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
- "Documentation/cdrom/aztcd\n");
-
-
-#ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
- if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
- printk
- ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
- AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
- AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
- return -EIO;
- } else {
- printk(KERN_INFO
- "aztcd: Soundwave32 card detected at %x Version %x\n",
- AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
- outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
- for (count = 0; count < 10000; count++); /*delay a bit */
- }
-#endif
-
- /* check for presence of drive */
-
- if (azt_port == -1) { /* autoprobing for proprietary interface */
- for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
- azt_port = azt_port_auto[i];
- printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
- "\n", azt_port);
- /*proprietary interfaces need 4 bytes */
- if (!request_region(azt_port, 4, "aztcd")) {
- continue;
- }
- outb(POLLED, MODE_PORT);
- inb(CMD_PORT);
- inb(CMD_PORT);
- outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
-
- aztTimeOutCount = 0;
- do {
- aztIndatum = inb(STATUS_PORT);
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
- break;
- } while (aztIndatum & AFL_STATUS);
- if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
- break;
- }
- else { /* Drive not found on this port - try next one */
- release_region(azt_port, 4);
- }
- }
- if ((i == 16) || (azt_port_auto[i] == 0)) {
- printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
- return -EIO;
- }
- } else { /* no autoprobing */
- if ((azt_port == 0x1f0) || (azt_port == 0x170))
- status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
- else
- status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
- if (!status) {
- printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
- "already used\n", azt_port);
- return -EIO;
- }
-
- if ((azt_port == 0x1f0) || (azt_port == 0x170))
- SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
-
- outb(POLLED, MODE_PORT);
- inb(CMD_PORT);
- inb(CMD_PORT);
- outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
-
- aztTimeOutCount = 0;
- do {
- aztIndatum = inb(STATUS_PORT);
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
- break;
- } while (aztIndatum & AFL_STATUS);
-
- if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
-#ifndef MODULE
- if (azt_cont != 0x79) {
- printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
- "drive found-Try boot parameter aztcd="
- "<BaseAddress>,0x79\n");
- ret = -EIO;
- goto err_out;
- }
-#else
- if (0) {
- }
-#endif
- else {
- printk(KERN_INFO "aztcd: drive reset - "
- "please wait\n");
- for (count = 0; count < 50; count++) {
- inb(STATUS_PORT); /*removing all data from earlier tries */
- inb(DATA_PORT);
- }
- outb(POLLED, MODE_PORT);
- inb(CMD_PORT);
- inb(CMD_PORT);
- getAztStatus(); /*trap errors */
- outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
- STEN_LOW;
- if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
- printk(KERN_WARNING "aztcd: no AZTECH "
- "CD-ROM drive found\n");
- ret = -EIO;
- goto err_out;
- }
-
- for (count = 0; count < AZT_TIMEOUT;
- count++)
- barrier(); /* Stop gcc 2.96 being smart */
- /* use udelay(), damnit -- AV */
-
- if ((st = getAztStatus()) == -1) {
- printk(KERN_WARNING "aztcd: Drive Status"
- " Error Status=%x\n", st);
- ret = -EIO;
- goto err_out;
- }
-#ifdef AZT_DEBUG
- printk(KERN_DEBUG "aztcd: Status = %x\n", st);
-#endif
- outb(POLLED, MODE_PORT);
- inb(CMD_PORT);
- inb(CMD_PORT);
- outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
- STEN_LOW;
- OP_OK;
- }
- }
- }
-
- azt_init_end = 1;
- STEN_LOW;
- result[0] = inb(DATA_PORT); /*reading in a null byte??? */
- for (count = 1; count < 50; count++) { /*Reading version string */
- aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
- do {
- aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
- aztTimeOutCount++;
- if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
- break;
- } while (aztIndatum & AFL_STATUS);
- if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
- break; /*all chars read? */
- result[count] = inb(DATA_PORT);
- }
- if (count > 30)
- max_count = 30; /*print max.30 chars of the version string */
- else
- max_count = count;
- printk(KERN_INFO "aztcd: FirmwareVersion=");
- for (count = 1; count < max_count; count++)
- printk("%c", result[count]);
- printk("<<>> ");
-
- if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
- printk("AZTECH drive detected\n");
- /*AZTECH*/}
- else if ((result[2] == 'C') && (result[3] == 'D')
- && (result[4] == 'D')) {
- printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
- } else if ((result[1] == 0x03) && (result[2] == '5')) {
- printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
- } else { /*OTHERS or none */
- printk("\nunknown drive or firmware version detected\n");
- printk
- ("aztcd may not run stable, if you want to try anyhow,\n");
- printk("boot with: aztcd=<BaseAddress>,0x79\n");
- if ((azt_cont != 0x79)) {
- printk("aztcd: FirmwareVersion=");
- for (count = 1; count < 5; count++)
- printk("%c", result[count]);
- printk("<<>> ");
- printk("Aborted\n");
- ret = -EIO;
- goto err_out;
- }
- }
- azt_disk = alloc_disk(1);
- if (!azt_disk)
- goto err_out;
-
- if (register_blkdev(MAJOR_NR, "aztcd")) {
- ret = -EIO;
- goto err_out2;
- }
-
- azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
- if (!azt_queue) {
- ret = -ENOMEM;
- goto err_out3;
- }
-
- blk_queue_hardsect_size(azt_queue, 2048);
- azt_disk->major = MAJOR_NR;
- azt_disk->first_minor = 0;
- azt_disk->fops = &azt_fops;
- sprintf(azt_disk->disk_name, "aztcd");
- azt_disk->queue = azt_queue;
- add_disk(azt_disk);
- azt_invalidate_buffers();
- aztPresent = 1;
- aztCloseDoor();
- return 0;
-err_out3:
- unregister_blkdev(MAJOR_NR, "aztcd");
-err_out2:
- put_disk(azt_disk);
-err_out:
- if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
- SWITCH_IDE_MASTER;
- release_region(azt_port, 8); /*IDE-interface */
- } else
- release_region(azt_port, 4); /*proprietary interface */
- return ret;
-
-}
-
-static void __exit aztcd_exit(void)
-{
- del_gendisk(azt_disk);
- put_disk(azt_disk);
- if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
- printk("What's that: can't unregister aztcd\n");
- return;
- }
- blk_cleanup_queue(azt_queue);
- if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
- SWITCH_IDE_MASTER;
- release_region(azt_port, 8); /*IDE-interface */
- } else
- release_region(azt_port, 4); /*proprietary interface */
- printk(KERN_INFO "aztcd module released.\n");
-}
-
-module_init(aztcd_init);
-module_exit(aztcd_exit);
-
-/*##########################################################################
- Aztcd State Machine: Controls Drive Operating State
- ##########################################################################
-*/
-static void azt_poll(void)
-{
- int st = 0;
- int loop_ctl = 1;
- int skip = 0;
-
- if (azt_error) {
- if (aztSendCmd(ACMD_GET_ERROR))
- RETURN("azt_poll 1");
- STEN_LOW;
- azt_error = inb(DATA_PORT) & 0xFF;
- printk("aztcd: I/O error 0x%02x\n", azt_error);
- azt_invalidate_buffers();
-#ifdef WARN_IF_READ_FAILURE
- if (AztTries == 5)
- printk
- ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
- azt_next_bn);
-#endif
- if (!AztTries--) {
- printk
- ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
- azt_next_bn);
- if (azt_transfer_is_active) {
- AztTries = 0;
- loop_ctl = 0;
- }
- if (current_valid())
- end_request(CURRENT, 0);
- AztTries = 5;
- }
- azt_error = 0;
- azt_state = AZT_S_STOP;
- }
-
- while (loop_ctl) {
- loop_ctl = 0; /* each case must flip this back to 1 if we want
- to come back up here */
- switch (azt_state) {
-
- case AZT_S_IDLE:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_IDLE\n");
- }
-#endif
- return;
-
- case AZT_S_START:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_START\n");
- }
-#endif
- if (aztSendCmd(ACMD_GET_STATUS))
- RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
- azt_state =
- azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
- AztTimeout = 3000;
- break;
-
- case AZT_S_MODE:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_MODE\n");
- }
-#endif
- if (!skip) {
- if ((st = aztStatus()) != -1) {
- if ((st & AST_DSK_CHG)
- || (st & AST_NOT_READY)) {
- aztDiskChanged = 1;
- aztTocUpToDate = 0;
- azt_invalidate_buffers();
- end_request(CURRENT, 0);
- printk
- ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
- }
- } else
- break;
- }
- skip = 0;
-
- if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
- aztDiskChanged = 1;
- aztTocUpToDate = 0;
- printk
- ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
- end_request(CURRENT, 0);
- printk((st & AST_DOOR_OPEN) ?
- "aztcd: door open\n" :
- "aztcd: disk removed\n");
- if (azt_transfer_is_active) {
- azt_state = AZT_S_START;
- loop_ctl = 1; /* goto immediately */
- break;
- }
- azt_state = AZT_S_IDLE;
- while (current_valid())
- end_request(CURRENT, 0);
- return;
- }
-
-/* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
- outb(0x01, DATA_PORT);
- PA_OK;
- STEN_LOW;
-*/
- if (aztSendCmd(ACMD_GET_STATUS))
- RETURN("azt_poll 4");
- STEN_LOW;
- azt_mode = 1;
- azt_state = AZT_S_READ;
- AztTimeout = 3000;
-
- break;
-
-
- case AZT_S_READ:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_READ\n");
- }
-#endif
- if (!skip) {
- if ((st = aztStatus()) != -1) {
- if ((st & AST_DSK_CHG)
- || (st & AST_NOT_READY)) {
- aztDiskChanged = 1;
- aztTocUpToDate = 0;
- azt_invalidate_buffers();
- printk
- ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
- end_request(CURRENT, 0);
- }
- } else
- break;
- }
-
- skip = 0;
- if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
- aztDiskChanged = 1;
- aztTocUpToDate = 0;
- printk((st & AST_DOOR_OPEN) ?
- "aztcd: door open\n" :
- "aztcd: disk removed\n");
- if (azt_transfer_is_active) {
- azt_state = AZT_S_START;
- loop_ctl = 1;
- break;
- }
- azt_state = AZT_S_IDLE;
- while (current_valid())
- end_request(CURRENT, 0);
- return;
- }
-
- if (current_valid()) {
- struct azt_Play_msf msf;
- int i;
- azt_next_bn = CURRENT->sector / 4;
- azt_hsg2msf(azt_next_bn, &msf.start);
- i = 0;
- /* find out in which track we are */
- while (azt_msf2hsg(&msf.start) >
- azt_msf2hsg(&Toc[++i].trackTime)) {
- };
- if (azt_msf2hsg(&msf.start) <
- azt_msf2hsg(&Toc[i].trackTime) -
- AZT_BUF_SIZ) {
- azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
- /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
- } else /* don't read beyond end of track */
-#if AZT_MULTISESSION
- {
- azt_read_count =
- (azt_msf2hsg(&Toc[i].trackTime)
- / 4) * 4 -
- azt_msf2hsg(&msf.start);
- if (azt_read_count < 0)
- azt_read_count = 0;
- if (azt_read_count > AZT_BUF_SIZ)
- azt_read_count =
- AZT_BUF_SIZ;
- printk
- ("aztcd: warning - trying to read beyond end of track\n");
-/* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
-*/ }
-#else
- {
- azt_read_count = AZT_BUF_SIZ;
- }
-#endif
- msf.end.min = 0;
- msf.end.sec = 0;
- msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
-#ifdef AZT_TEST3
- printk
- ("---reading msf-address %x:%x:%x %x:%x:%x\n",
- msf.start.min, msf.start.sec,
- msf.start.frame, msf.end.min,
- msf.end.sec, msf.end.frame);
- printk
- ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
- azt_next_bn, azt_buf_in, azt_buf_out,
- azt_buf_bn[azt_buf_in]);
-#endif
- if (azt_read_mode == AZT_MODE_2) {
- sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
- } else {
- sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
- }
- azt_state = AZT_S_DATA;
- AztTimeout = READ_TIMEOUT;
- } else {
- azt_state = AZT_S_STOP;
- loop_ctl = 1;
- break;
- }
-
- break;
-
-
- case AZT_S_DATA:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_DATA\n");
- }
-#endif
-
- st = inb(STATUS_PORT) & AFL_STATUSorDATA;
-
- switch (st) {
-
- case AFL_DATA:
-#ifdef AZT_TEST3
- if (st != azt_st_old) {
- azt_st_old = st;
- printk("---AFL_DATA st:%x\n", st);
- }
-#endif
- if (!AztTries--) {
- printk
- ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
- azt_next_bn);
- if (azt_transfer_is_active) {
- AztTries = 0;
- break;
- }
- if (current_valid())
- end_request(CURRENT, 0);
- AztTries = 5;
- }
- azt_state = AZT_S_START;
- AztTimeout = READ_TIMEOUT;
- loop_ctl = 1;
- break;
-
- case AFL_STATUSorDATA:
-#ifdef AZT_TEST3
- if (st != azt_st_old) {
- azt_st_old = st;
- printk
- ("---AFL_STATUSorDATA st:%x\n",
- st);
- }
-#endif
- break;
-
- default:
-#ifdef AZT_TEST3
- if (st != azt_st_old) {
- azt_st_old = st;
- printk("---default: st:%x\n", st);
- }
-#endif
- AztTries = 5;
- if (!current_valid() && azt_buf_in == azt_buf_out) {
- azt_state = AZT_S_STOP;
- loop_ctl = 1;
- break;
- }
- if (azt_read_count <= 0)
- printk
- ("aztcd: warning - try to read 0 frames\n");
- while (azt_read_count) { /*??? fast read ahead loop */
- azt_buf_bn[azt_buf_in] = -1;
- DTEN_LOW; /*??? unsolved problem, very
- seldom we get timeouts
- here, don't now the real
- reason. With my drive this
- sometimes also happens with
- Aztech's original driver under
- DOS. Is it a hardware bug?
- I tried to recover from such
- situations here. Zimmermann */
- if (aztTimeOutCount >= AZT_TIMEOUT) {
- printk
- ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
- azt_read_count,
- CURRENT->nr_sectors,
- azt_buf_in);
- printk
- ("azt_transfer_is_active:%x\n",
- azt_transfer_is_active);
- azt_read_count = 0;
- azt_state = AZT_S_STOP;
- loop_ctl = 1;
- end_request(CURRENT, 1); /*should we have here (1) or (0)? */
- } else {
- if (azt_read_mode ==
- AZT_MODE_2) {
- insb(DATA_PORT,
- azt_buf +
- CD_FRAMESIZE_RAW
- * azt_buf_in,
- CD_FRAMESIZE_RAW);
- } else {
- insb(DATA_PORT,
- azt_buf +
- CD_FRAMESIZE *
- azt_buf_in,
- CD_FRAMESIZE);
- }
- azt_read_count--;
-#ifdef AZT_TEST3
- printk
- ("AZT_S_DATA; ---I've read data- read_count: %d\n",
- azt_read_count);
- printk
- ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
- azt_next_bn,
- azt_buf_in,
- azt_buf_out,
- azt_buf_bn
- [azt_buf_in]);
-#endif
- azt_buf_bn[azt_buf_in] =
- azt_next_bn++;
- if (azt_buf_out == -1)
- azt_buf_out =
- azt_buf_in;
- azt_buf_in =
- azt_buf_in + 1 ==
- AZT_BUF_SIZ ? 0 :
- azt_buf_in + 1;
- }
- }
- if (!azt_transfer_is_active) {
- while (current_valid()) {
- azt_transfer();
- if (CURRENT->nr_sectors ==
- 0)
- end_request(CURRENT, 1);
- else
- break;
- }
- }
-
- if (current_valid()
- && (CURRENT->sector / 4 < azt_next_bn
- || CURRENT->sector / 4 >
- azt_next_bn + AZT_BUF_SIZ)) {
- azt_state = AZT_S_STOP;
- loop_ctl = 1;
- break;
- }
- AztTimeout = READ_TIMEOUT;
- if (azt_read_count == 0) {
- azt_state = AZT_S_STOP;
- loop_ctl = 1;
- break;
- }
- break;
- }
- break;
-
-
- case AZT_S_STOP:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_STOP\n");
- }
-#endif
- if (azt_read_count != 0)
- printk("aztcd: discard data=%x frames\n",
- azt_read_count);
- while (azt_read_count != 0) {
- int i;
- if (!(inb(STATUS_PORT) & AFL_DATA)) {
- if (azt_read_mode == AZT_MODE_2)
- for (i = 0;
- i < CD_FRAMESIZE_RAW;
- i++)
- inb(DATA_PORT);
- else
- for (i = 0;
- i < CD_FRAMESIZE; i++)
- inb(DATA_PORT);
- }
- azt_read_count--;
- }
- if (aztSendCmd(ACMD_GET_STATUS))
- RETURN("azt_poll 5");
- azt_state = AZT_S_STOPPING;
- AztTimeout = 1000;
- break;
-
- case AZT_S_STOPPING:
-#ifdef AZT_TEST3
- if (azt_state != azt_state_old) {
- azt_state_old = azt_state;
- printk("AZT_S_STOPPING\n");
- }
-#endif
-
- if ((st = aztStatus()) == -1 && AztTimeout)
- break;
-
- if ((st != -1)
- && ((st & AST_DSK_CHG)
- || (st & AST_NOT_READY))) {
- aztDiskChanged = 1;
- aztTocUpToDate = 0;
- azt_invalidate_buffers();
- printk
- ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
- end_request(CURRENT, 0);
- }
-
-#ifdef AZT_TEST3
- printk("CURRENT_VALID %d azt_mode %d\n",
- current_valid(), azt_mode);
-#endif
-
- if (current_valid()) {
- if (st != -1) {
- if (azt_mode == 1) {
- azt_state = AZT_S_READ;
- loop_ctl = 1;
- skip = 1;
- break;
- } else {
- azt_state = AZT_S_MODE;
- loop_ctl = 1;
- skip = 1;
- break;
- }
- } else {
- azt_state = AZT_S_START;
- AztTimeout = 1;
- }
- } else {
- azt_state = AZT_S_IDLE;
- return;
- }
- break;
-
- default:
- printk("aztcd: invalid state %d\n", azt_state);
- return;
- } /* case */
- } /* while */
-
-
- if (!AztTimeout--) {
- printk("aztcd: timeout in state %d\n", azt_state);
- azt_state = AZT_S_STOP;
- if (aztSendCmd(ACMD_STOP))
- RETURN("azt_poll 6");
- STEN_LOW_WAIT;
- };
-
- SET_TIMER(azt_poll, HZ / 100);
-}
-
-
-/*###########################################################################
- * Miscellaneous support functions
- ###########################################################################
-*/
-static void azt_hsg2msf(long hsg, struct msf *msf)
-{
- hsg += 150;
- msf->min = hsg / 4500;
- hsg %= 4500;
- msf->sec = hsg / 75;
- msf->frame = hsg % 75;
-#ifdef AZT_DEBUG
- if (msf->min >= 70)
- printk("aztcd: Error hsg2msf address Minutes\n");
- if (msf->sec >= 60)
- printk("aztcd: Error hsg2msf address Seconds\n");
- if (msf->frame >= 75)
- printk("aztcd: Error hsg2msf address Frames\n");
-#endif
- azt_bin2bcd(&msf->min); /* convert to BCD */
- azt_bin2bcd(&msf->sec);
- azt_bin2bcd(&msf->frame);
-}
-
-static long azt_msf2hsg(struct msf *mp)
-{
- return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
- + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
-}
-
-static void azt_bin2bcd(unsigned char *p)
-{
- int u, t;
-
- u = *p % 10;
- t = *p / 10;
- *p = u | (t << 4);
-}
-
-static int azt_bcd2bin(unsigned char bcd)
-{
- return (bcd >> 4) * 10 + (bcd & 0xF);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);
diff --git a/drivers/cdrom/aztcd.h b/drivers/cdrom/aztcd.h
deleted file mode 100644
index 057501e31628..000000000000
--- a/drivers/cdrom/aztcd.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* $Id: aztcd.h,v 2.60 1997/11/29 09:51:22 root Exp root $
- *
- * Definitions for a AztechCD268 CD-ROM interface
- * Copyright (C) 1994-98 Werner Zimmermann
- *
- * based on Mitsumi CDROM driver by Martin Harriss
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * History: W.Zimmermann adaption to Aztech CD268-01A Version 1.3
- * October 1994 Email: Werner.Zimmermann@fht-esslingen.de
- */
-
-/* *** change this to set the I/O port address of your CD-ROM drive,
- set to '-1', if you want autoprobing */
-#define AZT_BASE_ADDR -1
-
-/* list of autoprobing addresses (not more than 15), last value must be 0x000
- Note: Autoprobing is only enabled, if AZT_BASE_ADDR is set to '-1' ! */
-#define AZT_BASE_AUTO { 0x320, 0x300, 0x310, 0x330, 0x000 }
-
-/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard
- and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */
-/*#define AZT_SW32 1
-*/
-
-#ifdef AZT_SW32
-#define AZT_SW32_BASE_ADDR 0x220 /*I/O port base address of your soundcard*/
-#endif
-
-/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray
- from locking */
-#define AZT_ALLOW_TRAY_LOCK 1
-
-/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you
- don't want the auto-eject feature*/
-#define AZT_AUTO_EJECT 0
-
-/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
- cooked mode */
-#define AZT_PRIVATE_IOCTLS 1
-
-/*Set this to 1, if you want multisession support by the ISO fs. Even if you set
- this value to '0' you can use multisession CDs. In that case the drive's firm-
- ware will do the appropriate redirection automatically. The CD will then look
- like a single session CD (but nevertheless all data may be read). Please read
- chapter '5.1 Multisession support' in README.aztcd for details. Normally it's
- uncritical to leave this setting untouched */
-#define AZT_MULTISESSION 1
-
-/*Uncomment this, if you are using a linux kernel version prior to 2.1.0 */
-/*#define AZT_KERNEL_PRIOR_2_1 */
-
-/*---------------------------------------------------------------------------*/
-/*-----nothing to be configured for normal applications below this line------*/
-
-
-/* Increase this if you get lots of timeouts; if you get kernel panic, replace
- STEN_LOW_WAIT by STEN_LOW in the source code */
-#define AZT_STATUS_DELAY 400 /*for timer wait, STEN_LOW_WAIT*/
-#define AZT_TIMEOUT 8000000 /*for busy wait STEN_LOW, DTEN_LOW*/
-#define AZT_FAST_TIMEOUT 10000 /*for reading the version string*/
-
-/* number of times to retry a command before giving up */
-#define AZT_RETRY_ATTEMPTS 3
-
-/* port access macros */
-#define CMD_PORT azt_port
-#define DATA_PORT azt_port
-#define STATUS_PORT azt_port+1
-#define MODE_PORT azt_port+2
-#ifdef AZT_SW32
- #define AZT_SW32_INIT (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16))
- #define AZT_SW32_CONFIG_REG AZT_SW32_BASE_ADDR+0x16 /*Soundwave32 Config. Register*/
- #define AZT_SW32_ID_REG AZT_SW32_BASE_ADDR+0x04 /*Soundwave32 ID Version Register*/
-#endif
-
-/* status bits */
-#define AST_CMD_CHECK 0x80 /* 1 = command error */
-#define AST_DOOR_OPEN 0x40 /* 1 = door is open */
-#define AST_NOT_READY 0x20 /* 1 = no disk in the drive */
-#define AST_DSK_CHG 0x02 /* 1 = disk removed or changed */
-#define AST_MODE 0x01 /* 0=MODE1, 1=MODE2 */
-#define AST_MODE_BITS 0x1C /* Mode Bits */
-#define AST_INITIAL 0x0C /* initial, only valid ... */
-#define AST_BUSY 0x04 /* now playing, only valid
- in combination with mode
- bits */
-/* flag bits */
-#define AFL_DATA 0x02 /* data available if low */
-#define AFL_STATUS 0x04 /* status available if low */
-#define AFL_OP_OK 0x01 /* OP_OK command correct*/
-#define AFL_PA_OK 0x02 /* PA_OK parameter correct*/
-#define AFL_OP_ERR 0x05 /* error in command*/
-#define AFL_PA_ERR 0x06 /* error in parameters*/
-#define POLLED 0x04 /* polled mode */
-
-/* commands */
-#define ACMD_SOFT_RESET 0x10 /* reset drive */
-#define ACMD_PLAY_READ 0x20 /* read data track in cooked mode */
-#define ACMD_PLAY_READ_RAW 0x21 /* reading in raw mode*/
-#define ACMD_SEEK 0x30 /* seek msf address*/
-#define ACMD_SEEK_TO_LEADIN 0x31 /* seek to leadin track*/
-#define ACMD_GET_ERROR 0x40 /* get error code */
-#define ACMD_GET_STATUS 0x41 /* get status */
-#define ACMD_GET_Q_CHANNEL 0x50 /* read info from q channel */
-#define ACMD_EJECT 0x60 /* eject/open tray */
-#define ACMD_CLOSE 0x61 /* close tray */
-#define ACMD_LOCK 0x71 /* lock tray closed */
-#define ACMD_UNLOCK 0x72 /* unlock tray */
-#define ACMD_PAUSE 0x80 /* pause */
-#define ACMD_STOP 0x81 /* stop play */
-#define ACMD_PLAY_AUDIO 0x90 /* play audio track */
-#define ACMD_SET_VOLUME 0x93 /* set audio level */
-#define ACMD_GET_VERSION 0xA0 /* get firmware version */
-#define ACMD_SET_DISK_TYPE 0xA1 /* set disk data mode */
-
-#define MAX_TRACKS 104
-
-struct msf {
- unsigned char min;
- unsigned char sec;
- unsigned char frame;
-};
-
-struct azt_Play_msf {
- struct msf start;
- struct msf end;
-};
-
-struct azt_DiskInfo {
- unsigned char first;
- unsigned char next;
- unsigned char last;
- struct msf diskLength;
- struct msf firstTrack;
- unsigned char multi;
- struct msf nextSession;
- struct msf lastSession;
- unsigned char xa;
- unsigned char audio;
-};
-
-struct azt_Toc {
- unsigned char ctrl_addr;
- unsigned char track;
- unsigned char pointIndex;
- struct msf trackTime;
- struct msf diskTime;
-};
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 3625a05bc3d3..aa5468f487ba 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -302,7 +302,7 @@ module_param(lockdoor, bool, 0);
module_param(check_media_type, bool, 0);
module_param(mrw_format_restart, bool, 0);
-static DEFINE_SPINLOCK(cdrom_lock);
+static DEFINE_MUTEX(cdrom_mutex);
static const char *mrw_format_status[] = {
"not mrw",
@@ -438,10 +438,10 @@ int register_cdrom(struct cdrom_device_info *cdi)
cdo->generic_packet = cdrom_dummy_generic_packet;
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
- spin_lock(&cdrom_lock);
+ mutex_lock(&cdrom_mutex);
cdi->next = topCdromPtr;
topCdromPtr = cdi;
- spin_unlock(&cdrom_lock);
+ mutex_unlock(&cdrom_mutex);
return 0;
}
#undef ENSURE
@@ -452,7 +452,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
cdinfo(CD_OPEN, "entering unregister_cdrom\n");
prev = NULL;
- spin_lock(&cdrom_lock);
+ mutex_lock(&cdrom_mutex);
cdi = topCdromPtr;
while (cdi && cdi != unreg) {
prev = cdi;
@@ -460,7 +460,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
}
if (cdi == NULL) {
- spin_unlock(&cdrom_lock);
+ mutex_unlock(&cdrom_mutex);
return -2;
}
if (prev)
@@ -468,7 +468,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
else
topCdromPtr = cdi->next;
- spin_unlock(&cdrom_lock);
+ mutex_unlock(&cdrom_mutex);
if (cdi->exit)
cdi->exit(cdi);
@@ -3289,103 +3289,137 @@ static struct cdrom_sysctl_settings {
int check; /* check media type */
} cdrom_sysctl_settings;
+enum cdrom_print_option {
+ CTL_NAME,
+ CTL_SPEED,
+ CTL_SLOTS,
+ CTL_CAPABILITY
+};
+
+static int cdrom_print_info(const char *header, int val, char *info,
+ int *pos, enum cdrom_print_option option)
+{
+ const int max_size = sizeof(cdrom_sysctl_settings.info);
+ struct cdrom_device_info *cdi;
+ int ret;
+
+ ret = scnprintf(info + *pos, max_size - *pos, header);
+ if (!ret)
+ return 1;
+
+ *pos += ret;
+
+ for (cdi = topCdromPtr; cdi; cdi = cdi->next) {
+ switch (option) {
+ case CTL_NAME:
+ ret = scnprintf(info + *pos, max_size - *pos,
+ "\t%s", cdi->name);
+ break;
+ case CTL_SPEED:
+ ret = scnprintf(info + *pos, max_size - *pos,
+ "\t%d", cdi->speed);
+ break;
+ case CTL_SLOTS:
+ ret = scnprintf(info + *pos, max_size - *pos,
+ "\t%d", cdi->capacity);
+ break;
+ case CTL_CAPABILITY:
+ ret = scnprintf(info + *pos, max_size - *pos,
+ "\t%d", CDROM_CAN(val) != 0);
+ break;
+ default:
+ printk(KERN_INFO "cdrom: invalid option%d\n", option);
+ return 1;
+ }
+ if (!ret)
+ return 1;
+ *pos += ret;
+ }
+
+ return 0;
+}
+
static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
- int pos;
- struct cdrom_device_info *cdi;
+ int pos;
char *info = cdrom_sysctl_settings.info;
+ const int max_size = sizeof(cdrom_sysctl_settings.info);
if (!*lenp || (*ppos && !write)) {
*lenp = 0;
return 0;
}
+ mutex_lock(&cdrom_mutex);
+
pos = sprintf(info, "CD-ROM information, " VERSION "\n");
- pos += sprintf(info+pos, "\ndrive name:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%s", cdi->name);
-
- pos += sprintf(info+pos, "\ndrive speed:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", cdi->speed);
-
- pos += sprintf(info+pos, "\ndrive # of slots:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", cdi->capacity);
-
- pos += sprintf(info+pos, "\nCan close tray:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0);
-
- pos += sprintf(info+pos, "\nCan open tray:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0);
-
- pos += sprintf(info+pos, "\nCan lock tray:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK) != 0);
-
- pos += sprintf(info+pos, "\nCan change speed:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0);
-
- pos += sprintf(info+pos, "\nCan select disk:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC) != 0);
-
- pos += sprintf(info+pos, "\nCan read multisession:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0);
-
- pos += sprintf(info+pos, "\nCan read MCN:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN) != 0);
-
- pos += sprintf(info+pos, "\nReports media changed:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0);
-
- pos += sprintf(info+pos, "\nCan play audio:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0);
-
- pos += sprintf(info+pos, "\nCan write CD-R:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_R) != 0);
-
- pos += sprintf(info+pos, "\nCan write CD-RW:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_RW) != 0);
-
- pos += sprintf(info+pos, "\nCan read DVD:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD) != 0);
-
- pos += sprintf(info+pos, "\nCan write DVD-R:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_R) != 0);
-
- pos += sprintf(info+pos, "\nCan write DVD-RAM:");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
-
- pos += sprintf(info+pos, "\nCan read MRW:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW) != 0);
-
- pos += sprintf(info+pos, "\nCan write MRW:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW_W) != 0);
-
- pos += sprintf(info+pos, "\nCan write RAM:\t");
- for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
- pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_RAM) != 0);
-
- strcpy(info+pos,"\n\n");
-
- return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME))
+ goto done;
+ if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED))
+ goto done;
+ if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS))
+ goto done;
+ if (cdrom_print_info("\nCan close tray:\t",
+ CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan open tray:\t",
+ CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan lock tray:\t",
+ CDC_LOCK, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan change speed:",
+ CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan select disk:",
+ CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan read multisession:",
+ CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan read MCN:\t",
+ CDC_MCN, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nReports media changed:",
+ CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan play audio:\t",
+ CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan write CD-R:\t",
+ CDC_CD_R, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan write CD-RW:",
+ CDC_CD_RW, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan read DVD:\t",
+ CDC_DVD, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan write DVD-R:",
+ CDC_DVD_R, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan write DVD-RAM:",
+ CDC_DVD_RAM, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan read MRW:\t",
+ CDC_MRW, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan write MRW:\t",
+ CDC_MRW_W, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (cdrom_print_info("\nCan write RAM:\t",
+ CDC_RAM, info, &pos, CTL_CAPABILITY))
+ goto done;
+ if (!scnprintf(info + pos, max_size - pos, "\n\n"))
+ goto done;
+doit:
+ mutex_unlock(&cdrom_mutex);
+ return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+done:
+ printk(KERN_INFO "cdrom: info buffer too small\n");
+ goto doit;
}
/* Unfortunately, per device settings are not implemented through
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
deleted file mode 100644
index 2157c58755e0..000000000000
--- a/drivers/cdrom/cdu31a.c
+++ /dev/null
@@ -1,3251 +0,0 @@
-/*
-* Sony CDU-31A CDROM interface device driver.
-*
-* Corey Minyard (minyard@wf-rch.cirr.com)
-*
-* Colossians 3:17
-*
-* See Documentation/cdrom/cdu31a for additional details about this driver.
-*
-* The Sony interface device driver handles Sony interface CDROM
-* drives and provides a complete block-level interface as well as an
-* ioctl() interface compatible with the Sun (as specified in
-* include/linux/cdrom.h). With this interface, CDROMs can be
-* accessed and standard audio CDs can be played back normally.
-*
-* WARNING - All autoprobes have been removed from the driver.
-* You MUST configure the CDU31A via a LILO config
-* at boot time or in lilo.conf. I have the
-* following in my lilo.conf:
-*
-* append="cdu31a=0x1f88,0,PAS"
-*
-* The first number is the I/O base address of the
-* card. The second is the interrupt (0 means none).
- * The third should be "PAS" if on a Pro-Audio
- * spectrum, or nothing if on something else.
- *
- * This interface is (unfortunately) a polled interface. This is
- * because most Sony interfaces are set up with DMA and interrupts
- * disables. Some (like mine) do not even have the capability to
- * handle interrupts or DMA. For this reason you will see a lot of
- * the following:
- *
- * retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
- * while (time_before(jiffies, retry_count) && (! <some condition to wait for))
- * {
- * while (handle_sony_cd_attention())
- * ;
- *
- * sony_sleep();
- * }
- * if (the condition not met)
- * {
- * return an error;
- * }
- *
- * This ugly hack waits for something to happen, sleeping a little
- * between every try. it also handles attentions, which are
- * asynchronous events from the drive informing the driver that a disk
- * has been inserted, removed, etc.
- *
- * NEWS FLASH - The driver now supports interrupts but they are
- * turned off by default. Use of interrupts is highly encouraged, it
- * cuts CPU usage down to a reasonable level. I had DMA in for a while
- * but PC DMA is just too slow. Better to just insb() it.
- *
- * One thing about these drives: They talk in MSF (Minute Second Frame) format.
- * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
- * disk. The funny thing is that these are sent to the drive in BCD, but the
- * interface wants to see them in decimal. A lot of conversion goes on.
- *
- * DRIVER SPECIAL FEATURES
- * -----------------------
- *
- * This section describes features beyond the normal audio and CD-ROM
- * functions of the drive.
- *
- * XA compatibility
- *
- * The driver should support XA disks for both the CDU31A and CDU33A.
- * It does this transparently, the using program doesn't need to set it.
- *
- * Multi-Session
- *
- * A multi-session disk looks just like a normal disk to the user.
- * Just mount one normally, and all the data should be there.
- * A special thanks to Koen for help with this!
- *
- * Raw sector I/O
- *
- * Using the CDROMREADAUDIO it is possible to read raw audio and data
- * tracks. Both operations return 2352 bytes per sector. On the data
- * tracks, the first 12 bytes is not returned by the drive and the value
- * of that data is indeterminate.
- *
- *
- * Copyright (C) 1993 Corey Minyard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- * CDs with form1 and form2 sectors cause problems
- * with current read-ahead strategy.
- *
- * Credits:
- * Heiko Eissfeldt <heiko@colossus.escape.de>
- * For finding abug in the return of the track numbers.
- * TOC processing redone for proper multisession support.
- *
- *
- * It probably a little late to be adding a history, but I guess I
- * will start.
- *
- * 10/24/95 - Added support for disabling the eject button when the
- * drive is open. Note that there is a small problem
- * still here, if the eject button is pushed while the
- * drive light is flashing, the drive will return a bad
- * status and be reset. It recovers, though.
- *
- * 03/07/97 - Fixed a problem with timers.
- *
- *
- * 18 Spetember 1997 -- Ported to Uniform CD-ROM driver by
- * Heiko Eissfeldt <heiko@colossus.escape.de> with additional
- * changes by Erik Andersen <andersee@debian.org>
- *
- * 24 January 1998 -- Removed the scd_disc_status() function, which was now
- * just dead code left over from the port.
- * Erik Andersen <andersee@debian.org>
- *
- * 16 July 1998 -- Drive donated to Erik Andersen by John Kodis
- * <kodis@jagunet.com>. Work begun on fixing driver to
- * work under 2.1.X. Added temporary extra printks
- * which seem to slow it down enough to work.
- *
- * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
- * Removed init_module & cleanup_module in favor of
- * module_init & module_exit.
- * Torben Mathiasen <tmm@image.dk>
- *
- * 22 October 2004 -- Make the driver work in 2.6.X
- * Added workaround to fix hard lockups on eject
- * Fixed door locking problem after mounting empty drive
- * Set double-speed drives to double speed by default
- * Removed all readahead things - not needed anymore
- * Ondrej Zary <rainbow@rainbow-software.org>
-*/
-
-#define DEBUG 1
-
-#include <linux/major.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/hdreg.h>
-#include <linux/genhd.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/cdrom.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/dma.h>
-
-#include "cdu31a.h"
-
-#define MAJOR_NR CDU31A_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
-
-#define PFX "CDU31A: "
-
-/*
-** Edit the following data to change interrupts, DMA channels, etc.
-** Default is polled and no DMA. DMA is not recommended for double-speed
-** drives.
-*/
-static struct {
- unsigned short base; /* I/O Base Address */
- short int_num; /* Interrupt Number (-1 means scan for it,
- 0 means don't use) */
-} cdu31a_addresses[] __initdata = {
- {0}
-};
-
-static int handle_sony_cd_attention(void);
-static int read_subcode(void);
-static void sony_get_toc(void);
-static int scd_spinup(void);
-/*static int scd_open(struct inode *inode, struct file *filp);*/
-static int scd_open(struct cdrom_device_info *, int);
-static void do_sony_cd_cmd(unsigned char cmd,
- unsigned char *params,
- unsigned int num_params,
- unsigned char *result_buffer,
- unsigned int *result_size);
-static void size_to_buf(unsigned int size, unsigned char *buf);
-
-/* Parameters for the read-ahead. */
-static unsigned int sony_next_block; /* Next 512 byte block offset */
-static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
- in the current read command. */
-
-
-/* The base I/O address of the Sony Interface. This is a variable (not a
- #define) so it can be easily changed via some future ioctl() */
-static unsigned int cdu31a_port = 0;
-module_param(cdu31a_port, uint, 0);
-
-/*
- * The following are I/O addresses of the various registers for the drive. The
- * comment for the base address also applies here.
- */
-static volatile unsigned short sony_cd_cmd_reg;
-static volatile unsigned short sony_cd_param_reg;
-static volatile unsigned short sony_cd_write_reg;
-static volatile unsigned short sony_cd_control_reg;
-static volatile unsigned short sony_cd_status_reg;
-static volatile unsigned short sony_cd_result_reg;
-static volatile unsigned short sony_cd_read_reg;
-static volatile unsigned short sony_cd_fifost_reg;
-
-static struct request_queue *cdu31a_queue;
-static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */
-
-static int sony_spun_up = 0; /* Has the drive been spun up? */
-
-static int sony_speed = 0; /* Last wanted speed */
-
-static int sony_xa_mode = 0; /* Is an XA disk in the drive
- and the drive a CDU31A? */
-
-static int sony_raw_data_mode = 1; /* 1 if data tracks, 0 if audio.
- For raw data reads. */
-
-static unsigned int sony_usage = 0; /* How many processes have the
- drive open. */
-
-static int sony_pas_init = 0; /* Initialize the Pro-Audio
- Spectrum card? */
-
-static struct s_sony_session_toc single_toc; /* Holds the
- table of
- contents. */
-
-static struct s_all_sessions_toc sony_toc; /* entries gathered from all
- sessions */
-
-static int sony_toc_read = 0; /* Has the TOC been read for
- the drive? */
-
-static struct s_sony_subcode last_sony_subcode; /* Points to the last
- subcode address read */
-
-static DECLARE_MUTEX(sony_sem); /* Semaphore for drive hardware access */
-
-static int is_double_speed = 0; /* does the drive support double speed ? */
-
-static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */
-
-/*
- * The audio status uses the values from read subchannel data as specified
- * in include/linux/cdrom.h.
- */
-static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
-
-/*
- * The following are a hack for pausing and resuming audio play. The drive
- * does not work as I would expect it, if you stop it then start it again,
- * the drive seeks back to the beginning and starts over. This holds the
- * position during a pause so a resume can restart it. It uses the
- * audio status variable above to tell if it is paused.
- */
-static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
-static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
-
-/* What IRQ is the drive using? 0 if none. */
-static int cdu31a_irq = 0;
-module_param(cdu31a_irq, int, 0);
-
-/* The interrupt handler will wake this queue up when it gets an
- interrupts. */
-static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
-static int irq_flag = 0;
-
-static int curr_control_reg = 0; /* Current value of the control register */
-
-/* A disk changed variable. When a disk change is detected, it will
- all be set to TRUE. As the upper layers ask for disk_changed status
- it will be cleared. */
-static char disk_changed;
-
-/* This was readahead_buffer once... Now it's used only for audio reads */
-static char audio_buffer[CD_FRAMESIZE_RAW];
-
-/* Used to time a short period to abort an operation after the
- drive has been idle for a while. This keeps the light on
- the drive from flashing for very long. */
-static struct timer_list cdu31a_abort_timer;
-
-/* Marks if the timeout has started an abort read. This is used
- on entry to the drive to tell the code to read out the status
- from the abort read. */
-static int abort_read_started = 0;
-
-/*
- * Uniform cdrom interface function
- * report back, if disc has changed from time of last request.
- */
-static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
- int retval;
-
- retval = disk_changed;
- disk_changed = 0;
-
- return retval;
-}
-
-/*
- * Uniform cdrom interface function
- * report back, if drive is ready
- */
-static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
- if (CDSL_CURRENT != slot_nr)
- /* we have no changer support */
- return -EINVAL;
- if (sony_spun_up)
- return CDS_DISC_OK;
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- if (scd_spinup() == 0)
- sony_spun_up = 1;
- up(&sony_sem);
- return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
-}
-
-static inline void enable_interrupts(void)
-{
- curr_control_reg |= (SONY_ATTN_INT_EN_BIT
- | SONY_RES_RDY_INT_EN_BIT
- | SONY_DATA_RDY_INT_EN_BIT);
- outb(curr_control_reg, sony_cd_control_reg);
-}
-
-static inline void disable_interrupts(void)
-{
- curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
- | SONY_RES_RDY_INT_EN_BIT
- | SONY_DATA_RDY_INT_EN_BIT);
- outb(curr_control_reg, sony_cd_control_reg);
-}
-
-/*
- * Wait a little while (used for polling the drive). If in initialization,
- * setting a timeout doesn't work, so just loop for a while.
- */
-static inline void sony_sleep(void)
-{
- if (cdu31a_irq <= 0) {
- yield();
- } else { /* Interrupt driven */
- DEFINE_WAIT(w);
- int first = 1;
-
- while (1) {
- prepare_to_wait(&cdu31a_irq_wait, &w,
- TASK_INTERRUPTIBLE);
- if (first) {
- enable_interrupts();
- first = 0;
- }
-
- if (irq_flag != 0)
- break;
- if (!signal_pending(current)) {
- schedule();
- continue;
- } else
- disable_interrupts();
- break;
- }
- finish_wait(&cdu31a_irq_wait, &w);
- irq_flag = 0;
- }
-}
-
-
-/*
- * The following are convenience routine to read various status and set
- * various conditions in the drive.
- */
-static inline int is_attention(void)
-{
- return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0;
-}
-
-static inline int is_busy(void)
-{
- return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0;
-}
-
-static inline int is_data_ready(void)
-{
- return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0;
-}
-
-static inline int is_data_requested(void)
-{
- return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0;
-}
-
-static inline int is_result_ready(void)
-{
- return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0;
-}
-
-static inline int is_param_write_rdy(void)
-{
- return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0;
-}
-
-static inline int is_result_reg_not_empty(void)
-{
- return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0;
-}
-
-static inline void reset_drive(void)
-{
- curr_control_reg = 0;
- sony_toc_read = 0;
- outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
-}
-
-/*
- * Uniform cdrom interface function
- * reset drive and return when it is ready
- */
-static int scd_reset(struct cdrom_device_info *cdi)
-{
- unsigned long retry_count;
-
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- reset_drive();
-
- retry_count = jiffies + SONY_RESET_TIMEOUT;
- while (time_before(jiffies, retry_count) && (!is_attention())) {
- sony_sleep();
- }
-
- up(&sony_sem);
- return 0;
-}
-
-static inline void clear_attention(void)
-{
- outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline void clear_result_ready(void)
-{
- outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline void clear_data_ready(void)
-{
- outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
- sony_cd_control_reg);
-}
-
-static inline void clear_param_reg(void)
-{
- outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline unsigned char read_status_register(void)
-{
- return inb(sony_cd_status_reg);
-}
-
-static inline unsigned char read_result_register(void)
-{
- return inb(sony_cd_result_reg);
-}
-
-static inline unsigned char read_data_register(void)
-{
- return inb(sony_cd_read_reg);
-}
-
-static inline void write_param(unsigned char param)
-{
- outb(param, sony_cd_param_reg);
-}
-
-static inline void write_cmd(unsigned char cmd)
-{
- outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
- sony_cd_control_reg);
- outb(cmd, sony_cd_cmd_reg);
-}
-
-static irqreturn_t cdu31a_interrupt(int irq, void *dev_id)
-{
- unsigned char val;
-
- if (abort_read_started) {
- /* We might be waiting for an abort to finish. Don't
- disable interrupts yet, though, because we handle
- this one here. */
- /* Clear out the result registers. */
- while (is_result_reg_not_empty()) {
- val = read_result_register();
- }
- clear_data_ready();
- clear_result_ready();
-
- /* Clear out the data */
- while (is_data_requested()) {
- val = read_data_register();
- }
- abort_read_started = 0;
-
- /* If something was waiting, wake it up now. */
- if (waitqueue_active(&cdu31a_irq_wait)) {
- disable_interrupts();
- irq_flag = 1;
- wake_up_interruptible(&cdu31a_irq_wait);
- }
- } else if (waitqueue_active(&cdu31a_irq_wait)) {
- disable_interrupts();
- irq_flag = 1;
- wake_up_interruptible(&cdu31a_irq_wait);
- } else {
- disable_interrupts();
- printk(KERN_NOTICE PFX
- "Got an interrupt but nothing was waiting\n");
- }
- return IRQ_HANDLED;
-}
-
-/*
- * give more verbose error messages
- */
-static unsigned char *translate_error(unsigned char err_code)
-{
- static unsigned char errbuf[80];
-
- switch (err_code) {
- case 0x10: return "illegal command ";
- case 0x11: return "illegal parameter ";
-
- case 0x20: return "not loaded ";
- case 0x21: return "no disc ";
- case 0x22: return "not spinning ";
- case 0x23: return "spinning ";
- case 0x25: return "spindle servo ";
- case 0x26: return "focus servo ";
- case 0x29: return "eject mechanism ";
- case 0x2a: return "audio playing ";
- case 0x2c: return "emergency eject ";
-
- case 0x30: return "focus ";
- case 0x31: return "frame sync ";
- case 0x32: return "subcode address ";
- case 0x33: return "block sync ";
- case 0x34: return "header address ";
-
- case 0x40: return "illegal track read ";
- case 0x41: return "mode 0 read ";
- case 0x42: return "illegal mode read ";
- case 0x43: return "illegal block size read ";
- case 0x44: return "mode read ";
- case 0x45: return "form read ";
- case 0x46: return "leadout read ";
- case 0x47: return "buffer overrun ";
-
- case 0x53: return "unrecoverable CIRC ";
- case 0x57: return "unrecoverable LECC ";
-
- case 0x60: return "no TOC ";
- case 0x61: return "invalid subcode data ";
- case 0x63: return "focus on TOC read ";
- case 0x64: return "frame sync on TOC read ";
- case 0x65: return "TOC data ";
-
- case 0x70: return "hardware failure ";
- case 0x91: return "leadin ";
- case 0x92: return "leadout ";
- case 0x93: return "data track ";
- }
- sprintf(errbuf, "unknown 0x%02x ", err_code);
- return errbuf;
-}
-
-/*
- * Set the drive parameters so the drive will auto-spin-up when a
- * disk is inserted.
- */
-static void set_drive_params(int want_doublespeed)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned char params[3];
-
-
- params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
- params[1] = 0x00; /* Never spin down the drive. */
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params, 2, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_NOTICE PFX
- "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
- }
-
- params[0] = SONY_SD_MECH_CONTROL;
- params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
-
- if (is_auto_eject)
- params[1] |= SONY_AUTO_EJECT_BIT;
-
- if (is_double_speed && want_doublespeed) {
- params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if
- possible */
- }
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params, 2, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_NOTICE PFX "Unable to set mechanical "
- "parameters: 0x%2.2x\n", res_reg[1]);
- }
-}
-
-/*
- * Uniform cdrom interface function
- * select reading speed for data access
- */
-static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
-{
- if (speed == 0)
- sony_speed = 1;
- else
- sony_speed = speed - 1;
-
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- set_drive_params(sony_speed);
- up(&sony_sem);
- return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * lock or unlock eject button
- */
-static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
-{
- if (lock == 0) {
- is_auto_eject = 1;
- } else {
- is_auto_eject = 0;
- }
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- set_drive_params(sony_speed);
- up(&sony_sem);
- return 0;
-}
-
-/*
- * This code will reset the drive and attempt to restore sane parameters.
- */
-static void restart_on_error(void)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned long retry_count;
-
-
- printk(KERN_NOTICE PFX "Resetting drive on error\n");
- reset_drive();
- retry_count = jiffies + SONY_RESET_TIMEOUT;
- while (time_before(jiffies, retry_count) && (!is_attention())) {
- sony_sleep();
- }
- set_drive_params(sony_speed);
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n",
- res_reg[1]);
- }
-
- msleep(2000);
-
- sony_get_toc();
-}
-
-/*
- * This routine writes data to the parameter register. Since this should
- * happen fairly fast, it is polled with no OS waits between.
- */
-static int write_params(unsigned char *params, int num_params)
-{
- unsigned int retry_count;
-
-
- retry_count = SONY_READY_RETRIES;
- while ((retry_count > 0) && (!is_param_write_rdy())) {
- retry_count--;
- }
- if (!is_param_write_rdy()) {
- return -EIO;
- }
-
- while (num_params > 0) {
- write_param(*params);
- params++;
- num_params--;
- }
-
- return 0;
-}
-
-
-/*
- * The following reads data from the command result register. It is a
- * fairly complex routine, all status info flows back through this
- * interface. The algorithm is stolen directly from the flowcharts in
- * the drive manual.
- */
-static void
-get_result(unsigned char *result_buffer, unsigned int *result_size)
-{
- unsigned char a, b;
- int i;
- unsigned long retry_count;
-
-
- while (handle_sony_cd_attention());
- /* Wait for the result data to be ready */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count)
- && (is_busy() || (!(is_result_ready())))) {
- sony_sleep();
-
- while (handle_sony_cd_attention());
- }
- if (is_busy() || (!(is_result_ready()))) {
- pr_debug(PFX "timeout out %d\n", __LINE__);
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- return;
- }
-
- /*
- * Get the first two bytes. This determines what else needs
- * to be done.
- */
- clear_result_ready();
- a = read_result_register();
- *result_buffer = a;
- result_buffer++;
-
- /* Check for block error status result. */
- if ((a & 0xf0) == 0x50) {
- *result_size = 1;
- return;
- }
-
- b = read_result_register();
- *result_buffer = b;
- result_buffer++;
- *result_size = 2;
-
- /*
- * 0x20 means an error occurred. Byte 2 will have the error code.
- * Otherwise, the command succeeded, byte 2 will have the count of
- * how many more status bytes are coming.
- *
- * The result register can be read 10 bytes at a time, a wait for
- * result ready to be asserted must be done between every 10 bytes.
- */
- if ((a & 0xf0) != 0x20) {
- if (b > 8) {
- for (i = 0; i < 8; i++) {
- *result_buffer = read_result_register();
- result_buffer++;
- (*result_size)++;
- }
- b = b - 8;
-
- while (b > 10) {
- retry_count = SONY_READY_RETRIES;
- while ((retry_count > 0)
- && (!is_result_ready())) {
- retry_count--;
- }
- if (!is_result_ready()) {
- pr_debug(PFX "timeout out %d\n",
- __LINE__);
- result_buffer[0] = 0x20;
- result_buffer[1] =
- SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- return;
- }
-
- clear_result_ready();
-
- for (i = 0; i < 10; i++) {
- *result_buffer =
- read_result_register();
- result_buffer++;
- (*result_size)++;
- }
- b = b - 10;
- }
-
- if (b > 0) {
- retry_count = SONY_READY_RETRIES;
- while ((retry_count > 0)
- && (!is_result_ready())) {
- retry_count--;
- }
- if (!is_result_ready()) {
- pr_debug(PFX "timeout out %d\n",
- __LINE__);
- result_buffer[0] = 0x20;
- result_buffer[1] =
- SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- return;
- }
- }
- }
-
- while (b > 0) {
- *result_buffer = read_result_register();
- result_buffer++;
- (*result_size)++;
- b--;
- }
- }
-}
-
-/*
- * Do a command that does not involve data transfer. This routine must
- * be re-entrant from the same task to support being called from the
- * data operation code when an error occurs.
- */
-static void
-do_sony_cd_cmd(unsigned char cmd,
- unsigned char *params,
- unsigned int num_params,
- unsigned char *result_buffer, unsigned int *result_size)
-{
- unsigned long retry_count;
- int num_retries = 0;
-
-retry_cd_operation:
-
- while (handle_sony_cd_attention());
-
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && (is_busy())) {
- sony_sleep();
-
- while (handle_sony_cd_attention());
- }
- if (is_busy()) {
- pr_debug(PFX "timeout out %d\n", __LINE__);
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- } else {
- clear_result_ready();
- clear_param_reg();
-
- write_params(params, num_params);
- write_cmd(cmd);
-
- get_result(result_buffer, result_size);
- }
-
- if (((result_buffer[0] & 0xf0) == 0x20)
- && (num_retries < MAX_CDU31A_RETRIES)) {
- num_retries++;
- msleep(100);
- goto retry_cd_operation;
- }
-}
-
-
-/*
- * Handle an attention from the drive. This will return 1 if it found one
- * or 0 if not (if one is found, the caller might want to call again).
- *
- * This routine counts the number of consecutive times it is called
- * (since this is always called from a while loop until it returns
- * a 0), and returns a 0 if it happens too many times. This will help
- * prevent a lockup.
- */
-static int handle_sony_cd_attention(void)
-{
- unsigned char atten_code;
- static int num_consecutive_attentions = 0;
- volatile int val;
-
-
-#if 0
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
-#endif
- if (is_attention()) {
- if (num_consecutive_attentions >
- CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
- printk(KERN_NOTICE PFX "Too many consecutive "
- "attentions: %d\n", num_consecutive_attentions);
- num_consecutive_attentions = 0;
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__,
- __LINE__);
- return 0;
- }
-
- clear_attention();
- atten_code = read_result_register();
-
- switch (atten_code) {
- /* Someone changed the CD. Mark it as changed */
- case SONY_MECH_LOADED_ATTN:
- disk_changed = 1;
- sony_toc_read = 0;
- sony_audio_status = CDROM_AUDIO_NO_STATUS;
- sony_blocks_left = 0;
- break;
-
- case SONY_SPIN_DOWN_COMPLETE_ATTN:
- /* Mark the disk as spun down. */
- sony_spun_up = 0;
- break;
-
- case SONY_AUDIO_PLAY_DONE_ATTN:
- sony_audio_status = CDROM_AUDIO_COMPLETED;
- read_subcode();
- break;
-
- case SONY_EJECT_PUSHED_ATTN:
- if (is_auto_eject) {
- sony_audio_status = CDROM_AUDIO_INVALID;
- }
- break;
-
- case SONY_LEAD_IN_ERR_ATTN:
- case SONY_LEAD_OUT_ERR_ATTN:
- case SONY_DATA_TRACK_ERR_ATTN:
- case SONY_AUDIO_PLAYBACK_ERR_ATTN:
- sony_audio_status = CDROM_AUDIO_ERROR;
- break;
- }
-
- num_consecutive_attentions++;
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
- return 1;
- } else if (abort_read_started) {
- while (is_result_reg_not_empty()) {
- val = read_result_register();
- }
- clear_data_ready();
- clear_result_ready();
- /* Clear out the data */
- while (is_data_requested()) {
- val = read_data_register();
- }
- abort_read_started = 0;
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
- return 1;
- }
-
- num_consecutive_attentions = 0;
-#if 0
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-#endif
- return 0;
-}
-
-
-/* Convert from an integer 0-99 to BCD */
-static inline unsigned int int_to_bcd(unsigned int val)
-{
- int retval;
-
-
- retval = (val / 10) << 4;
- retval = retval | val % 10;
- return retval;
-}
-
-
-/* Convert from BCD to an integer from 0-99 */
-static unsigned int bcd_to_int(unsigned int bcd)
-{
- return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
-}
-
-
-/*
- * Convert a logical sector value (like the OS would want to use for
- * a block device) to an MSF format.
- */
-static void log_to_msf(unsigned int log, unsigned char *msf)
-{
- log = log + LOG_START_OFFSET;
- msf[0] = int_to_bcd(log / 4500);
- log = log % 4500;
- msf[1] = int_to_bcd(log / 75);
- msf[2] = int_to_bcd(log % 75);
-}
-
-
-/*
- * Convert an MSF format to a logical sector.
- */
-static unsigned int msf_to_log(unsigned char *msf)
-{
- unsigned int log;
-
-
- log = msf[2];
- log += msf[1] * 75;
- log += msf[0] * 4500;
- log = log - LOG_START_OFFSET;
-
- return log;
-}
-
-
-/*
- * Take in integer size value and put it into a buffer like
- * the drive would want to see a number-of-sector value.
- */
-static void size_to_buf(unsigned int size, unsigned char *buf)
-{
- buf[0] = size / 65536;
- size = size % 65536;
- buf[1] = size / 256;
- buf[2] = size % 256;
-}
-
-/* Starts a read operation. Returns 0 on success and 1 on failure.
- The read operation used here allows multiple sequential sectors
- to be read and status returned for each sector. The driver will
- read the output one at a time as the requests come and abort the
- operation if the requested sector is not the next one from the
- drive. */
-static int
-start_request(unsigned int sector, unsigned int nsect)
-{
- unsigned char params[6];
- unsigned long retry_count;
-
-
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
- log_to_msf(sector, params);
- size_to_buf(nsect, &params[3]);
-
- /*
- * Clear any outstanding attentions and wait for the drive to
- * complete any pending operations.
- */
- while (handle_sony_cd_attention());
-
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && (is_busy())) {
- sony_sleep();
-
- while (handle_sony_cd_attention());
- }
-
- if (is_busy()) {
- printk(KERN_NOTICE PFX "Timeout while waiting "
- "to issue command\n");
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
- return 1;
- } else {
- /* Issue the command */
- clear_result_ready();
- clear_param_reg();
-
- write_params(params, 6);
- write_cmd(SONY_READ_BLKERR_STAT_CMD);
-
- sony_blocks_left = nsect * 4;
- sony_next_block = sector * 4;
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
- return 0;
- }
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-/* Abort a pending read operation. Clear all the drive status variables. */
-static void abort_read(void)
-{
- unsigned char result_reg[2];
- int result_size;
- volatile int val;
-
-
- do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
- if ((result_reg[0] & 0xf0) == 0x20) {
- printk(KERN_ERR PFX "Aborting read, %s error\n",
- translate_error(result_reg[1]));
- }
-
- while (is_result_reg_not_empty()) {
- val = read_result_register();
- }
- clear_data_ready();
- clear_result_ready();
- /* Clear out the data */
- while (is_data_requested()) {
- val = read_data_register();
- }
-
- sony_blocks_left = 0;
-}
-
-/* Called when the timer times out. This will abort the
- pending read operation. */
-static void handle_abort_timeout(unsigned long data)
-{
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
- /* If it is in use, ignore it. */
- if (down_trylock(&sony_sem) == 0) {
- /* We can't use abort_read(), because it will sleep
- or schedule in the timer interrupt. Just start
- the operation, finish it on the next access to
- the drive. */
- clear_result_ready();
- clear_param_reg();
- write_cmd(SONY_ABORT_CMD);
-
- sony_blocks_left = 0;
- abort_read_started = 1;
- up(&sony_sem);
- }
- pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-/* Actually get one sector of data from the drive. */
-static void
-input_data_sector(char *buffer)
-{
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
- /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
- the disk. The real data is after that. We can use audio_buffer. */
- if (sony_xa_mode)
- insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD);
-
- clear_data_ready();
-
- insb(sony_cd_read_reg, buffer, 2048);
-
- /* If an XA disk, we have to clear out the rest of the unused
- error correction data. We can use audio_buffer for that. */
- if (sony_xa_mode)
- insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL);
-
- pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-/* read data from the drive. Note the nsect must be <= 4. */
-static void
-read_data_block(char *buffer,
- unsigned int block,
- unsigned int nblocks,
- unsigned char res_reg[], int *res_size)
-{
- unsigned long retry_count;
-
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
- res_reg[0] = 0;
- res_reg[1] = 0;
- *res_size = 0;
-
- /* Wait for the drive to tell us we have something */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && !(is_data_ready())) {
- while (handle_sony_cd_attention());
-
- sony_sleep();
- }
- if (!(is_data_ready())) {
- if (is_result_ready()) {
- get_result(res_reg, res_size);
- if ((res_reg[0] & 0xf0) != 0x20) {
- printk(KERN_NOTICE PFX "Got result that should"
- " have been error: %d\n", res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- abort_read();
- } else {
- pr_debug(PFX "timeout out %d\n", __LINE__);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- }
- } else {
- input_data_sector(buffer);
- sony_blocks_left -= nblocks;
- sony_next_block += nblocks;
-
- /* Wait for the status from the drive. */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count)
- && !(is_result_ready())) {
- while (handle_sony_cd_attention());
-
- sony_sleep();
- }
-
- if (!is_result_ready()) {
- pr_debug(PFX "timeout out %d\n", __LINE__);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- } else {
- get_result(res_reg, res_size);
-
- /* If we got a buffer status, handle that. */
- if ((res_reg[0] & 0xf0) == 0x50) {
-
- if ((res_reg[0] ==
- SONY_NO_CIRC_ERR_BLK_STAT)
- || (res_reg[0] ==
- SONY_NO_LECC_ERR_BLK_STAT)
- || (res_reg[0] ==
- SONY_RECOV_LECC_ERR_BLK_STAT)) {
- /* nothing here */
- } else {
- printk(KERN_ERR PFX "Data block "
- "error: 0x%x\n", res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
-
- /* Final transfer is done for read command, get final result. */
- if (sony_blocks_left == 0) {
- get_result(res_reg, res_size);
- }
- } else if ((res_reg[0] & 0xf0) != 0x20) {
- /* The drive gave me bad status, I don't know what to do.
- Reset the driver and return an error. */
- printk(KERN_ERR PFX "Invalid block "
- "status: 0x%x\n", res_reg[0]);
- restart_on_error();
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- }
- }
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-
-/*
- * The OS calls this to perform a read or write operation to the drive.
- * Write obviously fail. Reads to a read ahead of sony_buffer_size
- * bytes to help speed operations. This especially helps since the OS
- * uses 1024 byte blocks and the drive uses 2048 byte blocks. Since most
- * data access on a CD is done sequentially, this saves a lot of operations.
- */
-static void do_cdu31a_request(request_queue_t * q)
-{
- struct request *req;
- int block, nblock, num_retries;
- unsigned char res_reg[12];
- unsigned int res_size;
-
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
- spin_unlock_irq(q->queue_lock);
- if (down_interruptible(&sony_sem)) {
- spin_lock_irq(q->queue_lock);
- return;
- }
-
- /* Get drive status before doing anything. */
- while (handle_sony_cd_attention());
-
- /* Make sure we have a valid TOC. */
- sony_get_toc();
-
-
- /* Make sure the timer is cancelled. */
- del_timer(&cdu31a_abort_timer);
-
- while (1) {
- /*
- * The beginning here is stolen from the hard disk driver. I hope
- * it's right.
- */
- req = elv_next_request(q);
- if (!req)
- goto end_do_cdu31a_request;
-
- if (!sony_spun_up)
- scd_spinup();
-
- block = req->sector;
- nblock = req->nr_sectors;
- pr_debug(PFX "request at block %d, length %d blocks\n",
- block, nblock);
- if (!sony_toc_read) {
- printk(KERN_NOTICE PFX "TOC not read\n");
- end_request(req, 0);
- continue;
- }
-
- /* WTF??? */
- if (!blk_fs_request(req)) {
- end_request(req, 0);
- continue;
- }
- if (rq_data_dir(req) == WRITE) {
- end_request(req, 0);
- continue;
- }
-
- /*
- * If the block address is invalid or the request goes beyond the end of
- * the media, return an error.
- */
- if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
- printk(KERN_NOTICE PFX "Request past end of media\n");
- end_request(req, 0);
- continue;
- }
-
- if (nblock > 4)
- nblock = 4;
- num_retries = 0;
-
- try_read_again:
- while (handle_sony_cd_attention());
-
- if (!sony_toc_read) {
- printk(KERN_NOTICE PFX "TOC not read\n");
- end_request(req, 0);
- continue;
- }
-
- /* If no data is left to be read from the drive, start the
- next request. */
- if (sony_blocks_left == 0) {
- if (start_request(block / 4, nblock / 4)) {
- end_request(req, 0);
- continue;
- }
- }
- /* If the requested block is not the next one waiting in
- the driver, abort the current operation and start a
- new one. */
- else if (block != sony_next_block) {
- pr_debug(PFX "Read for block %d, expected %d\n",
- block, sony_next_block);
- abort_read();
- if (!sony_toc_read) {
- printk(KERN_NOTICE PFX "TOC not read\n");
- end_request(req, 0);
- continue;
- }
- if (start_request(block / 4, nblock / 4)) {
- printk(KERN_NOTICE PFX "start request failed\n");
- end_request(req, 0);
- continue;
- }
- }
-
- read_data_block(req->buffer, block, nblock, res_reg, &res_size);
-
- if (res_reg[0] != 0x20) {
- if (!end_that_request_first(req, 1, nblock)) {
- spin_lock_irq(q->queue_lock);
- blkdev_dequeue_request(req);
- end_that_request_last(req, 1);
- spin_unlock_irq(q->queue_lock);
- }
- continue;
- }
-
- if (num_retries > MAX_CDU31A_RETRIES) {
- end_request(req, 0);
- continue;
- }
-
- num_retries++;
- if (res_reg[1] == SONY_NOT_SPIN_ERR) {
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
- &res_size);
- } else {
- printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n",
- translate_error(res_reg[1]), block, nblock);
- }
- goto try_read_again;
- }
- end_do_cdu31a_request:
-#if 0
- /* After finished, cancel any pending operations. */
- abort_read();
-#else
- /* Start a timer to time out after a while to disable
- the read. */
- cdu31a_abort_timer.expires = jiffies + 2 * HZ; /* Wait 2 seconds */
- add_timer(&cdu31a_abort_timer);
-#endif
-
- up(&sony_sem);
- spin_lock_irq(q->queue_lock);
- pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-
-/*
- * Read the table of contents from the drive and set up TOC if
- * successful.
- */
-static void sony_get_toc(void)
-{
- unsigned char res_reg[2];
- unsigned int res_size;
- unsigned char parms[1];
- int session;
- int num_spin_ups;
- int totaltracks = 0;
- int mint = 99;
- int maxt = 0;
-
- pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
- num_spin_ups = 0;
- if (!sony_toc_read) {
- respinup_on_gettoc:
- /* Ignore the result, since it might error if spinning already. */
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
- &res_size);
-
- do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
- &res_size);
-
- /* The drive sometimes returns error 0. I don't know why, but ignore
- it. It seems to mean the drive has already done the operation. */
- if ((res_size < 2)
- || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
- /* If the drive is already playing, it's ok. */
- if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
- || (res_reg[1] == 0)) {
- goto gettoc_drive_spinning;
- }
-
- /* If the drive says it is not spun up (even though we just did it!)
- then retry the operation at least a few times. */
- if ((res_reg[1] == SONY_NOT_SPIN_ERR)
- && (num_spin_ups < MAX_CDU31A_RETRIES)) {
- num_spin_ups++;
- goto respinup_on_gettoc;
- }
-
- printk("cdu31a: Error reading TOC: %x %s\n",
- res_reg[0], translate_error(res_reg[1]));
- return;
- }
-
- gettoc_drive_spinning:
-
- /* The idea here is we keep asking for sessions until the command
- fails. Then we know what the last valid session on the disk is.
- No need to check session 0, since session 0 is the same as session
- 1; the command returns different information if you give it 0.
- */
-#if DEBUG
- memset(&sony_toc, 0x0e, sizeof(sony_toc));
- memset(&single_toc, 0x0f, sizeof(single_toc));
-#endif
- session = 1;
- while (1) {
-/* This seems to slow things down enough to make it work. This
- * appears to be a problem in do_sony_cd_cmd. This printk seems
- * to address the symptoms... -Erik */
- pr_debug(PFX "Trying session %d\n", session);
- parms[0] = session;
- do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
- parms, 1, res_reg, &res_size);
-
- pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]);
-
- if ((res_size < 2)
- || ((res_reg[0] & 0xf0) == 0x20)) {
- /* An error reading the TOC, this must be past the last session. */
- if (session == 1)
- printk
- ("Yikes! Couldn't read any sessions!");
- break;
- }
- pr_debug(PFX "Reading session %d\n", session);
-
- parms[0] = session;
- do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
- parms,
- 1,
- (unsigned char *) &single_toc,
- &res_size);
- if ((res_size < 2)
- || ((single_toc.exec_status[0] & 0xf0) ==
- 0x20)) {
- printk(KERN_ERR PFX "Error reading "
- "session %d: %x %s\n",
- session, single_toc.exec_status[0],
- translate_error(single_toc.
- exec_status[1]));
- /* An error reading the TOC. Return without sony_toc_read
- set. */
- return;
- }
- pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, "
- "1st trk %d, dsktyp %x, dum0 %x\n",
- single_toc.address0, single_toc.control0,
- single_toc.point0,
- bcd_to_int(single_toc.first_track_num),
- single_toc.disk_type, single_toc.dummy0);
- pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, "
- "lst trk %d, dummy1 %x, dum2 %x\n",
- single_toc.address1, single_toc.control1,
- single_toc.point1,
- bcd_to_int(single_toc.last_track_num),
- single_toc.dummy1, single_toc.dummy2);
- pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x "
- "leadout start min %d, sec %d, frame %d\n",
- single_toc.address2, single_toc.control2,
- single_toc.point2,
- bcd_to_int(single_toc.lead_out_start_msf[0]),
- bcd_to_int(single_toc.lead_out_start_msf[1]),
- bcd_to_int(single_toc.lead_out_start_msf[2]));
- if (res_size > 18 && single_toc.pointb0 > 0xaf)
- pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
- "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
- single_toc.addressb0,
- single_toc.controlb0,
- single_toc.pointb0,
- bcd_to_int(single_toc.
- next_poss_prog_area_msf
- [0]),
- bcd_to_int(single_toc.
- next_poss_prog_area_msf
- [1]),
- bcd_to_int(single_toc.
- next_poss_prog_area_msf
- [2]),
- single_toc.num_mode_5_pointers,
- bcd_to_int(single_toc.
- max_start_outer_leadout_msf
- [0]),
- bcd_to_int(single_toc.
- max_start_outer_leadout_msf
- [1]),
- bcd_to_int(single_toc.
- max_start_outer_leadout_msf
- [2]));
- if (res_size > 27 && single_toc.pointb1 > 0xaf)
- pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
- single_toc.addressb1,
- single_toc.controlb1,
- single_toc.pointb1,
- single_toc.dummyb0_1[0],
- single_toc.dummyb0_1[1],
- single_toc.dummyb0_1[2],
- single_toc.dummyb0_1[3],
- single_toc.num_skip_interval_pointers,
- single_toc.num_skip_track_assignments,
- single_toc.dummyb0_2);
- if (res_size > 36 && single_toc.pointb2 > 0xaf)
- pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressb2,
- single_toc.controlb2,
- single_toc.pointb2,
- single_toc.tracksb2[0],
- single_toc.tracksb2[1],
- single_toc.tracksb2[2],
- single_toc.tracksb2[3],
- single_toc.tracksb2[4],
- single_toc.tracksb2[5],
- single_toc.tracksb2[6]);
- if (res_size > 45 && single_toc.pointb3 > 0xaf)
- pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressb3,
- single_toc.controlb3,
- single_toc.pointb3,
- single_toc.tracksb3[0],
- single_toc.tracksb3[1],
- single_toc.tracksb3[2],
- single_toc.tracksb3[3],
- single_toc.tracksb3[4],
- single_toc.tracksb3[5],
- single_toc.tracksb3[6]);
- if (res_size > 54 && single_toc.pointb4 > 0xaf)
- pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressb4,
- single_toc.controlb4,
- single_toc.pointb4,
- single_toc.tracksb4[0],
- single_toc.tracksb4[1],
- single_toc.tracksb4[2],
- single_toc.tracksb4[3],
- single_toc.tracksb4[4],
- single_toc.tracksb4[5],
- single_toc.tracksb4[6]);
- if (res_size > 63 && single_toc.pointc0 > 0xaf)
- pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressc0,
- single_toc.controlc0,
- single_toc.pointc0,
- single_toc.dummyc0[0],
- single_toc.dummyc0[1],
- single_toc.dummyc0[2],
- single_toc.dummyc0[3],
- single_toc.dummyc0[4],
- single_toc.dummyc0[5],
- single_toc.dummyc0[6]);
-#undef DEBUG
-#define DEBUG 0
-
- sony_toc.lead_out_start_msf[0] =
- bcd_to_int(single_toc.lead_out_start_msf[0]);
- sony_toc.lead_out_start_msf[1] =
- bcd_to_int(single_toc.lead_out_start_msf[1]);
- sony_toc.lead_out_start_msf[2] =
- bcd_to_int(single_toc.lead_out_start_msf[2]);
- sony_toc.lead_out_start_lba =
- single_toc.lead_out_start_lba =
- msf_to_log(sony_toc.lead_out_start_msf);
-
- /* For points that do not exist, move the data over them
- to the right location. */
- if (single_toc.pointb0 != 0xb0) {
- memmove(((char *) &single_toc) + 27,
- ((char *) &single_toc) + 18,
- res_size - 18);
- res_size += 9;
- } else if (res_size > 18) {
- sony_toc.lead_out_start_msf[0] =
- bcd_to_int(single_toc.
- max_start_outer_leadout_msf
- [0]);
- sony_toc.lead_out_start_msf[1] =
- bcd_to_int(single_toc.
- max_start_outer_leadout_msf
- [1]);
- sony_toc.lead_out_start_msf[2] =
- bcd_to_int(single_toc.
- max_start_outer_leadout_msf
- [2]);
- sony_toc.lead_out_start_lba =
- msf_to_log(sony_toc.
- lead_out_start_msf);
- }
- if (single_toc.pointb1 != 0xb1) {
- memmove(((char *) &single_toc) + 36,
- ((char *) &single_toc) + 27,
- res_size - 27);
- res_size += 9;
- }
- if (single_toc.pointb2 != 0xb2) {
- memmove(((char *) &single_toc) + 45,
- ((char *) &single_toc) + 36,
- res_size - 36);
- res_size += 9;
- }
- if (single_toc.pointb3 != 0xb3) {
- memmove(((char *) &single_toc) + 54,
- ((char *) &single_toc) + 45,
- res_size - 45);
- res_size += 9;
- }
- if (single_toc.pointb4 != 0xb4) {
- memmove(((char *) &single_toc) + 63,
- ((char *) &single_toc) + 54,
- res_size - 54);
- res_size += 9;
- }
- if (single_toc.pointc0 != 0xc0) {
- memmove(((char *) &single_toc) + 72,
- ((char *) &single_toc) + 63,
- res_size - 63);
- res_size += 9;
- }
-#if DEBUG
- printk(PRINT_INFO PFX "start track lba %u, "
- "leadout start lba %u\n",
- single_toc.start_track_lba,
- single_toc.lead_out_start_lba);
- {
- int i;
- for (i = 0;
- i <
- 1 +
- bcd_to_int(single_toc.last_track_num)
- -
- bcd_to_int(single_toc.
- first_track_num); i++) {
- printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n",
- i,
- single_toc.tracks[i].address,
- single_toc.tracks[i].control,
- bcd_to_int(single_toc.
- tracks[i].track),
- bcd_to_int(single_toc.
- tracks[i].
- track_start_msf
- [0]),
- bcd_to_int(single_toc.
- tracks[i].
- track_start_msf
- [1]),
- bcd_to_int(single_toc.
- tracks[i].
- track_start_msf
- [2]));
- if (mint >
- bcd_to_int(single_toc.
- tracks[i].track))
- mint =
- bcd_to_int(single_toc.
- tracks[i].
- track);
- if (maxt <
- bcd_to_int(single_toc.
- tracks[i].track))
- maxt =
- bcd_to_int(single_toc.
- tracks[i].
- track);
- }
- printk(KERN_INFO PFX "min track number %d, "
- "max track number %d\n",
- mint, maxt);
- }
-#endif
-
- /* prepare a special table of contents for a CD-I disc. They don't have one. */
- if (single_toc.disk_type == 0x10 &&
- single_toc.first_track_num == 2 &&
- single_toc.last_track_num == 2 /* CD-I */ ) {
- sony_toc.tracks[totaltracks].address = 1;
- sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
- sony_toc.tracks[totaltracks].track = 1;
- sony_toc.tracks[totaltracks].
- track_start_msf[0] = 0;
- sony_toc.tracks[totaltracks].
- track_start_msf[1] = 2;
- sony_toc.tracks[totaltracks].
- track_start_msf[2] = 0;
- mint = maxt = 1;
- totaltracks++;
- } else
- /* gather track entries from this session */
- {
- int i;
- for (i = 0;
- i <
- 1 +
- bcd_to_int(single_toc.last_track_num)
- -
- bcd_to_int(single_toc.
- first_track_num);
- i++, totaltracks++) {
- sony_toc.tracks[totaltracks].
- address =
- single_toc.tracks[i].address;
- sony_toc.tracks[totaltracks].
- control =
- single_toc.tracks[i].control;
- sony_toc.tracks[totaltracks].
- track =
- bcd_to_int(single_toc.
- tracks[i].track);
- sony_toc.tracks[totaltracks].
- track_start_msf[0] =
- bcd_to_int(single_toc.
- tracks[i].
- track_start_msf[0]);
- sony_toc.tracks[totaltracks].
- track_start_msf[1] =
- bcd_to_int(single_toc.
- tracks[i].
- track_start_msf[1]);
- sony_toc.tracks[totaltracks].
- track_start_msf[2] =
- bcd_to_int(single_toc.
- tracks[i].
- track_start_msf[2]);
- if (i == 0)
- single_toc.
- start_track_lba =
- msf_to_log(sony_toc.
- tracks
- [totaltracks].
- track_start_msf);
- if (mint >
- sony_toc.tracks[totaltracks].
- track)
- mint =
- sony_toc.
- tracks[totaltracks].
- track;
- if (maxt <
- sony_toc.tracks[totaltracks].
- track)
- maxt =
- sony_toc.
- tracks[totaltracks].
- track;
- }
- }
- sony_toc.first_track_num = mint;
- sony_toc.last_track_num = maxt;
- /* Disk type of last session wins. For example:
- CD-Extra has disk type 0 for the first session, so
- a dumb HiFi CD player thinks it is a plain audio CD.
- We are interested in the disk type of the last session,
- which is 0x20 (XA) for CD-Extra, so we can access the
- data track ... */
- sony_toc.disk_type = single_toc.disk_type;
- sony_toc.sessions = session;
-
- /* don't believe everything :-) */
- if (session == 1)
- single_toc.start_track_lba = 0;
- sony_toc.start_track_lba =
- single_toc.start_track_lba;
-
- if (session > 1 && single_toc.pointb0 == 0xb0 &&
- sony_toc.lead_out_start_lba ==
- single_toc.lead_out_start_lba) {
- break;
- }
-
- /* Let's not get carried away... */
- if (session > 40) {
- printk(KERN_NOTICE PFX "too many sessions: "
- "%d\n", session);
- break;
- }
- session++;
- }
- sony_toc.track_entries = totaltracks;
- /* add one entry for the LAST track with track number CDROM_LEADOUT */
- sony_toc.tracks[totaltracks].address = single_toc.address2;
- sony_toc.tracks[totaltracks].control = single_toc.control2;
- sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
- sony_toc.tracks[totaltracks].track_start_msf[0] =
- sony_toc.lead_out_start_msf[0];
- sony_toc.tracks[totaltracks].track_start_msf[1] =
- sony_toc.lead_out_start_msf[1];
- sony_toc.tracks[totaltracks].track_start_msf[2] =
- sony_toc.lead_out_start_msf[2];
-
- sony_toc_read = 1;
-
- pr_debug(PFX "Disk session %d, start track: %d, "
- "stop track: %d\n",
- session, single_toc.start_track_lba,
- single_toc.lead_out_start_lba);
- }
- pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-
-/*
- * Uniform cdrom interface function
- * return multisession offset and sector information
- */
-static int scd_get_last_session(struct cdrom_device_info *cdi,
- struct cdrom_multisession *ms_info)
-{
- if (ms_info == NULL)
- return 1;
-
- if (!sony_toc_read) {
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- sony_get_toc();
- up(&sony_sem);
- }
-
- ms_info->addr_format = CDROM_LBA;
- ms_info->addr.lba = sony_toc.start_track_lba;
- ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
- sony_toc.disk_type == 0x10 /* CDI */ ;
-
- return 0;
-}
-
-/*
- * Search for a specific track in the table of contents.
- */
-static int find_track(int track)
-{
- int i;
-
- for (i = 0; i <= sony_toc.track_entries; i++) {
- if (sony_toc.tracks[i].track == track) {
- return i;
- }
- }
-
- return -1;
-}
-
-
-/*
- * Read the subcode and put it in last_sony_subcode for future use.
- */
-static int read_subcode(void)
-{
- unsigned int res_size;
-
-
- do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
- NULL,
- 0, (unsigned char *) &last_sony_subcode, &res_size);
- if ((res_size < 2)
- || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
- printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n",
- translate_error(last_sony_subcode.exec_status[1]));
- return -EIO;
- }
-
- last_sony_subcode.track_num =
- bcd_to_int(last_sony_subcode.track_num);
- last_sony_subcode.index_num =
- bcd_to_int(last_sony_subcode.index_num);
- last_sony_subcode.abs_msf[0] =
- bcd_to_int(last_sony_subcode.abs_msf[0]);
- last_sony_subcode.abs_msf[1] =
- bcd_to_int(last_sony_subcode.abs_msf[1]);
- last_sony_subcode.abs_msf[2] =
- bcd_to_int(last_sony_subcode.abs_msf[2]);
-
- last_sony_subcode.rel_msf[0] =
- bcd_to_int(last_sony_subcode.rel_msf[0]);
- last_sony_subcode.rel_msf[1] =
- bcd_to_int(last_sony_subcode.rel_msf[1]);
- last_sony_subcode.rel_msf[2] =
- bcd_to_int(last_sony_subcode.rel_msf[2]);
- return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * return the media catalog number found on some older audio cds
- */
-static int
-scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
- unsigned char resbuffer[2 + 14];
- unsigned char *mcnp = mcn->medium_catalog_number;
- unsigned char *resp = resbuffer + 3;
- unsigned int res_size;
-
- memset(mcn->medium_catalog_number, 0, 14);
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
- NULL, 0, resbuffer, &res_size);
- up(&sony_sem);
- if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
- else {
- /* packed bcd to single ASCII digits */
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- }
- *mcnp = '\0';
- return 0;
-}
-
-
-/*
- * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If
- * the drive is playing, the subchannel needs to be read (since it would be
- * changing). If the drive is paused or completed, the subcode information has
- * already been stored, just use that. The ioctl call wants things in decimal
- * (not BCD), so all the conversions are done.
- */
-static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
-{
- /* Get attention stuff */
- while (handle_sony_cd_attention());
-
- sony_get_toc();
- if (!sony_toc_read) {
- return -EIO;
- }
-
- switch (sony_audio_status) {
- case CDROM_AUDIO_NO_STATUS:
- case CDROM_AUDIO_PLAY:
- if (read_subcode() < 0) {
- return -EIO;
- }
- break;
-
- case CDROM_AUDIO_PAUSED:
- case CDROM_AUDIO_COMPLETED:
- break;
-
-#if 0
- case CDROM_AUDIO_NO_STATUS:
- schi->cdsc_audiostatus = sony_audio_status;
- return 0;
- break;
-#endif
- case CDROM_AUDIO_INVALID:
- case CDROM_AUDIO_ERROR:
- default:
- return -EIO;
- }
-
- schi->cdsc_audiostatus = sony_audio_status;
- schi->cdsc_adr = last_sony_subcode.address;
- schi->cdsc_ctrl = last_sony_subcode.control;
- schi->cdsc_trk = last_sony_subcode.track_num;
- schi->cdsc_ind = last_sony_subcode.index_num;
- if (schi->cdsc_format == CDROM_MSF) {
- schi->cdsc_absaddr.msf.minute =
- last_sony_subcode.abs_msf[0];
- schi->cdsc_absaddr.msf.second =
- last_sony_subcode.abs_msf[1];
- schi->cdsc_absaddr.msf.frame =
- last_sony_subcode.abs_msf[2];
-
- schi->cdsc_reladdr.msf.minute =
- last_sony_subcode.rel_msf[0];
- schi->cdsc_reladdr.msf.second =
- last_sony_subcode.rel_msf[1];
- schi->cdsc_reladdr.msf.frame =
- last_sony_subcode.rel_msf[2];
- } else if (schi->cdsc_format == CDROM_LBA) {
- schi->cdsc_absaddr.lba =
- msf_to_log(last_sony_subcode.abs_msf);
- schi->cdsc_reladdr.lba =
- msf_to_log(last_sony_subcode.rel_msf);
- }
-
- return 0;
-}
-
-/* Get audio data from the drive. This is fairly complex because I
- am looking for status and data at the same time, but if I get status
- then I just look for data. I need to get the status immediately so
- the switch from audio to data tracks will happen quickly. */
-static void
-read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
-{
- unsigned long retry_count;
- int result_read;
-
-
- res_reg[0] = 0;
- res_reg[1] = 0;
- *res_size = 0;
- result_read = 0;
-
- /* Wait for the drive to tell us we have something */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- continue_read_audio_wait:
- while (time_before(jiffies, retry_count) && !(is_data_ready())
- && !(is_result_ready() || result_read)) {
- while (handle_sony_cd_attention());
-
- sony_sleep();
- }
- if (!(is_data_ready())) {
- if (is_result_ready() && !result_read) {
- get_result(res_reg, res_size);
-
- /* Read block status and continue waiting for data. */
- if ((res_reg[0] & 0xf0) == 0x50) {
- result_read = 1;
- goto continue_read_audio_wait;
- }
- /* Invalid data from the drive. Shut down the operation. */
- else if ((res_reg[0] & 0xf0) != 0x20) {
- printk(KERN_WARNING PFX "Got result that "
- "should have been error: %d\n",
- res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- abort_read();
- } else {
- pr_debug(PFX "timeout out %d\n", __LINE__);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- }
- } else {
- clear_data_ready();
-
- /* If data block, then get 2340 bytes offset by 12. */
- if (sony_raw_data_mode) {
- insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
- CD_FRAMESIZE_RAW1);
- } else {
- /* Audio gets the whole 2352 bytes. */
- insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
- }
-
- /* If I haven't already gotten the result, get it now. */
- if (!result_read) {
- /* Wait for the drive to tell us we have something */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count)
- && !(is_result_ready())) {
- while (handle_sony_cd_attention());
-
- sony_sleep();
- }
-
- if (!is_result_ready()) {
- pr_debug(PFX "timeout out %d\n", __LINE__);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- return;
- } else {
- get_result(res_reg, res_size);
- }
- }
-
- if ((res_reg[0] & 0xf0) == 0x50) {
- if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
- /* Ok, nothing to do. */
- } else {
- printk(KERN_ERR PFX "Data block error: 0x%x\n",
- res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- } else if ((res_reg[0] & 0xf0) != 0x20) {
- /* The drive gave me bad status, I don't know what to do.
- Reset the driver and return an error. */
- printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n",
- res_reg[0]);
- restart_on_error();
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- }
-}
-
-/* Perform a raw data read. This will automatically detect the
- track type and read the proper data (audio or data). */
-static int read_audio(struct cdrom_read_audio *ra)
-{
- int retval;
- unsigned char params[2];
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned int cframe;
-
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- if (!sony_spun_up)
- scd_spinup();
-
- /* Set the drive to do raw operations. */
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x06 | sony_raw_data_mode;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params, 2, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n",
- res_reg[1]);
- retval = -EIO;
- goto out_up;
- }
-
- /* From here down, we have to goto exit_read_audio instead of returning
- because the drive parameters have to be set back to data before
- return. */
-
- retval = 0;
- if (start_request(ra->addr.lba, ra->nframes)) {
- retval = -EIO;
- goto exit_read_audio;
- }
-
- /* For every requested frame. */
- cframe = 0;
- while (cframe < ra->nframes) {
- read_audio_data(audio_buffer, res_reg, &res_size);
- if ((res_reg[0] & 0xf0) == 0x20) {
- if (res_reg[1] == SONY_BAD_DATA_ERR) {
- printk(KERN_ERR PFX "Data error on audio "
- "sector %d\n",
- ra->addr.lba + cframe);
- } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
- /* Illegal track type, change track types and start over. */
- sony_raw_data_mode =
- (sony_raw_data_mode) ? 0 : 1;
-
- /* Set the drive mode. */
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x06 | sony_raw_data_mode;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2, res_reg, &res_size);
- if ((res_size < 2)
- || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_ERR PFX "Unable to set "
- "decode params: 0x%2.2x\n",
- res_reg[1]);
- retval = -EIO;
- goto exit_read_audio;
- }
-
- /* Restart the request on the current frame. */
- if (start_request
- (ra->addr.lba + cframe,
- ra->nframes - cframe)) {
- retval = -EIO;
- goto exit_read_audio;
- }
-
- /* Don't go back to the top because don't want to get into
- and infinite loop. A lot of code gets duplicated, but
- that's no big deal, I don't guess. */
- read_audio_data(audio_buffer, res_reg,
- &res_size);
- if ((res_reg[0] & 0xf0) == 0x20) {
- if (res_reg[1] ==
- SONY_BAD_DATA_ERR) {
- printk(KERN_ERR PFX "Data error"
- " on audio sector %d\n",
- ra->addr.lba +
- cframe);
- } else {
- printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n",
- ra->addr.lba + cframe,
- translate_error
- (res_reg[1]));
- retval = -EIO;
- goto exit_read_audio;
- }
- } else if (copy_to_user(ra->buf +
- (CD_FRAMESIZE_RAW
- * cframe),
- audio_buffer,
- CD_FRAMESIZE_RAW)) {
- retval = -EFAULT;
- goto exit_read_audio;
- }
- } else {
- printk(KERN_ERR PFX "Error reading audio "
- "data on sector %d: %s\n",
- ra->addr.lba + cframe,
- translate_error(res_reg[1]));
- retval = -EIO;
- goto exit_read_audio;
- }
- } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
- (char *)audio_buffer,
- CD_FRAMESIZE_RAW)) {
- retval = -EFAULT;
- goto exit_read_audio;
- }
-
- cframe++;
- }
-
- get_result(res_reg, &res_size);
- if ((res_reg[0] & 0xf0) == 0x20) {
- printk(KERN_ERR PFX "Error return from audio read: %s\n",
- translate_error(res_reg[1]));
- retval = -EIO;
- goto exit_read_audio;
- }
-
- exit_read_audio:
-
- /* Set the drive mode back to the proper one for the disk. */
- params[0] = SONY_SD_DECODE_PARAM;
- if (!sony_xa_mode) {
- params[1] = 0x0f;
- } else {
- params[1] = 0x07;
- }
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params, 2, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n",
- res_reg[1]);
- retval = -EIO;
- }
-
- out_up:
- up(&sony_sem);
-
- return retval;
-}
-
-static int
-do_sony_cd_cmd_chk(const char *name,
- unsigned char cmd,
- unsigned char *params,
- unsigned int num_params,
- unsigned char *result_buffer, unsigned int *result_size)
-{
- do_sony_cd_cmd(cmd, params, num_params, result_buffer,
- result_size);
- if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
- printk(KERN_ERR PFX "Error %s (CDROM%s)\n",
- translate_error(result_buffer[1]), name);
- return -EIO;
- }
- return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * open the tray
- */
-static int scd_tray_move(struct cdrom_device_info *cdi, int position)
-{
- int retval;
-
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- if (position == 1 /* open tray */ ) {
- unsigned char res_reg[12];
- unsigned int res_size;
-
- do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
- &res_size);
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
- &res_size);
-
- sony_audio_status = CDROM_AUDIO_INVALID;
- retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
- res_reg, &res_size);
- } else {
- if (0 == scd_spinup())
- sony_spun_up = 1;
- retval = 0;
- }
- up(&sony_sem);
- return retval;
-}
-
-/*
- * The big ugly ioctl handler.
- */
-static int scd_audio_ioctl(struct cdrom_device_info *cdi,
- unsigned int cmd, void *arg)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned char params[7];
- int i, retval;
-
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- switch (cmd) {
- case CDROMSTART: /* Spin up the drive */
- retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
- 0, res_reg, &res_size);
- break;
-
- case CDROMSTOP: /* Spin down the drive */
- do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
- &res_size);
-
- /*
- * Spin the drive down, ignoring the error if the disk was
- * already not spinning.
- */
- sony_audio_status = CDROM_AUDIO_NO_STATUS;
- retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
- 0, res_reg, &res_size);
- break;
-
- case CDROMPAUSE: /* Pause the drive */
- if (do_sony_cd_cmd_chk
- ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
- &res_size)) {
- retval = -EIO;
- break;
- }
- /* Get the current position and save it for resuming */
- if (read_subcode() < 0) {
- retval = -EIO;
- break;
- }
- cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
- cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
- cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
- sony_audio_status = CDROM_AUDIO_PAUSED;
- retval = 0;
- break;
-
- case CDROMRESUME: /* Start the drive after being paused */
- if (sony_audio_status != CDROM_AUDIO_PAUSED) {
- retval = -EINVAL;
- break;
- }
-
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
- &res_size);
-
- /* Start the drive at the saved position. */
- params[1] = int_to_bcd(cur_pos_msf[0]);
- params[2] = int_to_bcd(cur_pos_msf[1]);
- params[3] = int_to_bcd(cur_pos_msf[2]);
- params[4] = int_to_bcd(final_pos_msf[0]);
- params[5] = int_to_bcd(final_pos_msf[1]);
- params[6] = int_to_bcd(final_pos_msf[2]);
- params[0] = 0x03;
- if (do_sony_cd_cmd_chk
- ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
- &res_size) < 0) {
- retval = -EIO;
- break;
- }
- sony_audio_status = CDROM_AUDIO_PLAY;
- retval = 0;
- break;
-
- case CDROMPLAYMSF: /* Play starting at the given MSF address. */
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
- &res_size);
-
- /* The parameters are given in int, must be converted */
- for (i = 1; i < 7; i++) {
- params[i] =
- int_to_bcd(((unsigned char *) arg)[i - 1]);
- }
- params[0] = 0x03;
- if (do_sony_cd_cmd_chk
- ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
- res_reg, &res_size) < 0) {
- retval = -EIO;
- break;
- }
-
- /* Save the final position for pauses and resumes */
- final_pos_msf[0] = bcd_to_int(params[4]);
- final_pos_msf[1] = bcd_to_int(params[5]);
- final_pos_msf[2] = bcd_to_int(params[6]);
- sony_audio_status = CDROM_AUDIO_PLAY;
- retval = 0;
- break;
-
- case CDROMREADTOCHDR: /* Read the table of contents header */
- {
- struct cdrom_tochdr *hdr;
-
- sony_get_toc();
- if (!sony_toc_read) {
- retval = -EIO;
- break;
- }
-
- hdr = (struct cdrom_tochdr *) arg;
- hdr->cdth_trk0 = sony_toc.first_track_num;
- hdr->cdth_trk1 = sony_toc.last_track_num;
- }
- retval = 0;
- break;
-
- case CDROMREADTOCENTRY: /* Read a given table of contents entry */
- {
- struct cdrom_tocentry *entry;
- int track_idx;
- unsigned char *msf_val = NULL;
-
- sony_get_toc();
- if (!sony_toc_read) {
- retval = -EIO;
- break;
- }
-
- entry = (struct cdrom_tocentry *) arg;
-
- track_idx = find_track(entry->cdte_track);
- if (track_idx < 0) {
- retval = -EINVAL;
- break;
- }
-
- entry->cdte_adr =
- sony_toc.tracks[track_idx].address;
- entry->cdte_ctrl =
- sony_toc.tracks[track_idx].control;
- msf_val =
- sony_toc.tracks[track_idx].track_start_msf;
-
- /* Logical buffer address or MSF format requested? */
- if (entry->cdte_format == CDROM_LBA) {
- entry->cdte_addr.lba = msf_to_log(msf_val);
- } else if (entry->cdte_format == CDROM_MSF) {
- entry->cdte_addr.msf.minute = *msf_val;
- entry->cdte_addr.msf.second =
- *(msf_val + 1);
- entry->cdte_addr.msf.frame =
- *(msf_val + 2);
- }
- }
- retval = 0;
- break;
-
- case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- {
- struct cdrom_ti *ti = (struct cdrom_ti *) arg;
- int track_idx;
-
- sony_get_toc();
- if (!sony_toc_read) {
- retval = -EIO;
- break;
- }
-
- if ((ti->cdti_trk0 < sony_toc.first_track_num)
- || (ti->cdti_trk0 > sony_toc.last_track_num)
- || (ti->cdti_trk1 < ti->cdti_trk0)) {
- retval = -EINVAL;
- break;
- }
-
- track_idx = find_track(ti->cdti_trk0);
- if (track_idx < 0) {
- retval = -EINVAL;
- break;
- }
- params[1] =
- int_to_bcd(sony_toc.tracks[track_idx].
- track_start_msf[0]);
- params[2] =
- int_to_bcd(sony_toc.tracks[track_idx].
- track_start_msf[1]);
- params[3] =
- int_to_bcd(sony_toc.tracks[track_idx].
- track_start_msf[2]);
-
- /*
- * If we want to stop after the last track, use the lead-out
- * MSF to do that.
- */
- if (ti->cdti_trk1 >= sony_toc.last_track_num) {
- track_idx = find_track(CDROM_LEADOUT);
- } else {
- track_idx = find_track(ti->cdti_trk1 + 1);
- }
- if (track_idx < 0) {
- retval = -EINVAL;
- break;
- }
- params[4] =
- int_to_bcd(sony_toc.tracks[track_idx].
- track_start_msf[0]);
- params[5] =
- int_to_bcd(sony_toc.tracks[track_idx].
- track_start_msf[1]);
- params[6] =
- int_to_bcd(sony_toc.tracks[track_idx].
- track_start_msf[2]);
- params[0] = 0x03;
-
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
- &res_size);
-
- do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
- res_reg, &res_size);
-
- if ((res_size < 2)
- || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_ERR PFX
- "Params: %x %x %x %x %x %x %x\n",
- params[0], params[1], params[2],
- params[3], params[4], params[5],
- params[6]);
- printk(KERN_ERR PFX
- "Error %s (CDROMPLAYTRKIND)\n",
- translate_error(res_reg[1]));
- retval = -EIO;
- break;
- }
-
- /* Save the final position for pauses and resumes */
- final_pos_msf[0] = bcd_to_int(params[4]);
- final_pos_msf[1] = bcd_to_int(params[5]);
- final_pos_msf[2] = bcd_to_int(params[6]);
- sony_audio_status = CDROM_AUDIO_PLAY;
- retval = 0;
- break;
- }
-
- case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
- {
- struct cdrom_volctrl *volctrl =
- (struct cdrom_volctrl *) arg;
-
- params[0] = SONY_SD_AUDIO_VOLUME;
- params[1] = volctrl->channel0;
- params[2] = volctrl->channel1;
- retval = do_sony_cd_cmd_chk("VOLCTRL",
- SONY_SET_DRIVE_PARAM_CMD,
- params, 3, res_reg,
- &res_size);
- break;
- }
- case CDROMSUBCHNL: /* Get subchannel info */
- retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg);
- break;
-
- default:
- retval = -EINVAL;
- break;
- }
- up(&sony_sem);
- return retval;
-}
-
-static int scd_read_audio(struct cdrom_device_info *cdi,
- unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- int retval;
-
- if (down_interruptible(&sony_sem))
- return -ERESTARTSYS;
- switch (cmd) {
- case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte
- raw data tracks. */
- {
- struct cdrom_read_audio ra;
-
-
- sony_get_toc();
- if (!sony_toc_read) {
- retval = -EIO;
- break;
- }
-
- if (copy_from_user(&ra, argp, sizeof(ra))) {
- retval = -EFAULT;
- break;
- }
-
- if (ra.nframes == 0) {
- retval = 0;
- break;
- }
-
- if (!access_ok(VERIFY_WRITE, ra.buf,
- CD_FRAMESIZE_RAW * ra.nframes))
- return -EFAULT;
-
- if (ra.addr_format == CDROM_LBA) {
- if ((ra.addr.lba >=
- sony_toc.lead_out_start_lba)
- || (ra.addr.lba + ra.nframes >=
- sony_toc.lead_out_start_lba)) {
- retval = -EINVAL;
- break;
- }
- } else if (ra.addr_format == CDROM_MSF) {
- if ((ra.addr.msf.minute >= 75)
- || (ra.addr.msf.second >= 60)
- || (ra.addr.msf.frame >= 75)) {
- retval = -EINVAL;
- break;
- }
-
- ra.addr.lba = ((ra.addr.msf.minute * 4500)
- + (ra.addr.msf.second * 75)
- + ra.addr.msf.frame);
- if ((ra.addr.lba >=
- sony_toc.lead_out_start_lba)
- || (ra.addr.lba + ra.nframes >=
- sony_toc.lead_out_start_lba)) {
- retval = -EINVAL;
- break;
- }
-
- /* I know, this can go negative on an unsigned. However,
- the first thing done to the data is to add this value,
- so this should compensate and allow direct msf access. */
- ra.addr.lba -= LOG_START_OFFSET;
- } else {
- retval = -EINVAL;
- break;
- }
-
- retval = read_audio(&ra);
- break;
- }
- retval = 0;
- break;
-
- default:
- retval = -EINVAL;
- }
- up(&sony_sem);
- return retval;
-}
-
-static int scd_spinup(void)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- int num_spin_ups;
-
- num_spin_ups = 0;
-
- respinup_on_open:
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
- /* The drive sometimes returns error 0. I don't know why, but ignore
- it. It seems to mean the drive has already done the operation. */
- if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
- printk(KERN_ERR PFX "%s error (scd_open, spin up)\n",
- translate_error(res_reg[1]));
- return 1;
- }
-
- do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
- /* The drive sometimes returns error 0. I don't know why, but ignore
- it. It seems to mean the drive has already done the operation. */
- if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
- /* If the drive is already playing, it's ok. */
- if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
- || (res_reg[1] == 0)) {
- return 0;
- }
-
- /* If the drive says it is not spun up (even though we just did it!)
- then retry the operation at least a few times. */
- if ((res_reg[1] == SONY_NOT_SPIN_ERR)
- && (num_spin_ups < MAX_CDU31A_RETRIES)) {
- num_spin_ups++;
- goto respinup_on_open;
- }
-
- printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n",
- translate_error(res_reg[1]));
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
- &res_size);
- return 1;
- }
- return 0;
-}
-
-/*
- * Open the drive for operations. Spin the drive up and read the table of
- * contents if these have not already been done.
- */
-static int scd_open(struct cdrom_device_info *cdi, int purpose)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned char params[2];
-
- if (purpose == 1) {
- /* Open for IOCTLs only - no media check */
- sony_usage++;
- return 0;
- }
-
- if (sony_usage == 0) {
- if (scd_spinup() != 0)
- return -EIO;
- sony_get_toc();
- if (!sony_toc_read) {
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
- res_reg, &res_size);
- return -EIO;
- }
-
- /* For XA on the CDU31A only, we have to do special reads.
- The CDU33A handles XA automagically. */
- /* if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
- if ((sony_toc.disk_type != 0x00)
- && (!is_double_speed)) {
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x07;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params, 2, res_reg, &res_size);
- if ((res_size < 2)
- || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_WARNING PFX "Unable to set "
- "XA params: 0x%2.2x\n", res_reg[1]);
- }
- sony_xa_mode = 1;
- }
- /* A non-XA disk. Set the parms back if necessary. */
- else if (sony_xa_mode) {
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x0f;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params, 2, res_reg, &res_size);
- if ((res_size < 2)
- || ((res_reg[0] & 0xf0) == 0x20)) {
- printk(KERN_WARNING PFX "Unable to reset "
- "XA params: 0x%2.2x\n", res_reg[1]);
- }
- sony_xa_mode = 0;
- }
-
- sony_spun_up = 1;
- }
-
- sony_usage++;
-
- return 0;
-}
-
-
-/*
- * Close the drive. Spin it down if no task is using it. The spin
- * down will fail if playing audio, so audio play is OK.
- */
-static void scd_release(struct cdrom_device_info *cdi)
-{
- if (sony_usage == 1) {
- unsigned char res_reg[12];
- unsigned int res_size;
-
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
- &res_size);
-
- sony_spun_up = 0;
- }
- sony_usage--;
-}
-
-static struct cdrom_device_ops scd_dops = {
- .open = scd_open,
- .release = scd_release,
- .drive_status = scd_drive_status,
- .media_changed = scd_media_changed,
- .tray_move = scd_tray_move,
- .lock_door = scd_lock_door,
- .select_speed = scd_select_speed,
- .get_last_session = scd_get_last_session,
- .get_mcn = scd_get_mcn,
- .reset = scd_reset,
- .audio_ioctl = scd_audio_ioctl,
- .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
- CDC_SELECT_SPEED | CDC_MULTI_SESSION |
- CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
- CDC_RESET | CDC_DRIVE_STATUS,
- .n_minors = 1,
-};
-
-static struct cdrom_device_info scd_info = {
- .ops = &scd_dops,
- .speed = 2,
- .capacity = 1,
- .name = "cdu31a"
-};
-
-static int scd_block_open(struct inode *inode, struct file *file)
-{
- return cdrom_open(&scd_info, inode, file);
-}
-
-static int scd_block_release(struct inode *inode, struct file *file)
-{
- return cdrom_release(&scd_info, file);
-}
-
-static int scd_block_ioctl(struct inode *inode, struct file *file,
- unsigned cmd, unsigned long arg)
-{
- int retval;
-
- /* The eject and close commands should be handled by Uniform CD-ROM
- * driver - but I always got hard lockup instead of eject
- * until I put this here.
- */
- switch (cmd) {
- case CDROMEJECT:
- scd_lock_door(&scd_info, 0);
- retval = scd_tray_move(&scd_info, 1);
- break;
- case CDROMCLOSETRAY:
- retval = scd_tray_move(&scd_info, 0);
- break;
- case CDROMREADAUDIO:
- retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
- break;
- default:
- retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
- }
- return retval;
-}
-
-static int scd_block_media_changed(struct gendisk *disk)
-{
- return cdrom_media_changed(&scd_info);
-}
-
-static struct block_device_operations scd_bdops =
-{
- .owner = THIS_MODULE,
- .open = scd_block_open,
- .release = scd_block_release,
- .ioctl = scd_block_ioctl,
- .media_changed = scd_block_media_changed,
-};
-
-static struct gendisk *scd_gendisk;
-
-/* The different types of disc loading mechanisms supported */
-static char *load_mech[] __initdata =
- { "caddy", "tray", "pop-up", "unknown" };
-
-static int __init
-get_drive_configuration(unsigned short base_io,
- unsigned char res_reg[], unsigned int *res_size)
-{
- unsigned long retry_count;
-
-
- if (!request_region(base_io, 4, "cdu31a"))
- return 0;
-
- /* Set the base address */
- cdu31a_port = base_io;
-
- /* Set up all the register locations */
- sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
- sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
- sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
- sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
- sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
- sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
- sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
- sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
-
- /*
- * Check to see if anything exists at the status register location.
- * I don't know if this is a good way to check, but it seems to work
- * ok for me.
- */
- if (read_status_register() != 0xff) {
- /*
- * Reset the drive and wait for attention from it (to say it's reset).
- * If you don't wait, the next operation will probably fail.
- */
- reset_drive();
- retry_count = jiffies + SONY_RESET_TIMEOUT;
- while (time_before(jiffies, retry_count)
- && (!is_attention())) {
- sony_sleep();
- }
-
-#if 0
- /* If attention is never seen probably not a CDU31a present */
- if (!is_attention()) {
- res_reg[0] = 0x20;
- goto out_err;
- }
-#endif
-
- /*
- * Get the drive configuration.
- */
- do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
- NULL,
- 0, (unsigned char *) res_reg, res_size);
- if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0)
- goto out_err;
- return 1;
- }
-
- /* Return an error */
- res_reg[0] = 0x20;
-out_err:
- release_region(cdu31a_port, 4);
- cdu31a_port = 0;
- return 0;
-}
-
-#ifndef MODULE
-/*
- * Set up base I/O and interrupts, called from main.c.
- */
-
-static int __init cdu31a_setup(char *strings)
-{
- int ints[4];
-
- (void) get_options(strings, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0) {
- cdu31a_port = ints[1];
- }
- if (ints[0] > 1) {
- cdu31a_irq = ints[2];
- }
- if ((strings != NULL) && (*strings != '\0')) {
- if (strcmp(strings, "PAS") == 0) {
- sony_pas_init = 1;
- } else {
- printk(KERN_NOTICE PFX "Unknown interface type: %s\n",
- strings);
- }
- }
-
- return 1;
-}
-
-__setup("cdu31a=", cdu31a_setup);
-
-#endif
-
-/*
- * Initialize the driver.
- */
-int __init cdu31a_init(void)
-{
- struct s_sony_drive_config drive_config;
- struct gendisk *disk;
- int deficiency = 0;
- unsigned int res_size;
- char msg[255];
- char buf[40];
- int i;
- int tmp_irq;
-
- /*
- * According to Alex Freed (freed@europa.orion.adobe.com), this is
- * required for the Fusion CD-16 package. If the sound driver is
- * loaded, it should work fine, but just in case...
- *
- * The following turn on the CD-ROM interface for a Fusion CD-16.
- */
- if (sony_pas_init) {
- outb(0xbc, 0x9a01);
- outb(0xe2, 0x9a01);
- }
-
- /* Setting the base I/O address to 0xffff will disable it. */
- if (cdu31a_port == 0xffff)
- goto errout3;
-
- if (cdu31a_port != 0) {
- /* Need IRQ 0 because we can't sleep here. */
- tmp_irq = cdu31a_irq;
- cdu31a_irq = 0;
- if (!get_drive_configuration(cdu31a_port,
- drive_config.exec_status,
- &res_size))
- goto errout3;
- cdu31a_irq = tmp_irq;
- } else {
- cdu31a_irq = 0;
- for (i = 0; cdu31a_addresses[i].base; i++) {
- if (get_drive_configuration(cdu31a_addresses[i].base,
- drive_config.exec_status,
- &res_size)) {
- cdu31a_irq = cdu31a_addresses[i].int_num;
- break;
- }
- }
- if (!cdu31a_port)
- goto errout3;
- }
-
- if (register_blkdev(MAJOR_NR, "cdu31a"))
- goto errout2;
-
- disk = alloc_disk(1);
- if (!disk)
- goto errout1;
- disk->major = MAJOR_NR;
- disk->first_minor = 0;
- sprintf(disk->disk_name, "cdu31a");
- disk->fops = &scd_bdops;
- disk->flags = GENHD_FL_CD;
-
- if (SONY_HWC_DOUBLE_SPEED(drive_config))
- is_double_speed = 1;
-
- tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
- cdu31a_irq = 0;
-
- sony_speed = is_double_speed; /* Set 2X drives to 2X by default */
- set_drive_params(sony_speed);
-
- cdu31a_irq = tmp_irq;
-
- if (cdu31a_irq > 0) {
- if (request_irq
- (cdu31a_irq, cdu31a_interrupt, IRQF_DISABLED,
- "cdu31a", NULL)) {
- printk(KERN_WARNING PFX "Unable to grab IRQ%d for "
- "the CDU31A driver\n", cdu31a_irq);
- cdu31a_irq = 0;
- }
- }
-
- sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
- drive_config.vendor_id,
- drive_config.product_id,
- drive_config.product_rev_level);
- sprintf(buf, " Capabilities: %s",
- load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
- strcat(msg, buf);
- if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
- strcat(msg, ", audio");
- else
- deficiency |= CDC_PLAY_AUDIO;
- if (SONY_HWC_EJECT(drive_config))
- strcat(msg, ", eject");
- else
- deficiency |= CDC_OPEN_TRAY;
- if (SONY_HWC_LED_SUPPORT(drive_config))
- strcat(msg, ", LED");
- if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
- strcat(msg, ", elec. Vol");
- if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
- strcat(msg, ", sep. Vol");
- if (is_double_speed)
- strcat(msg, ", double speed");
- else
- deficiency |= CDC_SELECT_SPEED;
- if (cdu31a_irq > 0) {
- sprintf(buf, ", irq %d", cdu31a_irq);
- strcat(msg, buf);
- }
- strcat(msg, "\n");
- printk(KERN_INFO PFX "%s",msg);
-
- cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock);
- if (!cdu31a_queue)
- goto errout0;
- blk_queue_hardsect_size(cdu31a_queue, 2048);
-
- init_timer(&cdu31a_abort_timer);
- cdu31a_abort_timer.function = handle_abort_timeout;
-
- scd_info.mask = deficiency;
- scd_gendisk = disk;
- if (register_cdrom(&scd_info))
- goto err;
- disk->queue = cdu31a_queue;
- add_disk(disk);
-
- disk_changed = 1;
- return 0;
-
-err:
- blk_cleanup_queue(cdu31a_queue);
-errout0:
- if (cdu31a_irq)
- free_irq(cdu31a_irq, NULL);
- printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n");
- put_disk(disk);
-errout1:
- if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
- printk(KERN_WARNING PFX "Can't unregister block device\n");
- }
-errout2:
- release_region(cdu31a_port, 4);
-errout3:
- return -EIO;
-}
-
-
-static void __exit cdu31a_exit(void)
-{
- del_gendisk(scd_gendisk);
- put_disk(scd_gendisk);
- if (unregister_cdrom(&scd_info)) {
- printk(KERN_WARNING PFX "Can't unregister from Uniform "
- "cdrom driver\n");
- return;
- }
- if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
- printk(KERN_WARNING PFX "Can't unregister\n");
- return;
- }
-
- blk_cleanup_queue(cdu31a_queue);
-
- if (cdu31a_irq > 0)
- free_irq(cdu31a_irq, NULL);
-
- release_region(cdu31a_port, 4);
- printk(KERN_INFO PFX "module released.\n");
-}
-
-#ifdef MODULE
-module_init(cdu31a_init);
-#endif
-module_exit(cdu31a_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h
deleted file mode 100644
index 61d4768c412e..000000000000
--- a/drivers/cdrom/cdu31a.h
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Definitions for a Sony interface CDROM drive.
- *
- * Corey Minyard (minyard@wf-rch.cirr.com)
- *
- * Copyright (C) 1993 Corey Minyard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*
- * General defines.
- */
-#define SONY_XA_DISK_TYPE 0x20
-
-/*
- * Offsets (from the base address) and bits for the various write registers
- * of the drive.
- */
-#define SONY_CMD_REG_OFFSET 0
-#define SONY_PARAM_REG_OFFSET 1
-#define SONY_WRITE_REG_OFFSET 2
-#define SONY_CONTROL_REG_OFFSET 3
-# define SONY_ATTN_CLR_BIT 0x01
-# define SONY_RES_RDY_CLR_BIT 0x02
-# define SONY_DATA_RDY_CLR_BIT 0x04
-# define SONY_ATTN_INT_EN_BIT 0x08
-# define SONY_RES_RDY_INT_EN_BIT 0x10
-# define SONY_DATA_RDY_INT_EN_BIT 0x20
-# define SONY_PARAM_CLR_BIT 0x40
-# define SONY_DRIVE_RESET_BIT 0x80
-
-/*
- * Offsets (from the base address) and bits for the various read registers
- * of the drive.
- */
-#define SONY_STATUS_REG_OFFSET 0
-# define SONY_ATTN_BIT 0x01
-# define SONY_RES_RDY_BIT 0x02
-# define SONY_DATA_RDY_BIT 0x04
-# define SONY_ATTN_INT_ST_BIT 0x08
-# define SONY_RES_RDY_INT_ST_BIT 0x10
-# define SONY_DATA_RDY_INT_ST_BIT 0x20
-# define SONY_DATA_REQUEST_BIT 0x40
-# define SONY_BUSY_BIT 0x80
-#define SONY_RESULT_REG_OFFSET 1
-#define SONY_READ_REG_OFFSET 2
-#define SONY_FIFOST_REG_OFFSET 3
-# define SONY_PARAM_WRITE_RDY_BIT 0x01
-# define SONY_PARAM_REG_EMPTY_BIT 0x02
-# define SONY_RES_REG_NOT_EMP_BIT 0x04
-# define SONY_RES_REG_FULL_BIT 0x08
-
-#define LOG_START_OFFSET 150 /* Offset of first logical sector */
-
-#define SONY_DETECT_TIMEOUT (8*HZ/10) /* Maximum amount of time
- that drive detection code
- will wait for response
- from drive (in 1/100th's
- of seconds). */
-
-#define SONY_JIFFIES_TIMEOUT (10*HZ) /* Maximum number of times the
- drive will wait/try for an
- operation */
-#define SONY_RESET_TIMEOUT HZ /* Maximum number of times the
- drive will wait/try a reset
- operation */
-#define SONY_READY_RETRIES 20000 /* How many times to retry a
- spin waiting for a register
- to come ready */
-
-#define MAX_CDU31A_RETRIES 3 /* How many times to retry an
- operation */
-
-/* Commands to request or set drive control parameters and disc information */
-#define SONY_REQ_DRIVE_CONFIG_CMD 0x00 /* Returns s_sony_drive_config */
-#define SONY_REQ_DRIVE_MODE_CMD 0x01
-#define SONY_REQ_DRIVE_PARAM_CMD 0x02
-#define SONY_REQ_MECH_STATUS_CMD 0x03
-#define SONY_REQ_AUDIO_STATUS_CMD 0x04
-#define SONY_SET_DRIVE_PARAM_CMD 0x10
-#define SONY_REQ_TOC_DATA_CMD 0x20 /* Returns s_sony_toc */
-#define SONY_REQ_SUBCODE_ADDRESS_CMD 0x21 /* Returns s_sony_subcode */
-#define SONY_REQ_UPC_EAN_CMD 0x22
-#define SONY_REQ_ISRC_CMD 0x23
-#define SONY_REQ_TOC_DATA_SPEC_CMD 0x24 /* Returns s_sony_session_toc */
-
-/* Commands to request information from the drive */
-#define SONY_READ_TOC_CMD 0x30 /* let the drive firmware grab the TOC */
-#define SONY_SEEK_CMD 0x31
-#define SONY_READ_CMD 0x32
-#define SONY_READ_BLKERR_STAT_CMD 0x34
-#define SONY_ABORT_CMD 0x35
-#define SONY_READ_TOC_SPEC_CMD 0x36
-
-/* Commands to control audio */
-#define SONY_AUDIO_PLAYBACK_CMD 0x40
-#define SONY_AUDIO_STOP_CMD 0x41
-#define SONY_AUDIO_SCAN_CMD 0x42
-
-/* Miscellaneous control commands */
-#define SONY_EJECT_CMD 0x50
-#define SONY_SPIN_UP_CMD 0x51
-#define SONY_SPIN_DOWN_CMD 0x52
-
-/* Diagnostic commands */
-#define SONY_WRITE_BUFFER_CMD 0x60
-#define SONY_READ_BUFFER_CMD 0x61
-#define SONY_DIAGNOSTICS_CMD 0x62
-
-
-/*
- * The following are command parameters for the set drive parameter command
- */
-#define SONY_SD_DECODE_PARAM 0x00
-#define SONY_SD_INTERFACE_PARAM 0x01
-#define SONY_SD_BUFFERING_PARAM 0x02
-#define SONY_SD_AUDIO_PARAM 0x03
-#define SONY_SD_AUDIO_VOLUME 0x04
-#define SONY_SD_MECH_CONTROL 0x05
-#define SONY_SD_AUTO_SPIN_DOWN_TIME 0x06
-
-/*
- * The following are parameter bits for the mechanical control command
- */
-#define SONY_AUTO_SPIN_UP_BIT 0x01
-#define SONY_AUTO_EJECT_BIT 0x02
-#define SONY_DOUBLE_SPEED_BIT 0x04
-
-/*
- * The following extract information from the drive configuration about
- * the drive itself.
- */
-#define SONY_HWC_GET_LOAD_MECH(c) (c.hw_config[0] & 0x03)
-#define SONY_HWC_EJECT(c) (c.hw_config[0] & 0x04)
-#define SONY_HWC_LED_SUPPORT(c) (c.hw_config[0] & 0x08)
-#define SONY_HWC_DOUBLE_SPEED(c) (c.hw_config[0] & 0x10)
-#define SONY_HWC_GET_BUF_MEM_SIZE(c) ((c.hw_config[0] & 0xc0) >> 6)
-#define SONY_HWC_AUDIO_PLAYBACK(c) (c.hw_config[1] & 0x01)
-#define SONY_HWC_ELECTRIC_VOLUME(c) (c.hw_config[1] & 0x02)
-#define SONY_HWC_ELECTRIC_VOLUME_CTL(c) (c.hw_config[1] & 0x04)
-
-#define SONY_HWC_CADDY_LOAD_MECH 0x00
-#define SONY_HWC_TRAY_LOAD_MECH 0x01
-#define SONY_HWC_POPUP_LOAD_MECH 0x02
-#define SONY_HWC_UNKWN_LOAD_MECH 0x03
-
-#define SONY_HWC_8KB_BUFFER 0x00
-#define SONY_HWC_32KB_BUFFER 0x01
-#define SONY_HWC_64KB_BUFFER 0x02
-#define SONY_HWC_UNKWN_BUFFER 0x03
-
-/*
- * This is the complete status returned from the drive configuration request
- * command.
- */
-struct s_sony_drive_config
-{
- unsigned char exec_status[2];
- char vendor_id[8];
- char product_id[16];
- char product_rev_level[8];
- unsigned char hw_config[2];
-};
-
-/* The following is returned from the request subcode address command */
-struct s_sony_subcode
-{
- unsigned char exec_status[2];
- unsigned char address :4;
- unsigned char control :4;
- unsigned char track_num;
- unsigned char index_num;
- unsigned char rel_msf[3];
- unsigned char reserved1;
- unsigned char abs_msf[3];
-};
-
-#define MAX_TRACKS 100 /* The maximum tracks a disk may have. */
-/*
- * The following is returned from the request TOC (Table Of Contents) command.
- * (last_track_num-first_track_num+1) values are valid in tracks.
- */
-struct s_sony_toc
-{
- unsigned char exec_status[2];
- unsigned char address0 :4;
- unsigned char control0 :4;
- unsigned char point0;
- unsigned char first_track_num;
- unsigned char disk_type;
- unsigned char dummy0;
- unsigned char address1 :4;
- unsigned char control1 :4;
- unsigned char point1;
- unsigned char last_track_num;
- unsigned char dummy1;
- unsigned char dummy2;
- unsigned char address2 :4;
- unsigned char control2 :4;
- unsigned char point2;
- unsigned char lead_out_start_msf[3];
- struct
- {
- unsigned char address :4;
- unsigned char control :4;
- unsigned char track;
- unsigned char track_start_msf[3];
- } tracks[MAX_TRACKS];
-
- unsigned int lead_out_start_lba;
-};
-
-struct s_sony_session_toc
-{
- unsigned char exec_status[2];
- unsigned char session_number;
- unsigned char address0 :4;
- unsigned char control0 :4;
- unsigned char point0;
- unsigned char first_track_num;
- unsigned char disk_type;
- unsigned char dummy0;
- unsigned char address1 :4;
- unsigned char control1 :4;
- unsigned char point1;
- unsigned char last_track_num;
- unsigned char dummy1;
- unsigned char dummy2;
- unsigned char address2 :4;
- unsigned char control2 :4;
- unsigned char point2;
- unsigned char lead_out_start_msf[3];
- unsigned char addressb0 :4;
- unsigned char controlb0 :4;
- unsigned char pointb0;
- unsigned char next_poss_prog_area_msf[3];
- unsigned char num_mode_5_pointers;
- unsigned char max_start_outer_leadout_msf[3];
- unsigned char addressb1 :4;
- unsigned char controlb1 :4;
- unsigned char pointb1;
- unsigned char dummyb0_1[4];
- unsigned char num_skip_interval_pointers;
- unsigned char num_skip_track_assignments;
- unsigned char dummyb0_2;
- unsigned char addressb2 :4;
- unsigned char controlb2 :4;
- unsigned char pointb2;
- unsigned char tracksb2[7];
- unsigned char addressb3 :4;
- unsigned char controlb3 :4;
- unsigned char pointb3;
- unsigned char tracksb3[7];
- unsigned char addressb4 :4;
- unsigned char controlb4 :4;
- unsigned char pointb4;
- unsigned char tracksb4[7];
- unsigned char addressc0 :4;
- unsigned char controlc0 :4;
- unsigned char pointc0;
- unsigned char dummyc0[7];
- struct
- {
- unsigned char address :4;
- unsigned char control :4;
- unsigned char track;
- unsigned char track_start_msf[3];
- } tracks[MAX_TRACKS];
-
- unsigned int start_track_lba;
- unsigned int lead_out_start_lba;
- unsigned int mint;
- unsigned int maxt;
-};
-
-struct s_all_sessions_toc
-{
- unsigned char sessions;
- unsigned int track_entries;
- unsigned char first_track_num;
- unsigned char last_track_num;
- unsigned char disk_type;
- unsigned char lead_out_start_msf[3];
- struct
- {
- unsigned char address :4;
- unsigned char control :4;
- unsigned char track;
- unsigned char track_start_msf[3];
- } tracks[MAX_TRACKS];
-
- unsigned int start_track_lba;
- unsigned int lead_out_start_lba;
-};
-
-
-/*
- * The following are errors returned from the drive.
- */
-
-/* Command error group */
-#define SONY_ILL_CMD_ERR 0x10
-#define SONY_ILL_PARAM_ERR 0x11
-
-/* Mechanism group */
-#define SONY_NOT_LOAD_ERR 0x20
-#define SONY_NO_DISK_ERR 0x21
-#define SONY_NOT_SPIN_ERR 0x22
-#define SONY_SPIN_ERR 0x23
-#define SONY_SPINDLE_SERVO_ERR 0x25
-#define SONY_FOCUS_SERVO_ERR 0x26
-#define SONY_EJECT_MECH_ERR 0x29
-#define SONY_AUDIO_PLAYING_ERR 0x2a
-#define SONY_EMERGENCY_EJECT_ERR 0x2c
-
-/* Seek error group */
-#define SONY_FOCUS_ERR 0x30
-#define SONY_FRAME_SYNC_ERR 0x31
-#define SONY_SUBCODE_ADDR_ERR 0x32
-#define SONY_BLOCK_SYNC_ERR 0x33
-#define SONY_HEADER_ADDR_ERR 0x34
-
-/* Read error group */
-#define SONY_ILL_TRACK_R_ERR 0x40
-#define SONY_MODE_0_R_ERR 0x41
-#define SONY_ILL_MODE_R_ERR 0x42
-#define SONY_ILL_BLOCK_SIZE_R_ERR 0x43
-#define SONY_MODE_R_ERR 0x44
-#define SONY_FORM_R_ERR 0x45
-#define SONY_LEAD_OUT_R_ERR 0x46
-#define SONY_BUFFER_OVERRUN_R_ERR 0x47
-
-/* Data error group */
-#define SONY_UNREC_CIRC_ERR 0x53
-#define SONY_UNREC_LECC_ERR 0x57
-
-/* Subcode error group */
-#define SONY_NO_TOC_ERR 0x60
-#define SONY_SUBCODE_DATA_NVAL_ERR 0x61
-#define SONY_FOCUS_ON_TOC_READ_ERR 0x63
-#define SONY_FRAME_SYNC_ON_TOC_READ_ERR 0x64
-#define SONY_TOC_DATA_ERR 0x65
-
-/* Hardware failure group */
-#define SONY_HW_FAILURE_ERR 0x70
-#define SONY_LEAD_IN_A_ERR 0x91
-#define SONY_LEAD_OUT_A_ERR 0x92
-#define SONY_DATA_TRACK_A_ERR 0x93
-
-/*
- * The following are returned from the Read With Block Error Status command.
- * They are not errors but information (Errors from the 0x5x group above may
- * also be returned
- */
-#define SONY_NO_CIRC_ERR_BLK_STAT 0x50
-#define SONY_NO_LECC_ERR_BLK_STAT 0x54
-#define SONY_RECOV_LECC_ERR_BLK_STAT 0x55
-#define SONY_NO_ERR_DETECTION_STAT 0x59
-
-/*
- * The following is not an error returned by the drive, but by the code
- * that talks to the drive. It is returned because of a timeout.
- */
-#define SONY_TIMEOUT_OP_ERR 0x01
-#define SONY_SIGNAL_OP_ERR 0x02
-#define SONY_BAD_DATA_ERR 0x03
-
-
-/*
- * The following are attention code for asynchronous events from the drive.
- */
-
-/* Standard attention group */
-#define SONY_EMER_EJECT_ATTN 0x2c
-#define SONY_HW_FAILURE_ATTN 0x70
-#define SONY_MECH_LOADED_ATTN 0x80
-#define SONY_EJECT_PUSHED_ATTN 0x81
-
-/* Audio attention group */
-#define SONY_AUDIO_PLAY_DONE_ATTN 0x90
-#define SONY_LEAD_IN_ERR_ATTN 0x91
-#define SONY_LEAD_OUT_ERR_ATTN 0x92
-#define SONY_DATA_TRACK_ERR_ATTN 0x93
-#define SONY_AUDIO_PLAYBACK_ERR_ATTN 0x94
-
-/* Auto spin up group */
-#define SONY_SPIN_UP_COMPLETE_ATTN 0x24
-#define SONY_SPINDLE_SERVO_ERR_ATTN 0x25
-#define SONY_FOCUS_SERVO_ERR_ATTN 0x26
-#define SONY_TOC_READ_DONE_ATTN 0x62
-#define SONY_FOCUS_ON_TOC_READ_ERR_ATTN 0x63
-#define SONY_SYNC_ON_TOC_READ_ERR_ATTN 0x65
-
-/* Auto eject group */
-#define SONY_SPIN_DOWN_COMPLETE_ATTN 0x27
-#define SONY_EJECT_COMPLETE_ATTN 0x28
-#define SONY_EJECT_MECH_ERR_ATTN 0x29
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
deleted file mode 100644
index 230131163240..000000000000
--- a/drivers/cdrom/cm206.c
+++ /dev/null
@@ -1,1594 +0,0 @@
-/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
- Copyright (c) 1995--1997 David A. van Leeuwen.
- $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-History:
- Started 25 jan 1994. Waiting for documentation...
- 22 feb 1995: 0.1a first reasonably safe polling driver.
- Two major bugs, one in read_sector and one in
- do_cm206_request, happened to cancel!
- 25 feb 1995: 0.2a first reasonable interrupt driven version of above.
- uart writes are still done in polling mode.
- 25 feb 1995: 0.21a writes also in interrupt mode, still some
- small bugs to be found... Larger buffer.
- 2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in
- initialization), read_ahead of 16. Timeouts implemented.
- unclear if they do something...
- 7 mrt 1995: 0.23 Start of background read-ahead.
- 18 mrt 1995: 0.24 Working background read-ahead. (still problems)
- 26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
- Statistics implemented, though separate stats206.h.
- Accessible through ioctl 0x1000 (just a number).
- Hard to choose between v1.2 development and 1.1.75.
- Bottom-half doesn't work with 1.2...
- 0.25a: fixed... typo. Still problems...
- 1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
- 5 apr 1995: 0.27 Auto-probe for the adapter card base address.
- Auto-probe for the adaptor card irq line.
- 7 apr 1995: 0.28 Added lilo setup support for base address and irq.
- Use major number 32 (not in this source), officially
- assigned to this driver.
- 9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
- resume, eject. Play_track ignores track info, because we can't
- read a table-of-contents entry. Toc_entry is implemented
- as a `placebo' function: always returns start of disc.
- 3 may 1995: 0.30 Audio support completed. The get_toc_entry function
- is implemented as a binary search.
- 15 may 1995: 0.31 More work on audio stuff. Workman is not easy to
- satisfy; changed binary search into linear search.
- Auto-probe for base address somewhat relaxed.
- 1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
- 10 jun 1995: 0.33 Workman still behaves funny, but you should be
- able to eject and substitute another disc.
-
- An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
-
- 18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering
- verify_area's in the ioctls. Some bugs introduced by
- EM considering the base port and irq fixed.
-
- 18 dec 1995: 0.35 Add some code for error checking... no luck...
-
- We jump to reach our goal: version 1.0 in the next stable linux kernel.
-
- 19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
- request of Thomas Quinot.
- 25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
- open only for ioctl operation, e.g., for operation of
- tray etc.
- 4 apr 1996: 0.97 First implementation of layer between VFS and cdrom
- driver, a generic interface. Much of the functionality
- of cm206_open() and cm206_ioctl() is transferred to a
- new file cdrom.c and its header ucdrom.h.
-
- Upgrade to Linux kernel 1.3.78.
-
- 11 apr 1996 0.98 Upgrade to Linux kernel 1.3.85
- More code moved to cdrom.c
-
- 0.99 Some more small changes to decrease number
- of oopses at module load;
-
- 27 jul 1996 0.100 Many hours of debugging, kernel change from 1.2.13
- to 2.0.7 seems to have introduced some weird behavior
- in (interruptible_)sleep_on(&cd->data): the process
- seems to be woken without any explicit wake_up in my own
- code. Patch to try 100x in case such untriggered wake_up's
- occur.
-
- 28 jul 1996 0.101 Rewriting of the code that receives the command echo,
- using a fifo to store echoed bytes.
-
- Branch from 0.99:
-
- 0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
- (emoenke) various typos found by others. extra
- module-load oops protection.
-
- 0.99.1.1 Initialization constant cdrom_dops.speed
- changed from float (2.0) to int (2); Cli()-sti() pair
- around cm260_reset() in module initialization code.
-
- 0.99.1.2 Changes literally as proposed by Scott Snyder
- <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
- have to do mainly with the poor minor support i had. The
- major new concept is to change a cdrom driver's
- operations struct from the capabilities struct. This
- reflects the fact that there is one major for a driver,
- whilst there can be many minors whith completely
- different capabilities.
-
- 0.99.1.3 More changes for operations/info separation.
-
- 0.99.1.4 Added speed selection (someone had to do this
- first).
-
- 23 jan 1997 0.99.1.5 MODULE_PARMS call added.
-
- 23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as
- 0.99.1.1--0.99.1.5. I get too many complaints about the
- drive making read errors. What't wrong with the 2.0+
- kernel line? Why get i (and othe cm206 owners) weird
- results? Why were things good in the good old 1.1--1.2
- era? Why don't i throw away the drive?
-
- 2 feb 1997 0.102 Added `volatile' to values in cm206_struct. Seems to
- reduce many of the problems. Rewrote polling routines
- to use fixed delays between polls.
- 0.103 Changed printk behavior.
- 0.104 Added a 0.100 -> 0.100.1.1 change
-
-11 feb 1997 0.105 Allow auto_probe during module load, disable
- with module option "auto_probe=0". Moved some debugging
- statements to lower priority. Implemented select_speed()
- function.
-
-13 feb 1997 1.0 Final version for 2.0 kernel line.
-
- All following changes will be for the 2.1 kernel line.
-
-15 feb 1997 1.1 Keep up with kernel 2.1.26, merge in changes from
- cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS.
-
-14 sep 1997 1.2 Upgrade to Linux 2.1.55. Added blksize_size[], patch
- sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
-
-21 dec 1997 1.4 Upgrade to Linux 2.1.72.
-
-24 jan 1998 Removed the cm206_disc_status() function, as it was now dead
- code. The Uniform CDROM driver now provides this functionality.
-
-9 Nov. 1999 Make kernel-parameter implementation work with 2.3.x
- Removed init_module & cleanup_module in favor of
- module_init & module_exit.
- Torben Mathiasen <tmm@image.dk>
- *
- * Parts of the code are based upon lmscd.c written by Kai Petzke,
- * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
- * Harriss, but any off-the-shelf dynamic programming algorithm won't
- * be able to find them.
- *
- * The cm206 drive interface and the cm260 adapter card seem to be
- * sufficiently different from their cm205/cm250 counterparts
- * in order to write a complete new driver.
- *
- * I call all routines connected to the Linux kernel something
- * with `cm206' in it, as this stuff is too series-dependent.
- *
- * Currently, my limited knowledge is based on:
- * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
- * - Linux Kernel Programmierung, by Michael Beck and others
- * - Philips/LMS cm206 and cm226 product specification
- * - Philips/LMS cm260 product specification
- *
- * David van Leeuwen, david@tm.tno.nl. */
-#define REVISION "$Revision: 1.5 $"
-
-#include <linux/module.h>
-
-#include <linux/errno.h> /* These include what we really need */
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-/* #include <linux/ucdrom.h> */
-
-#include <asm/io.h>
-
-#define MAJOR_NR CM206_CDROM_MAJOR
-
-#include <linux/blkdev.h>
-
-#undef DEBUG
-#define STATISTICS /* record times and frequencies of events */
-#define AUTO_PROBE_MODULE
-#define USE_INSW
-
-#include "cm206.h"
-
-/* This variable defines whether or not to probe for adapter base port
- address and interrupt request. It can be overridden by the boot
- parameter `auto'.
-*/
-static int auto_probe = 1; /* Yes, why not? */
-
-static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ;
-#ifdef MODULE
-static int cm206[2] = { 0, 0 }; /* for compatible `insmod' parameter passing */
-module_param_array(cm206, int, NULL, 0); /* base,irq or irq,base */
-#endif
-
-module_param(cm206_base, int, 0); /* base */
-module_param(cm206_irq, int, 0); /* irq */
-module_param(auto_probe, bool, 0); /* auto probe base and irq */
-MODULE_LICENSE("GPL");
-
-#define POLLOOP 100 /* milliseconds */
-#define READ_AHEAD 1 /* defines private buffer, waste! */
-#define BACK_AHEAD 1 /* defines adapter-read ahead */
-#define DATA_TIMEOUT (3*HZ) /* measured in jiffies (10 ms) */
-#define UART_TIMEOUT (5*HZ/100)
-#define DSB_TIMEOUT (7*HZ) /* time for the slowest command to finish */
-#define UR_SIZE 4 /* uart receive buffer fifo size */
-
-#define LINUX_BLOCK_SIZE 512 /* WHERE is this defined? */
-#define RAW_SECTOR_SIZE 2352 /* ok, is also defined in cdrom.h */
-#define ISO_SECTOR_SIZE 2048
-#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
-#define CD_SYNC_HEAD 16 /* CD_SYNC + CD_HEAD */
-
-#ifdef STATISTICS /* keep track of errors in counters */
-#define stats(i) { ++cd->stats[st_ ## i]; \
- cd->last_stat[st_ ## i] = cd->stat_counter++; \
- }
-#else
-#define stats(i) (void) 0;
-#endif
-
-#define Debug(a) {printk (KERN_DEBUG); printk a;}
-#ifdef DEBUG
-#define debug(a) Debug(a)
-#else
-#define debug(a) (void) 0;
-#endif
-
-typedef unsigned char uch; /* 8-bits */
-typedef unsigned short ush; /* 16-bits */
-
-struct toc_struct { /* private copy of Table of Contents */
- uch track, fsm[3], q0;
-};
-
-struct cm206_struct {
- volatile ush intr_ds; /* data status read on last interrupt */
- volatile ush intr_ls; /* uart line status read on last interrupt */
- volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */
- volatile uch ur_w, ur_r; /* write/read buffer index */
- volatile uch dsb, cc; /* drive status byte and condition (error) code */
- int command; /* command to be written to the uart */
- int openfiles;
- ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2]; /* buffered cd-sector */
- int sector_first, sector_last; /* range of these sectors */
- wait_queue_head_t uart; /* wait queues for interrupt */
- wait_queue_head_t data;
- struct timer_list timer; /* time-out */
- char timed_out;
- signed char max_sectors; /* number of sectors that fit in adapter mem */
- char wait_back; /* we're waiting for a background-read */
- char background; /* is a read going on in the background? */
- int adapter_first; /* if so, that's the starting sector */
- int adapter_last;
- char fifo_overflowed;
- uch disc_status[7]; /* result of get_disc_status command */
-#ifdef STATISTICS
- int stats[NR_STATS];
- int last_stat[NR_STATS]; /* `time' at which stat was stat */
- int stat_counter;
-#endif
- struct toc_struct toc[101]; /* The whole table of contents + lead-out */
- uch q[10]; /* Last read q-channel info */
- uch audio_status[5]; /* last read position on pause */
- uch media_changed; /* record if media changed */
-};
-
-#define DISC_STATUS cd->disc_status[0]
-#define FIRST_TRACK cd->disc_status[1]
-#define LAST_TRACK cd->disc_status[2]
-#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
-#define PLAY_TO cd->toc[0] /* toc[0] records end-time in play */
-
-static struct cm206_struct *cd; /* the main memory structure */
-static struct request_queue *cm206_queue;
-static DEFINE_SPINLOCK(cm206_lock);
-
-/* First, we define some polling functions. These are actually
- only being used in the initialization. */
-
-static void send_command_polled(int command)
-{
- int loop = POLLOOP;
- while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
- && loop > 0) {
- mdelay(1); /* one millisec delay */
- --loop;
- }
- outw(command, r_uart_transmit);
-}
-
-static uch receive_echo_polled(void)
-{
- int loop = POLLOOP;
- while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
- mdelay(1);
- --loop;
- }
- return ((uch) inw(r_uart_receive));
-}
-
-static uch send_receive_polled(int command)
-{
- send_command_polled(command);
- return receive_echo_polled();
-}
-
-static inline void clear_ur(void)
-{
- if (cd->ur_r != cd->ur_w) {
- debug(("Deleting bytes from fifo:"));
- for (; cd->ur_r != cd->ur_w;
- cd->ur_r++, cd->ur_r %= UR_SIZE)
- debug((" 0x%x", cd->ur[cd->ur_r]));
- debug(("\n"));
- }
-}
-
-static struct tasklet_struct cm206_tasklet;
-
-/* The interrupt handler. When the cm260 generates an interrupt, very
- much care has to be taken in reading out the registers in the right
- order; in case of a receive_buffer_full interrupt, first the
- uart_receive must be read, and then the line status again to
- de-assert the interrupt line. It took me a couple of hours to find
- this out:-(
-
- The function reset_cm206 appears to cause an interrupt, because
- pulling up the INIT line clears both the uart-write-buffer /and/
- the uart-write-buffer-empty mask. We call this a `lost interrupt,'
- as there seems so reason for this to happen.
-*/
-
-static irqreturn_t cm206_interrupt(int sig, void *dev_id)
-{
- volatile ush fool;
- cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
- crc_error, sync_error, toc_ready
- interrupts */
- cd->intr_ls = inw(r_line_status); /* resets overrun bit */
- debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
- cd->background));
- if (cd->intr_ls & ls_attention)
- stats(attention);
- /* receive buffer full? */
- if (cd->intr_ls & ls_receive_buffer_full) {
- cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
- cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
- debug(("receiving #%d: 0x%x\n", cd->ur_w,
- cd->ur[cd->ur_w]));
- cd->ur_w++;
- cd->ur_w %= UR_SIZE;
- if (cd->ur_w == cd->ur_r)
- debug(("cd->ur overflow!\n"));
- if (waitqueue_active(&cd->uart) && cd->background < 2) {
- del_timer(&cd->timer);
- wake_up_interruptible(&cd->uart);
- }
- }
- /* data ready in fifo? */
- else if (cd->intr_ds & ds_data_ready) {
- if (cd->background)
- ++cd->adapter_last;
- if (waitqueue_active(&cd->data)
- && (cd->wait_back || !cd->background)) {
- del_timer(&cd->timer);
- wake_up_interruptible(&cd->data);
- }
- stats(data_ready);
- }
- /* ready to issue a write command? */
- else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
- outw(dc_normal | (inw(r_data_status) & 0x7f),
- r_data_control);
- outw(cd->command, r_uart_transmit);
- cd->command = 0;
- if (!cd->background)
- wake_up_interruptible(&cd->uart);
- }
- /* now treat errors (at least, identify them for debugging) */
- else if (cd->intr_ds & ds_fifo_overflow) {
- debug(("Fifo overflow at sectors 0x%x\n",
- cd->sector_first));
- fool = inw(r_fifo_output_buffer); /* de-assert the interrupt */
- cd->fifo_overflowed = 1; /* signal one word less should be read */
- stats(fifo_overflow);
- } else if (cd->intr_ds & ds_data_error) {
- debug(("Data error at sector 0x%x\n", cd->sector_first));
- stats(data_error);
- } else if (cd->intr_ds & ds_crc_error) {
- debug(("CRC error at sector 0x%x\n", cd->sector_first));
- stats(crc_error);
- } else if (cd->intr_ds & ds_sync_error) {
- debug(("Sync at sector 0x%x\n", cd->sector_first));
- stats(sync_error);
- } else if (cd->intr_ds & ds_toc_ready) {
- /* do something appropriate */
- }
- /* couldn't see why this interrupt, maybe due to init */
- else {
- outw(dc_normal | READ_AHEAD, r_data_control);
- stats(lost_intr);
- }
- if (cd->background
- && (cd->adapter_last - cd->adapter_first == cd->max_sectors
- || cd->fifo_overflowed))
- tasklet_schedule(&cm206_tasklet); /* issue a stop read command */
- stats(interrupt);
- return IRQ_HANDLED;
-}
-
-/* we have put the address of the wait queue in who */
-static void cm206_timeout(unsigned long who)
-{
- cd->timed_out = 1;
- debug(("Timing out\n"));
- wake_up_interruptible((wait_queue_head_t *) who);
-}
-
-/* This function returns 1 if a timeout occurred, 0 if an interrupt
- happened */
-static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
-{
- cd->timed_out = 0;
- init_timer(&cd->timer);
- cd->timer.data = (unsigned long) wait;
- cd->timer.expires = jiffies + timeout;
- add_timer(&cd->timer);
- debug(("going to sleep\n"));
- interruptible_sleep_on(wait);
- del_timer(&cd->timer);
- if (cd->timed_out) {
- cd->timed_out = 0;
- return 1;
- } else
- return 0;
-}
-
-static void send_command(int command)
-{
- debug(("Sending 0x%x\n", command));
- if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
- cd->command = command;
- cli(); /* don't interrupt before sleep */
- outw(dc_mask_sync_error | dc_no_stop_on_error |
- (inw(r_data_status) & 0x7f), r_data_control);
- /* interrupt routine sends command */
- if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
- debug(("Time out on write-buffer\n"));
- stats(write_timeout);
- outw(command, r_uart_transmit);
- }
- debug(("Write commmand delayed\n"));
- } else
- outw(command, r_uart_transmit);
-}
-
-static uch receive_byte(int timeout)
-{
- uch ret;
- cli();
- debug(("cli\n"));
- ret = cd->ur[cd->ur_r];
- if (cd->ur_r != cd->ur_w) {
- sti();
- debug(("returning #%d: 0x%x\n", cd->ur_r,
- cd->ur[cd->ur_r]));
- cd->ur_r++;
- cd->ur_r %= UR_SIZE;
- return ret;
- } else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
- debug(("Time out on receive-buffer\n"));
-#ifdef STATISTICS
- if (timeout == UART_TIMEOUT)
- stats(receive_timeout) /* no `;'! */
- else
- stats(dsb_timeout);
-#endif
- return 0xda;
- }
- ret = cd->ur[cd->ur_r];
- debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
- cd->ur[cd->ur_r]));
- cd->ur_r++;
- cd->ur_r %= UR_SIZE;
- return ret;
-}
-
-static inline uch receive_echo(void)
-{
- return receive_byte(UART_TIMEOUT);
-}
-
-static inline uch send_receive(int command)
-{
- send_command(command);
- return receive_echo();
-}
-
-static inline uch wait_dsb(void)
-{
- return receive_byte(DSB_TIMEOUT);
-}
-
-static int type_0_command(int command, int expect_dsb)
-{
- int e;
- clear_ur();
- if (command != (e = send_receive(command))) {
- debug(("command 0x%x echoed as 0x%x\n", command, e));
- stats(echo);
- return -1;
- }
- if (expect_dsb) {
- cd->dsb = wait_dsb(); /* wait for command to finish */
- }
- return 0;
-}
-
-static int type_1_command(int command, int bytes, uch * status)
-{ /* returns info */
- int i;
- if (type_0_command(command, 0))
- return -1;
- for (i = 0; i < bytes; i++)
- status[i] = send_receive(c_gimme);
- return 0;
-}
-
-/* This function resets the adapter card. We'd better not do this too
- * often, because it tends to generate `lost interrupts.' */
-static void reset_cm260(void)
-{
- outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
- udelay(10); /* 3.3 mu sec minimum */
- outw(dc_normal | READ_AHEAD, r_data_control);
-}
-
-/* fsm: frame-sec-min from linear address; one of many */
-static void fsm(int lba, uch * fsm)
-{
- fsm[0] = lba % 75;
- lba /= 75;
- lba += 2;
- fsm[1] = lba % 60;
- fsm[2] = lba / 60;
-}
-
-static inline int fsm2lba(uch * fsm)
-{
- return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
-}
-
-static inline int f_s_m2lba(uch f, uch s, uch m)
-{
- return f + 75 * (s - 2 + 60 * m);
-}
-
-static int start_read(int start)
-{
- uch read_sector[4] = { c_read_data, };
- int i, e;
-
- fsm(start, &read_sector[1]);
- clear_ur();
- for (i = 0; i < 4; i++)
- if (read_sector[i] != (e = send_receive(read_sector[i]))) {
- debug(("read_sector: %x echoes %x\n",
- read_sector[i], e));
- stats(echo);
- if (e == 0xff) { /* this seems to happen often */
- e = receive_echo();
- debug(("Second try %x\n", e));
- if (e != read_sector[i])
- return -1;
- }
- }
- return 0;
-}
-
-static int stop_read(void)
-{
- int e;
- type_0_command(c_stop, 0);
- if ((e = receive_echo()) != 0xff) {
- debug(("c_stop didn't send 0xff, but 0x%x\n", e));
- stats(stop_0xff);
- return -1;
- }
- return 0;
-}
-
-/* This function starts to read sectors in adapter memory, the
- interrupt routine should stop the read. In fact, the bottom_half
- routine takes care of this. Set a flag `background' in the cd
- struct to indicate the process. */
-
-static int read_background(int start, int reading)
-{
- if (cd->background)
- return -1; /* can't do twice */
- outw(dc_normal | BACK_AHEAD, r_data_control);
- if (!reading && start_read(start))
- return -2;
- cd->adapter_first = cd->adapter_last = start;
- cd->background = 1; /* flag a read is going on */
- return 0;
-}
-
-#ifdef USE_INSW
-#define transport_data insw
-#else
-/* this routine implements insw(,,). There was a time i had the
- impression that there would be any difference in error-behaviour. */
-void transport_data(int port, ush * dest, int count)
-{
- int i;
- ush *d;
- for (i = 0, d = dest; i < count; i++, d++)
- *d = inw(port);
-}
-#endif
-
-
-#define MAX_TRIES 100
-static int read_sector(int start)
-{
- int tries = 0;
- if (cd->background) {
- cd->background = 0;
- cd->adapter_last = -1; /* invalidate adapter memory */
- stop_read();
- }
- cd->fifo_overflowed = 0;
- reset_cm260(); /* empty fifo etc. */
- if (start_read(start))
- return -1;
- do {
- if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
- debug(("Read timed out sector 0x%x\n", start));
- stats(read_timeout);
- stop_read();
- return -3;
- }
- tries++;
- } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
- if (tries > 1)
- debug(("Took me some tries\n"))
- else
- if (tries == MAX_TRIES)
- debug(("MAX_TRIES tries for read sector\n"));
- transport_data(r_fifo_output_buffer, cd->sector,
- READ_AHEAD * RAW_SECTOR_SIZE / 2);
- if (read_background(start + READ_AHEAD, 1))
- stats(read_background);
- cd->sector_first = start;
- cd->sector_last = start + READ_AHEAD;
- stats(read_restarted);
- return 0;
-}
-
-/* The function of bottom-half is to send a stop command to the drive
- This isn't easy because the routine is not `owned' by any process;
- we can't go to sleep! The variable cd->background gives the status:
- 0 no read pending
- 1 a read is pending
- 2 c_stop waits for write_buffer_empty
- 3 c_stop waits for receive_buffer_full: echo
- 4 c_stop waits for receive_buffer_full: 0xff
-*/
-
-static void cm206_tasklet_func(unsigned long ignore)
-{
- debug(("bh: %d\n", cd->background));
- switch (cd->background) {
- case 1:
- stats(bh);
- if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
- cd->command = c_stop;
- outw(dc_mask_sync_error | dc_no_stop_on_error |
- (inw(r_data_status) & 0x7f), r_data_control);
- cd->background = 2;
- break; /* we'd better not time-out here! */
- } else
- outw(c_stop, r_uart_transmit);
- /* fall into case 2: */
- case 2:
- /* the write has been satisfied by interrupt routine */
- cd->background = 3;
- break;
- case 3:
- if (cd->ur_r != cd->ur_w) {
- if (cd->ur[cd->ur_r] != c_stop) {
- debug(("cm206_bh: c_stop echoed 0x%x\n",
- cd->ur[cd->ur_r]));
- stats(echo);
- }
- cd->ur_r++;
- cd->ur_r %= UR_SIZE;
- }
- cd->background++;
- break;
- case 4:
- if (cd->ur_r != cd->ur_w) {
- if (cd->ur[cd->ur_r] != 0xff) {
- debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
- stats(stop_0xff);
- }
- cd->ur_r++;
- cd->ur_r %= UR_SIZE;
- }
- cd->background = 0;
- }
-}
-
-static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
-
-/* This command clears the dsb_possible_media_change flag, so we must
- * retain it.
- */
-static void get_drive_status(void)
-{
- uch status[2];
- type_1_command(c_drive_status, 2, status); /* this might be done faster */
- cd->dsb = status[0];
- cd->cc = status[1];
- cd->media_changed |=
- !!(cd->dsb & (dsb_possible_media_change |
- dsb_drive_not_ready | dsb_tray_not_closed));
-}
-
-static void get_disc_status(void)
-{
- if (type_1_command(c_disc_status, 7, cd->disc_status)) {
- debug(("get_disc_status: error\n"));
- }
-}
-
-/* The new open. The real opening strategy is defined in cdrom.c. */
-
-static int cm206_open(struct cdrom_device_info *cdi, int purpose)
-{
- if (!cd->openfiles) { /* reset only first time */
- cd->background = 0;
- reset_cm260();
- cd->adapter_last = -1; /* invalidate adapter memory */
- cd->sector_last = -1;
- }
- ++cd->openfiles;
- stats(open);
- return 0;
-}
-
-static void cm206_release(struct cdrom_device_info *cdi)
-{
- if (cd->openfiles == 1) {
- if (cd->background) {
- cd->background = 0;
- stop_read();
- }
- cd->sector_last = -1; /* Make our internal buffer invalid */
- FIRST_TRACK = 0; /* No valid disc status */
- }
- --cd->openfiles;
-}
-
-/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
- * and then reads a sector in kernel memory. */
-static void empty_buffer(int sectors)
-{
- while (sectors >= 0) {
- transport_data(r_fifo_output_buffer,
- cd->sector + cd->fifo_overflowed,
- RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
- --sectors;
- ++cd->adapter_first; /* update the current adapter sector */
- cd->fifo_overflowed = 0; /* reset overflow bit */
- stats(sector_transferred);
- }
- cd->sector_first = cd->adapter_first - 1;
- cd->sector_last = cd->adapter_first; /* update the buffer sector */
-}
-
-/* try_adapter. This function determines if the requested sector is
- in adapter memory, or will appear there soon. Returns 0 upon
- success */
-static int try_adapter(int sector)
-{
- if (cd->adapter_first <= sector && sector < cd->adapter_last) {
- /* sector is in adapter memory */
- empty_buffer(sector - cd->adapter_first);
- return 0;
- } else if (cd->background == 1 && cd->adapter_first <= sector
- && sector < cd->adapter_first + cd->max_sectors) {
- /* a read is going on, we can wait for it */
- cd->wait_back = 1;
- while (sector >= cd->adapter_last) {
- if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
- debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
- stats(back_read_timeout);
- cd->wait_back = 0;
- return -1;
- }
- }
- cd->wait_back = 0;
- empty_buffer(sector - cd->adapter_first);
- return 0;
- } else
- return -2;
-}
-
-/* This is not a very smart implementation. We could optimize for
- consecutive block numbers. I'm not convinced this would really
- bring down the processor load. */
-static void do_cm206_request(request_queue_t * q)
-{
- long int i, cd_sec_no;
- int quarter, error;
- uch *source, *dest;
- struct request *req;
-
- while (1) { /* repeat until all requests have been satisfied */
- req = elv_next_request(q);
- if (!req)
- return;
-
- if (req->cmd != READ) {
- debug(("Non-read command %d on cdrom\n", req->cmd));
- end_request(req, 0);
- continue;
- }
- spin_unlock_irq(q->queue_lock);
- error = 0;
- for (i = 0; i < req->nr_sectors; i++) {
- int e1, e2;
- cd_sec_no = (req->sector + i) / BLOCKS_ISO; /* 4 times 512 bytes */
- quarter = (req->sector + i) % BLOCKS_ISO;
- dest = req->buffer + i * LINUX_BLOCK_SIZE;
- /* is already in buffer memory? */
- if (cd->sector_first <= cd_sec_no
- && cd_sec_no < cd->sector_last) {
- source =
- ((uch *) cd->sector) + 16 +
- quarter * LINUX_BLOCK_SIZE +
- (cd_sec_no -
- cd->sector_first) * RAW_SECTOR_SIZE;
- memcpy(dest, source, LINUX_BLOCK_SIZE);
- } else if (!(e1 = try_adapter(cd_sec_no)) ||
- !(e2 = read_sector(cd_sec_no))) {
- source =
- ((uch *) cd->sector) + 16 +
- quarter * LINUX_BLOCK_SIZE;
- memcpy(dest, source, LINUX_BLOCK_SIZE);
- } else {
- error = 1;
- debug(("cm206_request: %d %d\n", e1, e2));
- }
- }
- spin_lock_irq(q->queue_lock);
- end_request(req, !error);
- }
-}
-
-/* Audio support. I've tried very hard, but the cm206 drive doesn't
- seem to have a get_toc (table-of-contents) function, while i'm
- pretty sure it must read the toc upon disc insertion. Therefore
- this function has been implemented through a binary search
- strategy. All track starts that happen to be found are stored in
- cd->toc[], for future use.
-
- I've spent a whole day on a bug that only shows under Workman---
- I don't get it. Tried everything, nothing works. If workman asks
- for track# 0xaa, it'll get the wrong time back. Any other program
- receives the correct value. I'm stymied.
-*/
-
-/* seek seeks to address lba. It does wait to arrive there. */
-static void seek(int lba)
-{
- int i;
- uch seek_command[4] = { c_seek, };
-
- fsm(lba, &seek_command[1]);
- for (i = 0; i < 4; i++)
- type_0_command(seek_command[i], 0);
- cd->dsb = wait_dsb();
-}
-
-static uch bcdbin(unsigned char bcd)
-{ /* stolen from mcd.c! */
- return (bcd >> 4) * 10 + (bcd & 0xf);
-}
-
-static inline uch normalize_track(uch track)
-{
- if (track < 1)
- return 1;
- if (track > LAST_TRACK)
- return LAST_TRACK + 1;
- return track;
-}
-
-/* This function does a binary search for track start. It records all
- * tracks seen in the process. Input $track$ must be between 1 and
- * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm.
- */
-static int get_toc_lba(uch track)
-{
- int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
- int i, lba, l, old_lba = 0;
- uch *q = cd->q;
- uch ct; /* current track */
- int binary = 0;
- const int skip = 3 * 60 * 75; /* 3 minutes */
-
- for (i = track; i > 0; i--)
- if (cd->toc[i].track) {
- min = fsm2lba(cd->toc[i].fsm);
- break;
- }
- lba = min + skip;
- do {
- seek(lba);
- type_1_command(c_read_current_q, 10, q);
- ct = normalize_track(q[1]);
- if (!cd->toc[ct].track) {
- l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
- bcdbin(q[4]) - 2 +
- 60 * (q[7] -
- bcdbin(q
- [3])));
- cd->toc[ct].track = q[1]; /* lead out still 0xaa */
- fsm(l, cd->toc[ct].fsm);
- cd->toc[ct].q0 = q[0]; /* contains adr and ctrl info */
- if (ct == track)
- return l;
- }
- old_lba = lba;
- if (binary) {
- if (ct < track)
- min = lba;
- else
- max = lba;
- lba = (min + max) / 2;
- } else {
- if (ct < track)
- lba += skip;
- else {
- binary = 1;
- max = lba;
- min = lba - skip;
- lba = (min + max) / 2;
- }
- }
- } while (lba != old_lba);
- return lba;
-}
-
-static void update_toc_entry(uch track)
-{
- track = normalize_track(track);
- if (!cd->toc[track].track)
- get_toc_lba(track);
-}
-
-/* return 0 upon success */
-static int read_toc_header(struct cdrom_tochdr *hp)
-{
- if (!FIRST_TRACK)
- get_disc_status();
- if (hp) {
- int i;
- hp->cdth_trk0 = FIRST_TRACK;
- hp->cdth_trk1 = LAST_TRACK;
- /* fill in first track position */
- for (i = 0; i < 3; i++)
- cd->toc[1].fsm[i] = cd->disc_status[3 + i];
- update_toc_entry(LAST_TRACK + 1); /* find most entries */
- return 0;
- }
- return -1;
-}
-
-static void play_from_to_msf(struct cdrom_msf *msfp)
-{
- uch play_command[] = { c_play,
- msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
- msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
- 2
- };
- int i;
- for (i = 0; i < 9; i++)
- type_0_command(play_command[i], 0);
- for (i = 0; i < 3; i++)
- PLAY_TO.fsm[i] = play_command[i + 4];
- PLAY_TO.track = 0; /* say no track end */
- cd->dsb = wait_dsb();
-}
-
-static void play_from_to_track(int from, int to)
-{
- uch play_command[8] = { c_play, };
- int i;
-
- if (from == 0) { /* continue paused play */
- for (i = 0; i < 3; i++) {
- play_command[i + 1] = cd->audio_status[i + 2];
- play_command[i + 4] = PLAY_TO.fsm[i];
- }
- } else {
- update_toc_entry(from);
- update_toc_entry(to + 1);
- for (i = 0; i < 3; i++) {
- play_command[i + 1] = cd->toc[from].fsm[i];
- PLAY_TO.fsm[i] = play_command[i + 4] =
- cd->toc[to + 1].fsm[i];
- }
- PLAY_TO.track = to;
- }
- for (i = 0; i < 7; i++)
- type_0_command(play_command[i], 0);
- for (i = 0; i < 2; i++)
- type_0_command(0x2, 0); /* volume */
- cd->dsb = wait_dsb();
-}
-
-static int get_current_q(struct cdrom_subchnl *qp)
-{
- int i;
- uch *q = cd->q;
- if (type_1_command(c_read_current_q, 10, q))
- return 0;
-/* q[0] = bcdbin(q[0]); Don't think so! */
- for (i = 2; i < 6; i++)
- q[i] = bcdbin(q[i]);
- qp->cdsc_adr = q[0] & 0xf;
- qp->cdsc_ctrl = q[0] >> 4; /* from mcd.c */
- qp->cdsc_trk = q[1];
- qp->cdsc_ind = q[2];
- if (qp->cdsc_format == CDROM_MSF) {
- qp->cdsc_reladdr.msf.minute = q[3];
- qp->cdsc_reladdr.msf.second = q[4];
- qp->cdsc_reladdr.msf.frame = q[5];
- qp->cdsc_absaddr.msf.minute = q[7];
- qp->cdsc_absaddr.msf.second = q[8];
- qp->cdsc_absaddr.msf.frame = q[9];
- } else {
- qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
- qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
- }
- get_drive_status();
- if (cd->dsb & dsb_play_in_progress)
- qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
- else if (PAUSED)
- qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
- else
- qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
- return 0;
-}
-
-static void invalidate_toc(void)
-{
- memset(cd->toc, 0, sizeof(cd->toc));
- memset(cd->disc_status, 0, sizeof(cd->disc_status));
-}
-
-/* cdrom.c guarantees that cdte_format == CDROM_MSF */
-static void get_toc_entry(struct cdrom_tocentry *ep)
-{
- uch track = normalize_track(ep->cdte_track);
- update_toc_entry(track);
- ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
- ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
- ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
- ep->cdte_adr = cd->toc[track].q0 & 0xf;
- ep->cdte_ctrl = cd->toc[track].q0 >> 4;
- ep->cdte_datamode = 0;
-}
-
-/* Audio ioctl. Ioctl commands connected to audio are in such an
- * idiosyncratic i/o format, that we leave these untouched. Return 0
- * upon success. Memory checking has been done by cdrom_ioctl(), the
- * calling function, as well as LBA/MSF sanitization.
-*/
-static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
- void *arg)
-{
- switch (cmd) {
- case CDROMREADTOCHDR:
- return read_toc_header((struct cdrom_tochdr *) arg);
- case CDROMREADTOCENTRY:
- get_toc_entry((struct cdrom_tocentry *) arg);
- return 0;
- case CDROMPLAYMSF:
- play_from_to_msf((struct cdrom_msf *) arg);
- return 0;
- case CDROMPLAYTRKIND: /* admittedly, not particularly beautiful */
- play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
- ((struct cdrom_ti *) arg)->cdti_trk1);
- return 0;
- case CDROMSTOP:
- PAUSED = 0;
- if (cd->dsb & dsb_play_in_progress)
- return type_0_command(c_stop, 1);
- else
- return 0;
- case CDROMPAUSE:
- get_drive_status();
- if (cd->dsb & dsb_play_in_progress) {
- type_0_command(c_stop, 1);
- type_1_command(c_audio_status, 5,
- cd->audio_status);
- PAUSED = 1; /* say we're paused */
- }
- return 0;
- case CDROMRESUME:
- if (PAUSED)
- play_from_to_track(0, 0);
- PAUSED = 0;
- return 0;
- case CDROMSTART:
- case CDROMVOLCTRL:
- return 0;
- case CDROMSUBCHNL:
- return get_current_q((struct cdrom_subchnl *) arg);
- default:
- return -EINVAL;
- }
-}
-
-static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
- if (cd != NULL) {
- int r;
- get_drive_status(); /* ensure cd->media_changed OK */
- r = cd->media_changed;
- cd->media_changed = 0; /* clear bit */
- return r;
- } else
- return -EIO;
-}
-
-/* The new generic cdrom support. Routines should be concise, most of
- the logic should be in cdrom.c */
-
-
-/* controls tray movement */
-static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
-{
- if (position) { /* 1: eject */
- type_0_command(c_open_tray, 1);
- invalidate_toc();
- } else
- type_0_command(c_close_tray, 1); /* 0: close */
- return 0;
-}
-
-/* gives current state of the drive */
-static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
- get_drive_status();
- if (cd->dsb & dsb_tray_not_closed)
- return CDS_TRAY_OPEN;
- if (!(cd->dsb & dsb_disc_present))
- return CDS_NO_DISC;
- if (cd->dsb & dsb_drive_not_ready)
- return CDS_DRIVE_NOT_READY;
- return CDS_DISC_OK;
-}
-
-/* locks or unlocks door lock==1: lock; return 0 upon success */
-static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
-{
- uch command = (lock) ? c_lock_tray : c_unlock_tray;
- type_0_command(command, 1); /* wait and get dsb */
- /* the logic calculates the success, 0 means successful */
- return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
-}
-
-/* Although a session start should be in LBA format, we return it in
- MSF format because it is slightly easier, and the new generic ioctl
- will take care of the necessary conversion. */
-static int cm206_get_last_session(struct cdrom_device_info *cdi,
- struct cdrom_multisession *mssp)
-{
- if (!FIRST_TRACK)
- get_disc_status();
- if (mssp != NULL) {
- if (DISC_STATUS & cds_multi_session) { /* multi-session */
- mssp->addr.msf.frame = cd->disc_status[3];
- mssp->addr.msf.second = cd->disc_status[4];
- mssp->addr.msf.minute = cd->disc_status[5];
- mssp->addr_format = CDROM_MSF;
- mssp->xa_flag = 1;
- } else {
- mssp->xa_flag = 0;
- }
- return 1;
- }
- return 0;
-}
-
-static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
- uch upc[10];
- char *ret = mcn->medium_catalog_number;
- int i;
-
- if (type_1_command(c_read_upc, 10, upc))
- return -EIO;
- for (i = 0; i < 13; i++) {
- int w = i / 2 + 1, r = i % 2;
- if (r)
- ret[i] = 0x30 | (upc[w] & 0x0f);
- else
- ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
- }
- ret[13] = '\0';
- return 0;
-}
-
-static int cm206_reset(struct cdrom_device_info *cdi)
-{
- stop_read();
- reset_cm260();
- outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
- mdelay(1); /* 750 musec minimum */
- outw(dc_normal | READ_AHEAD, r_data_control);
- cd->sector_last = -1; /* flag no data buffered */
- cd->adapter_last = -1;
- invalidate_toc();
- return 0;
-}
-
-static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
-{
- int r;
- switch (speed) {
- case 0:
- r = type_0_command(c_auto_mode, 1);
- break;
- case 1:
- r = type_0_command(c_force_1x, 1);
- break;
- case 2:
- r = type_0_command(c_force_2x, 1);
- break;
- default:
- return -1;
- }
- if (r < 0)
- return r;
- else
- return 1;
-}
-
-static struct cdrom_device_ops cm206_dops = {
- .open = cm206_open,
- .release = cm206_release,
- .drive_status = cm206_drive_status,
- .media_changed = cm206_media_changed,
- .tray_move = cm206_tray_move,
- .lock_door = cm206_lock_door,
- .select_speed = cm206_select_speed,
- .get_last_session = cm206_get_last_session,
- .get_mcn = cm206_get_upc,
- .reset = cm206_reset,
- .audio_ioctl = cm206_audio_ioctl,
- .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
- CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
- CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
- CDC_DRIVE_STATUS,
- .n_minors = 1,
-};
-
-
-static struct cdrom_device_info cm206_info = {
- .ops = &cm206_dops,
- .speed = 2,
- .capacity = 1,
- .name = "cm206",
-};
-
-static int cm206_block_open(struct inode *inode, struct file *file)
-{
- return cdrom_open(&cm206_info, inode, file);
-}
-
-static int cm206_block_release(struct inode *inode, struct file *file)
-{
- return cdrom_release(&cm206_info, file);
-}
-
-static int cm206_block_ioctl(struct inode *inode, struct file *file,
- unsigned cmd, unsigned long arg)
-{
- switch (cmd) {
-#ifdef STATISTICS
- case CM206CTL_GET_STAT:
- if (arg >= NR_STATS)
- return -EINVAL;
- return cd->stats[arg];
- case CM206CTL_GET_LAST_STAT:
- if (arg >= NR_STATS)
- return -EINVAL;
- return cd->last_stat[arg];
-#endif
- default:
- break;
- }
-
- return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
-}
-
-static int cm206_block_media_changed(struct gendisk *disk)
-{
- return cdrom_media_changed(&cm206_info);
-}
-
-static struct block_device_operations cm206_bdops =
-{
- .owner = THIS_MODULE,
- .open = cm206_block_open,
- .release = cm206_block_release,
- .ioctl = cm206_block_ioctl,
- .media_changed = cm206_block_media_changed,
-};
-
-static struct gendisk *cm206_gendisk;
-
-/* This function probes for the adapter card. It returns the base
- address if it has found the adapter card. One can specify a base
- port to probe specifically, or 0 which means span all possible
- bases.
-
- Linus says it is too dangerous to use writes for probing, so we
- stick with pure reads for a while. Hope that 8 possible ranges,
- request_region, 15 bits of one port and 6 of another make things
- likely enough to accept the region on the first hit...
- */
-static int __init probe_base_port(int base)
-{
- int b = 0x300, e = 0x370; /* this is the range of start addresses */
- volatile int fool, i;
-
- if (base)
- b = e = base;
- for (base = b; base <= e; base += 0x10) {
- if (!request_region(base, 0x10,"cm206"))
- continue;
- for (i = 0; i < 3; i++)
- fool = inw(base + 2); /* empty possibly uart_receive_buffer */
- if ((inw(base + 6) & 0xffef) != 0x0001 || /* line_status */
- (inw(base) & 0xad00) != 0) { /* data status */
- release_region(base,0x10);
- continue;
- }
- return (base);
- }
- return 0;
-}
-
-#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
-/* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-static int __init probe_irq(int nr)
-{
- int irqs, irq;
- outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */
- sti();
- irqs = probe_irq_on();
- reset_cm260(); /* causes interrupt */
- udelay(100); /* wait for it */
- irq = probe_irq_off(irqs);
- outw(dc_normal | READ_AHEAD, r_data_control); /* services interrupt */
- if (nr && irq != nr && irq > 0)
- return 0; /* wrong interrupt happened */
- else
- return irq;
-}
-#endif
-
-int __init cm206_init(void)
-{
- uch e = 0;
- long int size = sizeof(struct cm206_struct);
- struct gendisk *disk;
-
- printk(KERN_INFO "cm206 cdrom driver " REVISION);
- cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
- if (!cm206_base) {
- printk(" can't find adapter!\n");
- return -EIO;
- }
- printk(" adapter at 0x%x", cm206_base);
- cd = kmalloc(size, GFP_KERNEL);
- if (!cd)
- goto out_base;
- /* Now we have found the adaptor card, try to reset it. As we have
- * found out earlier, this process generates an interrupt as well,
- * so we might just exploit that fact for irq probing! */
-#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
- cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
- if (cm206_irq <= 0) {
- printk("can't find IRQ!\n");
- goto out_probe;
- } else
- printk(" IRQ %d found\n", cm206_irq);
-#else
- cli();
- reset_cm260();
- /* Now, the problem here is that reset_cm260 can generate an
- interrupt. It seems that this can cause a kernel oops some time
- later. So we wait a while and `service' this interrupt. */
- mdelay(1);
- outw(dc_normal | READ_AHEAD, r_data_control);
- sti();
- printk(" using IRQ %d\n", cm206_irq);
-#endif
- if (send_receive_polled(c_drive_configuration) !=
- c_drive_configuration) {
- printk(KERN_INFO " drive not there\n");
- goto out_probe;
- }
- e = send_receive_polled(c_gimme);
- printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
- if (e & dcf_transfer_rate)
- printk(" double");
- else
- printk(" single");
- printk(" speed drive");
- if (e & dcf_motorized_tray)
- printk(", motorized tray");
- if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
- printk("\nUnable to reserve IRQ---aborted\n");
- goto out_probe;
- }
- printk(".\n");
-
- if (register_blkdev(MAJOR_NR, "cm206"))
- goto out_blkdev;
-
- disk = alloc_disk(1);
- if (!disk)
- goto out_disk;
- disk->major = MAJOR_NR;
- disk->first_minor = 0;
- sprintf(disk->disk_name, "cm206cd");
- disk->fops = &cm206_bdops;
- disk->flags = GENHD_FL_CD;
- cm206_gendisk = disk;
- if (register_cdrom(&cm206_info) != 0) {
- printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
- goto out_cdrom;
- }
- cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
- if (!cm206_queue)
- goto out_queue;
-
- blk_queue_hardsect_size(cm206_queue, 2048);
- disk->queue = cm206_queue;
- add_disk(disk);
-
- memset(cd, 0, sizeof(*cd)); /* give'm some reasonable value */
- cd->sector_last = -1; /* flag no data buffered */
- cd->adapter_last = -1;
- init_timer(&cd->timer);
- cd->timer.function = cm206_timeout;
- cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
- printk(KERN_INFO "%d kB adapter memory available, "
- " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
- size);
- return 0;
-
-out_queue:
- unregister_cdrom(&cm206_info);
-out_cdrom:
- put_disk(disk);
-out_disk:
- unregister_blkdev(MAJOR_NR, "cm206");
-out_blkdev:
- free_irq(cm206_irq, NULL);
-out_probe:
- kfree(cd);
-out_base:
- release_region(cm206_base, 16);
- return -EIO;
-}
-
-#ifdef MODULE
-
-
-static void __init parse_options(void)
-{
- int i;
- for (i = 0; i < 2; i++) {
- if (0x300 <= cm206[i] && i <= 0x370
- && cm206[i] % 0x10 == 0) {
- cm206_base = cm206[i];
- auto_probe = 0;
- } else if (3 <= cm206[i] && cm206[i] <= 15) {
- cm206_irq = cm206[i];
- auto_probe = 0;
- }
- }
-}
-
-static int __init __cm206_init(void)
-{
- parse_options();
-#if !defined(AUTO_PROBE_MODULE)
- auto_probe = 0;
-#endif
- return cm206_init();
-}
-
-static void __exit cm206_exit(void)
-{
- del_gendisk(cm206_gendisk);
- put_disk(cm206_gendisk);
- if (unregister_cdrom(&cm206_info)) {
- printk("Can't unregister cdrom cm206\n");
- return;
- }
- if (unregister_blkdev(MAJOR_NR, "cm206")) {
- printk("Can't unregister major cm206\n");
- return;
- }
- blk_cleanup_queue(cm206_queue);
- free_irq(cm206_irq, NULL);
- kfree(cd);
- release_region(cm206_base, 16);
- printk(KERN_INFO "cm206 removed\n");
-}
-
-module_init(__cm206_init);
-module_exit(cm206_exit);
-
-#else /* !MODULE */
-
-/* This setup function accepts either `auto' or numbers in the range
- * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
-
-static int __init cm206_setup(char *s)
-{
- int i, p[4];
-
- (void) get_options(s, ARRAY_SIZE(p), p);
-
- if (!strcmp(s, "auto"))
- auto_probe = 1;
- for (i = 1; i <= p[0]; i++) {
- if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
- cm206_base = p[i];
- auto_probe = 0;
- } else if (3 <= p[i] && p[i] <= 15) {
- cm206_irq = p[i];
- auto_probe = 0;
- }
- }
- return 1;
-}
-
-__setup("cm206=", cm206_setup);
-
-#endif /* !MODULE */
-MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
-
diff --git a/drivers/cdrom/cm206.h b/drivers/cdrom/cm206.h
deleted file mode 100644
index 0ae51c1a0dac..000000000000
--- a/drivers/cdrom/cm206.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* cm206.h Header file for cm206.c.
- Copyright (c) 1995 David van Leeuwen
-*/
-
-#ifndef LINUX_CM206_H
-#define LINUX_CM206_H
-
-#include <linux/ioctl.h>
-
-/* First, the cm260 stuff */
-/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined
- below, the values are not used unless autoprobing is turned off and
- no LILO boot options or module command line options are given. Change
- these values to your own as last resort if autoprobing and options
- don't work. */
-
-#define CM206_BASE 0x340
-#define CM206_IRQ 11
-
-#define r_data_status (cm206_base)
-#define r_uart_receive (cm206_base+0x2)
-#define r_fifo_output_buffer (cm206_base+0x4)
-#define r_line_status (cm206_base+0x6)
-#define r_data_control (cm206_base+0x8)
-#define r_uart_transmit (cm206_base+0xa)
-#define r_test_clock (cm206_base+0xc)
-#define r_test_control (cm206_base+0xe)
-
-/* the data_status flags */
-#define ds_ram_size 0x4000
-#define ds_toc_ready 0x2000
-#define ds_fifo_empty 0x1000
-#define ds_sync_error 0x800
-#define ds_crc_error 0x400
-#define ds_data_error 0x200
-#define ds_fifo_overflow 0x100
-#define ds_data_ready 0x80
-
-/* the line_status flags */
-#define ls_attention 0x10
-#define ls_parity_error 0x8
-#define ls_overrun 0x4
-#define ls_receive_buffer_full 0x2
-#define ls_transmitter_buffer_empty 0x1
-
-/* the data control register flags */
-#define dc_read_q_channel 0x4000
-#define dc_mask_sync_error 0x2000
-#define dc_toc_enable 0x1000
-#define dc_no_stop_on_error 0x800
-#define dc_break 0x400
-#define dc_initialize 0x200
-#define dc_mask_transmit_ready 0x100
-#define dc_flag_enable 0x80
-
-/* Define the default data control register flags here */
-#define dc_normal (dc_mask_sync_error | dc_no_stop_on_error | \
- dc_mask_transmit_ready)
-
-/* now some constants related to the cm206 */
-/* another drive status byte, echoed by the cm206 on most commands */
-
-#define dsb_error_condition 0x1
-#define dsb_play_in_progress 0x4
-#define dsb_possible_media_change 0x8
-#define dsb_disc_present 0x10
-#define dsb_drive_not_ready 0x20
-#define dsb_tray_locked 0x40
-#define dsb_tray_not_closed 0x80
-
-#define dsb_not_useful (dsb_drive_not_ready | dsb_tray_not_closed)
-
-/* the cm206 command set */
-
-#define c_close_tray 0
-#define c_lock_tray 0x01
-#define c_unlock_tray 0x04
-#define c_open_tray 0x05
-#define c_seek 0x10
-#define c_read_data 0x20
-#define c_force_1x 0x21
-#define c_force_2x 0x22
-#define c_auto_mode 0x23
-#define c_play 0x30
-#define c_set_audio_mode 0x31
-#define c_read_current_q 0x41
-#define c_stream_q 0x42
-#define c_drive_status 0x50
-#define c_disc_status 0x51
-#define c_audio_status 0x52
-#define c_drive_configuration 0x53
-#define c_read_upc 0x60
-#define c_stop 0x70
-#define c_calc_checksum 0xe5
-
-#define c_gimme 0xf8
-
-/* finally, the (error) condition that the drive can be in *
- * OK, this is not always an error, but let's prefix it with e_ */
-
-#define e_none 0
-#define e_illegal_command 0x01
-#define e_sync 0x02
-#define e_seek 0x03
-#define e_parity 0x04
-#define e_focus 0x05
-#define e_header_sync 0x06
-#define e_code_incompatibility 0x07
-#define e_reset_done 0x08
-#define e_bad_parameter 0x09
-#define e_radial 0x0a
-#define e_sub_code 0x0b
-#define e_no_data_track 0x0c
-#define e_scan 0x0d
-#define e_tray_open 0x0f
-#define e_no_disc 0x10
-#define e_tray stalled 0x11
-
-/* drive configuration masks */
-
-#define dcf_revision_code 0x7
-#define dcf_transfer_rate 0x60
-#define dcf_motorized_tray 0x80
-
-/* disc status byte */
-
-#define cds_multi_session 0x2
-#define cds_all_audio 0x8
-#define cds_xa_mode 0xf0
-
-/* finally some ioctls for the driver */
-
-#define CM206CTL_GET_STAT _IO( 0x20, 0 )
-#define CM206CTL_GET_LAST_STAT _IO( 0x20, 1 )
-
-#ifdef STATISTICS
-
-/* This is an ugly way to guarantee that the names of the statistics
- * are the same in the code and in the diagnostics program. */
-
-#ifdef __KERNEL__
-#define x(a) st_ ## a
-#define y enum
-#else
-#define x(a) #a
-#define y char * stats_name[] =
-#endif
-
-y {x(interrupt), x(data_ready), x(fifo_overflow), x(data_error),
- x(crc_error), x(sync_error), x(lost_intr), x(echo),
- x(write_timeout), x(receive_timeout), x(read_timeout),
- x(dsb_timeout), x(stop_0xff), x(back_read_timeout),
- x(sector_transferred), x(read_restarted), x(read_background),
- x(bh), x(open), x(ioctl_multisession), x(attention)
-#ifdef __KERNEL__
- , x(last_entry)
-#endif
- };
-
-#ifdef __KERNEL__
-#define NR_STATS st_last_entry
-#else
-#define NR_STATS (sizeof(stats_name)/sizeof(char*))
-#endif
-
-#undef y
-#undef x
-
-#endif /* STATISTICS */
-
-#endif /* LINUX_CM206_H */
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
deleted file mode 100644
index b3ab6e9b8df1..000000000000
--- a/drivers/cdrom/gscd.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-#define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
-
-/*
- linux/drivers/block/gscd.c - GoldStar R420 CDROM driver
-
- Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
- based upon pre-works by Eberhard Moenkeberg <emoenke@gwdg.de>
-
-
- For all kind of other information about the GoldStar CDROM
- and this Linux device driver I installed a WWW-URL:
- http://linux.rz.fh-hannover.de/~raupach
-
-
- If you are the editor of a Linux CD, you should
- enable gscd.c within your boot floppy kernel and
- send me one of your CDs for free.
-
-
- --------------------------------------------------------------------
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- --------------------------------------------------------------------
-
- 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
- Removed init_module & cleanup_module in favor of
- module_init & module_exit.
- Torben Mathiasen <tmm@image.dk>
-
-*/
-
-/* These settings are for various debug-level. Leave they untouched ... */
-#define NO_GSCD_DEBUG
-#define NO_IOCTL_DEBUG
-#define NO_MODULE_DEBUG
-#define NO_FUTURE_WORK
-/*------------------------*/
-
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
-#include <linux/blkdev.h>
-#include "gscd.h"
-
-static int gscdPresent = 0;
-
-static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
-static int gscd_bn = -1;
-static short gscd_port = GSCD_BASE_ADDR;
-module_param_named(gscd, gscd_port, short, 0);
-
-/* Kommt spaeter vielleicht noch mal dran ...
- * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
- */
-
-static void gscd_read_cmd(struct request *req);
-static void gscd_hsg2msf(long hsg, struct msf *msf);
-static void gscd_bin2bcd(unsigned char *p);
-
-/* Schnittstellen zum Kern/FS */
-
-static void __do_gscd_request(unsigned long dummy);
-static int gscd_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long);
-static int gscd_open(struct inode *, struct file *);
-static int gscd_release(struct inode *, struct file *);
-static int check_gscd_med_chg(struct gendisk *disk);
-
-/* GoldStar Funktionen */
-
-static void cmd_out(int, char *, char *, int);
-static void cmd_status(void);
-static void init_cd_drive(int);
-
-static int get_status(void);
-static void clear_Audio(void);
-static void cc_invalidate(void);
-
-/* some things for the next version */
-#ifdef FUTURE_WORK
-static void update_state(void);
-static long gscd_msf2hsg(struct msf *mp);
-static int gscd_bcd2bin(unsigned char bcd);
-#endif
-
-
-/* lo-level cmd-Funktionen */
-
-static void cmd_info_in(char *, int);
-static void cmd_end(void);
-static void cmd_read_b(char *, int, int);
-static void cmd_read_w(char *, int, int);
-static int cmd_unit_alive(void);
-static void cmd_write_cmd(char *);
-
-
-/* GoldStar Variablen */
-
-static int curr_drv_state;
-static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-static int drv_mode;
-static int disk_state;
-static int speed;
-static int ndrives;
-
-static unsigned char drv_num_read;
-static unsigned char f_dsk_valid;
-static unsigned char current_drive;
-static unsigned char f_drv_ok;
-
-
-static char f_AudioPlay;
-static char f_AudioPause;
-static int AudioStart_m;
-static int AudioStart_f;
-static int AudioEnd_m;
-static int AudioEnd_f;
-
-static DEFINE_TIMER(gscd_timer, NULL, 0, 0);
-static DEFINE_SPINLOCK(gscd_lock);
-static struct request_queue *gscd_queue;
-
-static struct block_device_operations gscd_fops = {
- .owner = THIS_MODULE,
- .open = gscd_open,
- .release = gscd_release,
- .ioctl = gscd_ioctl,
- .media_changed = check_gscd_med_chg,
-};
-
-/*
- * Checking if the media has been changed
- * (not yet implemented)
- */
-static int check_gscd_med_chg(struct gendisk *disk)
-{
-#ifdef GSCD_DEBUG
- printk("gscd: check_med_change\n");
-#endif
- return 0;
-}
-
-
-#ifndef MODULE
-/* Using new interface for kernel-parameters */
-
-static int __init gscd_setup(char *str)
-{
- int ints[2];
- (void) get_options(str, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0) {
- gscd_port = ints[1];
- }
- return 1;
-}
-
-__setup("gscd=", gscd_setup);
-
-#endif
-
-static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- unsigned char to_do[10];
- unsigned char dummy;
-
-
- switch (cmd) {
- case CDROMSTART: /* Spin up the drive */
- /* Don't think we can do this. Even if we could,
- * I think the drive times out and stops after a while
- * anyway. For now, ignore it.
- */
- return 0;
-
- case CDROMRESUME: /* keine Ahnung was das ist */
- return 0;
-
-
- case CDROMEJECT:
- cmd_status();
- to_do[0] = CMD_TRAY_CTL;
- cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-
- return 0;
-
- default:
- return -EINVAL;
- }
-
-}
-
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-
-static void gscd_transfer(struct request *req)
-{
- while (req->nr_sectors > 0 && gscd_bn == req->sector / 4) {
- long offs = (req->sector & 3) * 512;
- memcpy(req->buffer, gscd_buf + offs, 512);
- req->nr_sectors--;
- req->sector++;
- req->buffer += 512;
- }
-}
-
-
-/*
- * I/O request routine called from Linux kernel.
- */
-
-static void do_gscd_request(request_queue_t * q)
-{
- __do_gscd_request(0);
-}
-
-static void __do_gscd_request(unsigned long dummy)
-{
- struct request *req;
- unsigned int block;
- unsigned int nsect;
-
-repeat:
- req = elv_next_request(gscd_queue);
- if (!req)
- return;
-
- block = req->sector;
- nsect = req->nr_sectors;
-
- if (req->sector == -1)
- goto out;
-
- if (req->cmd != READ) {
- printk("GSCD: bad cmd %u\n", rq_data_dir(req));
- end_request(req, 0);
- goto repeat;
- }
-
- gscd_transfer(req);
-
- /* if we satisfied the request from the buffer, we're done. */
-
- if (req->nr_sectors == 0) {
- end_request(req, 1);
- goto repeat;
- }
-#ifdef GSCD_DEBUG
- printk("GSCD: block %d, nsect %d\n", block, nsect);
-#endif
- gscd_read_cmd(req);
-out:
- return;
-}
-
-
-
-/*
- * Check the result of the set-mode command. On success, send the
- * read-data command.
- */
-
-static void gscd_read_cmd(struct request *req)
-{
- long block;
- struct gscd_Play_msf gscdcmd;
- char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */
-
- cmd_status();
- if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
- printk("GSCD: no disk or door open\n");
- end_request(req, 0);
- } else {
- if (disk_state & ST_INVALID) {
- printk("GSCD: disk invalid\n");
- end_request(req, 0);
- } else {
- gscd_bn = -1; /* purge our buffer */
- block = req->sector / 4;
- gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
-
- cmd[2] = gscdcmd.start.min;
- cmd[3] = gscdcmd.start.sec;
- cmd[4] = gscdcmd.start.frame;
-
-#ifdef GSCD_DEBUG
- printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
- cmd[4]);
-#endif
- cmd_out(TYPE_DATA, (char *) &cmd,
- (char *) &gscd_buf[0], 1);
-
- gscd_bn = req->sector / 4;
- gscd_transfer(req);
- end_request(req, 1);
- }
- }
- SET_TIMER(__do_gscd_request, 1);
-}
-
-
-/*
- * Open the device special file. Check that a disk is in.
- */
-
-static int gscd_open(struct inode *ip, struct file *fp)
-{
- int st;
-
-#ifdef GSCD_DEBUG
- printk("GSCD: open\n");
-#endif
-
- if (gscdPresent == 0)
- return -ENXIO; /* no hardware */
-
- get_status();
- st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
- if (st) {
- printk("GSCD: no disk or door open\n");
- return -ENXIO;
- }
-
-/* if (updateToc() < 0)
- return -EIO;
-*/
-
- return 0;
-}
-
-
-/*
- * On close, we flush all gscd blocks from the buffer cache.
- */
-
-static int gscd_release(struct inode *inode, struct file *file)
-{
-
-#ifdef GSCD_DEBUG
- printk("GSCD: release\n");
-#endif
-
- gscd_bn = -1;
-
- return 0;
-}
-
-
-static int get_status(void)
-{
- int status;
-
- cmd_status();
- status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
-
- if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
- cc_invalidate();
- return 1;
- } else {
- return 0;
- }
-}
-
-
-static void cc_invalidate(void)
-{
- drv_num_read = 0xFF;
- f_dsk_valid = 0xFF;
- current_drive = 0xFF;
- f_drv_ok = 0xFF;
-
- clear_Audio();
-
-}
-
-static void clear_Audio(void)
-{
-
- f_AudioPlay = 0;
- f_AudioPause = 0;
- AudioStart_m = 0;
- AudioStart_f = 0;
- AudioEnd_m = 0;
- AudioEnd_f = 0;
-
-}
-
-/*
- * waiting ?
- */
-
-static int wait_drv_ready(void)
-{
- int found, read;
-
- do {
- found = inb(GSCDPORT(0));
- found &= 0x0f;
- read = inb(GSCDPORT(0));
- read &= 0x0f;
- } while (read != found);
-
-#ifdef GSCD_DEBUG
- printk("Wait for: %d\n", read);
-#endif
-
- return read;
-}
-
-static void cc_Ident(char *respons)
-{
- char to_do[] = { CMD_IDENT, 0, 0 };
-
- cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
-
-}
-
-static void cc_SetSpeed(void)
-{
- char to_do[] = { CMD_SETSPEED, 0, 0 };
- char dummy;
-
- if (speed > 0) {
- to_do[1] = speed & 0x0F;
- cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
- }
-}
-
-static void cc_Reset(void)
-{
- char to_do[] = { CMD_RESET, 0 };
- char dummy;
-
- cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-}
-
-static void cmd_status(void)
-{
- char to_do[] = { CMD_STATUS, 0 };
- char dummy;
-
- cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
-
-#ifdef GSCD_DEBUG
- printk("GSCD: Status: %d\n", disk_state);
-#endif
-
-}
-
-static void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
-{
- int result;
-
-
- result = wait_drv_ready();
- if (result != drv_mode) {
- unsigned long test_loops = 0xFFFF;
- int i, dummy;
-
- outb(curr_drv_state, GSCDPORT(0));
-
- /* LOCLOOP_170 */
- do {
- result = wait_drv_ready();
- test_loops--;
- } while ((result != drv_mode) && (test_loops > 0));
-
- if (result != drv_mode) {
- disk_state = ST_x08 | ST_x04 | ST_INVALID;
- return;
- }
-
- /* ...and waiting */
- for (i = 1, dummy = 1; i < 0xFFFF; i++) {
- dummy *= i;
- }
- }
-
- /* LOC_172 */
- /* check the unit */
- /* and wake it up */
- if (cmd_unit_alive() != 0x08) {
- /* LOC_174 */
- /* game over for this unit */
- disk_state = ST_x08 | ST_x04 | ST_INVALID;
- return;
- }
-
- /* LOC_176 */
-#ifdef GSCD_DEBUG
- printk("LOC_176 ");
-#endif
- if (drv_mode == 0x09) {
- /* magic... */
- printk("GSCD: magic ...\n");
- outb(result, GSCDPORT(2));
- }
-
- /* write the command to the drive */
- cmd_write_cmd(cmd);
-
- /* LOC_178 */
- for (;;) {
- result = wait_drv_ready();
- if (result != drv_mode) {
- /* LOC_179 */
- if (result == 0x04) { /* Mode 4 */
- /* LOC_205 */
-#ifdef GSCD_DEBUG
- printk("LOC_205 ");
-#endif
- disk_state = inb(GSCDPORT(2));
-
- do {
- result = wait_drv_ready();
- } while (result != drv_mode);
- return;
-
- } else {
- if (result == 0x06) { /* Mode 6 */
- /* LOC_181 */
-#ifdef GSCD_DEBUG
- printk("LOC_181 ");
-#endif
-
- if (cmd_type == TYPE_DATA) {
- /* read data */
- /* LOC_184 */
- if (drv_mode == 9) {
- /* read the data to the buffer (word) */
-
- /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
- cmd_read_w
- (respo_buf,
- respo_count,
- CD_FRAMESIZE /
- 2);
- return;
- } else {
- /* read the data to the buffer (byte) */
-
- /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
- cmd_read_b
- (respo_buf,
- respo_count,
- CD_FRAMESIZE);
- return;
- }
- } else {
- /* read the info to the buffer */
- cmd_info_in(respo_buf,
- respo_count);
- return;
- }
-
- return;
- }
- }
-
- } else {
- disk_state = ST_x08 | ST_x04 | ST_INVALID;
- return;
- }
- } /* for (;;) */
-
-
-#ifdef GSCD_DEBUG
- printk("\n");
-#endif
-}
-
-
-static void cmd_write_cmd(char *pstr)
-{
- int i, j;
-
- /* LOC_177 */
-#ifdef GSCD_DEBUG
- printk("LOC_177 ");
-#endif
-
- /* calculate the number of parameter */
- j = *pstr & 0x0F;
-
- /* shift it out */
- for (i = 0; i < j; i++) {
- outb(*pstr, GSCDPORT(2));
- pstr++;
- }
-}
-
-
-static int cmd_unit_alive(void)
-{
- int result;
- unsigned long max_test_loops;
-
-
- /* LOC_172 */
-#ifdef GSCD_DEBUG
- printk("LOC_172 ");
-#endif
-
- outb(curr_drv_state, GSCDPORT(0));
- max_test_loops = 0xFFFF;
-
- do {
- result = wait_drv_ready();
- max_test_loops--;
- } while ((result != 0x08) && (max_test_loops > 0));
-
- return result;
-}
-
-
-static void cmd_info_in(char *pb, int count)
-{
- int result;
- char read;
-
-
- /* read info */
- /* LOC_182 */
-#ifdef GSCD_DEBUG
- printk("LOC_182 ");
-#endif
-
- do {
- read = inb(GSCDPORT(2));
- if (count > 0) {
- *pb = read;
- pb++;
- count--;
- }
-
- /* LOC_183 */
- do {
- result = wait_drv_ready();
- } while (result == 0x0E);
- } while (result == 6);
-
- cmd_end();
- return;
-}
-
-
-static void cmd_read_b(char *pb, int count, int size)
-{
- int result;
- int i;
-
-
- /* LOC_188 */
- /* LOC_189 */
-#ifdef GSCD_DEBUG
- printk("LOC_189 ");
-#endif
-
- do {
- do {
- result = wait_drv_ready();
- } while (result != 6 || result == 0x0E);
-
- if (result != 6) {
- cmd_end();
- return;
- }
-#ifdef GSCD_DEBUG
- printk("LOC_191 ");
-#endif
-
- for (i = 0; i < size; i++) {
- *pb = inb(GSCDPORT(2));
- pb++;
- }
- count--;
- } while (count > 0);
-
- cmd_end();
- return;
-}
-
-
-static void cmd_end(void)
-{
- int result;
-
-
- /* LOC_204 */
-#ifdef GSCD_DEBUG
- printk("LOC_204 ");
-#endif
-
- do {
- result = wait_drv_ready();
- if (result == drv_mode) {
- return;
- }
- } while (result != 4);
-
- /* LOC_205 */
-#ifdef GSCD_DEBUG
- printk("LOC_205 ");
-#endif
-
- disk_state = inb(GSCDPORT(2));
-
- do {
- result = wait_drv_ready();
- } while (result != drv_mode);
- return;
-
-}
-
-
-static void cmd_read_w(char *pb, int count, int size)
-{
- int result;
- int i;
-
-
-#ifdef GSCD_DEBUG
- printk("LOC_185 ");
-#endif
-
- do {
- /* LOC_185 */
- do {
- result = wait_drv_ready();
- } while (result != 6 || result == 0x0E);
-
- if (result != 6) {
- cmd_end();
- return;
- }
-
- for (i = 0; i < size; i++) {
- /* na, hier muss ich noch mal drueber nachdenken */
- *pb = inw(GSCDPORT(2));
- pb++;
- }
- count--;
- } while (count > 0);
-
- cmd_end();
- return;
-}
-
-static int __init find_drives(void)
-{
- int *pdrv;
- int drvnum;
- int subdrv;
- int i;
-
- speed = 0;
- pdrv = (int *) &drv_states;
- curr_drv_state = 0xFE;
- subdrv = 0;
- drvnum = 0;
-
- for (i = 0; i < 8; i++) {
- subdrv++;
- cmd_status();
- disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
- if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
- /* LOC_240 */
- *pdrv = curr_drv_state;
- init_cd_drive(drvnum);
- pdrv++;
- drvnum++;
- } else {
- if (subdrv < 2) {
- continue;
- } else {
- subdrv = 0;
- }
- }
-
-/* curr_drv_state<<1; <-- das geht irgendwie nicht */
-/* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
- curr_drv_state *= 2;
- curr_drv_state |= 1;
-#ifdef GSCD_DEBUG
- printk("DriveState: %d\n", curr_drv_state);
-#endif
- }
-
- ndrives = drvnum;
- return drvnum;
-}
-
-static void __init init_cd_drive(int num)
-{
- char resp[50];
- int i;
-
- printk("GSCD: init unit %d\n", num);
- cc_Ident((char *) &resp);
-
- printk("GSCD: identification: ");
- for (i = 0; i < 0x1E; i++) {
- printk("%c", resp[i]);
- }
- printk("\n");
-
- cc_SetSpeed();
-
-}
-
-#ifdef FUTURE_WORK
-/* return_done */
-static void update_state(void)
-{
- unsigned int AX;
-
-
- if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
- if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
- AX = ST_INVALID;
- }
-
- if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
- == 0) {
- invalidate();
- f_drv_ok = 0;
- }
-
- AX |= 0x8000;
- }
-
- if (disk_state & ST_PLAYING) {
- AX |= 0x200;
- }
-
- AX |= 0x100;
- /* pkt_esbx = AX; */
-
- disk_state = 0;
-
-}
-#endif
-
-static struct gendisk *gscd_disk;
-
-static void __exit gscd_exit(void)
-{
- CLEAR_TIMER;
-
- del_gendisk(gscd_disk);
- put_disk(gscd_disk);
- if ((unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
- printk("What's that: can't unregister GoldStar-module\n");
- return;
- }
- blk_cleanup_queue(gscd_queue);
- release_region(gscd_port, GSCD_IO_EXTENT);
- printk(KERN_INFO "GoldStar-module released.\n");
-}
-
-/* This is the common initialisation for the GoldStar drive. */
-/* It is called at boot time AND for module init. */
-static int __init gscd_init(void)
-{
- int i;
- int result;
- int ret=0;
-
- printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
- printk(KERN_INFO
- "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
- gscd_port);
-
- if (!request_region(gscd_port, GSCD_IO_EXTENT, "gscd")) {
- printk(KERN_WARNING "GSCD: Init failed, I/O port (%X) already"
- " in use.\n", gscd_port);
- return -EIO;
- }
-
-
- /* check for card */
- result = wait_drv_ready();
- if (result == 0x09) {
- printk(KERN_WARNING "GSCD: DMA kann ich noch nicht!\n");
- ret = -EIO;
- goto err_out1;
- }
-
- if (result == 0x0b) {
- drv_mode = result;
- i = find_drives();
- if (i == 0) {
- printk(KERN_WARNING "GSCD: GoldStar CD-ROM Drive is"
- " not found.\n");
- ret = -EIO;
- goto err_out1;
- }
- }
-
- if ((result != 0x0b) && (result != 0x09)) {
- printk(KERN_WARNING "GSCD: GoldStar Interface Adapter does not "
- "exist or H/W error\n");
- ret = -EIO;
- goto err_out1;
- }
-
- /* reset all drives */
- i = 0;
- while (drv_states[i] != 0) {
- curr_drv_state = drv_states[i];
- printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
- cc_Reset();
- printk("done\n");
- i++;
- }
-
- gscd_disk = alloc_disk(1);
- if (!gscd_disk)
- goto err_out1;
- gscd_disk->major = MAJOR_NR;
- gscd_disk->first_minor = 0;
- gscd_disk->fops = &gscd_fops;
- sprintf(gscd_disk->disk_name, "gscd");
-
- if (register_blkdev(MAJOR_NR, "gscd")) {
- ret = -EIO;
- goto err_out2;
- }
-
- gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock);
- if (!gscd_queue) {
- ret = -ENOMEM;
- goto err_out3;
- }
-
- disk_state = 0;
- gscdPresent = 1;
-
- gscd_disk->queue = gscd_queue;
- add_disk(gscd_disk);
-
- printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
- return 0;
-
-err_out3:
- unregister_blkdev(MAJOR_NR, "gscd");
-err_out2:
- put_disk(gscd_disk);
-err_out1:
- release_region(gscd_port, GSCD_IO_EXTENT);
- return ret;
-}
-
-static void gscd_hsg2msf(long hsg, struct msf *msf)
-{
- hsg += CD_MSF_OFFSET;
- msf->min = hsg / (CD_FRAMES * CD_SECS);
- hsg %= CD_FRAMES * CD_SECS;
- msf->sec = hsg / CD_FRAMES;
- msf->frame = hsg % CD_FRAMES;
-
- gscd_bin2bcd(&msf->min); /* convert to BCD */
- gscd_bin2bcd(&msf->sec);
- gscd_bin2bcd(&msf->frame);
-}
-
-
-static void gscd_bin2bcd(unsigned char *p)
-{
- int u, t;
-
- u = *p % 10;
- t = *p / 10;
- *p = u | (t << 4);
-}
-
-
-#ifdef FUTURE_WORK
-static long gscd_msf2hsg(struct msf *mp)
-{
- return gscd_bcd2bin(mp->frame)
- + gscd_bcd2bin(mp->sec) * CD_FRAMES
- + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
-}
-
-static int gscd_bcd2bin(unsigned char bcd)
-{
- return (bcd >> 4) * 10 + (bcd & 0xF);
-}
-#endif
-
-MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
-MODULE_LICENSE("GPL");
-module_init(gscd_init);
-module_exit(gscd_exit);
-MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR);
diff --git a/drivers/cdrom/gscd.h b/drivers/cdrom/gscd.h
deleted file mode 100644
index a41e64bfc061..000000000000
--- a/drivers/cdrom/gscd.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Definitions for a GoldStar R420 CD-ROM interface
- *
- * Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
- * Eberhard Moenkeberg <emoenke@gwdg.de>
- *
- * Published under the GPL.
- *
- */
-
-
-/* The Interface Card default address is 0x340. This will work for most
- applications. Address selection is accomplished by jumpers PN801-1 to
- PN801-4 on the GoldStar Interface Card.
- Appropriate settings are: 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360
- 0x370, 0x380, 0x390, 0x3A0, 0x3B0, 0x3C0, 0x3D0, 0x3E0, 0x3F0 */
-
-/* insert here the I/O port address and extent */
-#define GSCD_BASE_ADDR 0x340
-#define GSCD_IO_EXTENT 4
-
-
-/************** nothing to set up below here *********************/
-
-/* port access macro */
-#define GSCDPORT(x) (gscd_port + (x))
-
-/*
- * commands
- * the lower nibble holds the command length
- */
-#define CMD_STATUS 0x01
-#define CMD_READSUBQ 0x02 /* 1: ?, 2: UPC, 5: ? */
-#define CMD_SEEK 0x05 /* read_mode M-S-F */
-#define CMD_READ 0x07 /* read_mode M-S-F nsec_h nsec_l */
-#define CMD_RESET 0x11
-#define CMD_SETMODE 0x15
-#define CMD_PLAY 0x17 /* M-S-F M-S-F */
-#define CMD_LOCK_CTL 0x22 /* 0: unlock, 1: lock */
-#define CMD_IDENT 0x31
-#define CMD_SETSPEED 0x32 /* 0: auto */ /* ??? */
-#define CMD_GETMODE 0x41
-#define CMD_PAUSE 0x51
-#define CMD_READTOC 0x61
-#define CMD_DISKINFO 0x71
-#define CMD_TRAY_CTL 0x81
-
-/*
- * disk_state:
- */
-#define ST_PLAYING 0x80
-#define ST_UNLOCKED 0x40
-#define ST_NO_DISK 0x20
-#define ST_DOOR_OPEN 0x10
-#define ST_x08 0x08
-#define ST_x04 0x04
-#define ST_INVALID 0x02
-#define ST_x01 0x01
-
-/*
- * cmd_type:
- */
-#define TYPE_INFO 0x01
-#define TYPE_DATA 0x02
-
-/*
- * read_mode:
- */
-#define MOD_POLLED 0x80
-#define MOD_x08 0x08
-#define MOD_RAW 0x04
-
-#define READ_DATA(port, buf, nr) insb(port, buf, nr)
-
-#define SET_TIMER(func, jifs) \
- ((mod_timer(&gscd_timer, jiffies + jifs)), \
- (gscd_timer.function = func))
-
-#define CLEAR_TIMER del_timer_sync(&gscd_timer)
-
-#define MAX_TRACKS 104
-
-struct msf {
- unsigned char min;
- unsigned char sec;
- unsigned char frame;
-};
-
-struct gscd_Play_msf {
- struct msf start;
- struct msf end;
-};
-
-struct gscd_DiskInfo {
- unsigned char first;
- unsigned char last;
- struct msf diskLength;
- struct msf firstTrack;
-};
-
-struct gscd_Toc {
- unsigned char ctrl_addr;
- unsigned char track;
- unsigned char pointIndex;
- struct msf trackTime;
- struct msf diskTime;
-};
-
diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c
deleted file mode 100644
index db0fd9a240e3..000000000000
--- a/drivers/cdrom/isp16.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/* -- ISP16 cdrom detection and configuration
- *
- * Copyright (c) 1995,1996 Eric van der Maarel <H.T.M.v.d.Maarel@marin.nl>
- *
- * Version 0.6
- *
- * History:
- * 0.5 First release.
- * Was included in the sjcd and optcd cdrom drivers.
- * 0.6 First "stand-alone" version.
- * Removed sound configuration.
- * Added "module" support.
- *
- * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
- * Removed init_module & cleanup_module in favor of
- * module_init & module_exit.
- * Torben Mathiasen <tmm@image.dk>
- *
- * 19 June 2004 -- check_region() converted to request_region()
- * and return statement cleanups.
- * - Jesper Juhl
- *
- * Detect cdrom interface on ISP16 sound card.
- * Configure cdrom interface.
- *
- * Algorithm for the card with OPTi 82C928 taken
- * from the CDSETUP.SYS driver for MSDOS,
- * by OPTi Computers, version 2.03.
- * Algorithm for the card with OPTi 82C929 as communicated
- * to me by Vadim Model and Leo Spiekman.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define ISP16_VERSION_MAJOR 0
-#define ISP16_VERSION_MINOR 6
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include "isp16.h"
-
-static short isp16_detect(void);
-static short isp16_c928__detect(void);
-static short isp16_c929__detect(void);
-static short isp16_cdi_config(int base, u_char drive_type, int irq,
- int dma);
-static short isp16_type; /* dependent on type of interface card */
-static u_char isp16_ctrl;
-static u_short isp16_enable_port;
-
-static int isp16_cdrom_base = ISP16_CDROM_IO_BASE;
-static int isp16_cdrom_irq = ISP16_CDROM_IRQ;
-static int isp16_cdrom_dma = ISP16_CDROM_DMA;
-static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
-
-module_param(isp16_cdrom_base, int, 0);
-module_param(isp16_cdrom_irq, int, 0);
-module_param(isp16_cdrom_dma, int, 0);
-module_param(isp16_cdrom_type, charp, 0);
-
-#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
-#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
-
-#ifndef MODULE
-
-static int
-__init isp16_setup(char *str)
-{
- int ints[4];
-
- (void) get_options(str, ARRAY_SIZE(ints), ints);
- if (ints[0] > 0)
- isp16_cdrom_base = ints[1];
- if (ints[0] > 1)
- isp16_cdrom_irq = ints[2];
- if (ints[0] > 2)
- isp16_cdrom_dma = ints[3];
- if (str)
- isp16_cdrom_type = str;
-
- return 1;
-}
-
-__setup("isp16=", isp16_setup);
-
-#endif /* MODULE */
-
-/*
- * ISP16 initialisation.
- *
- */
-static int __init isp16_init(void)
-{
- u_char expected_drive;
-
- printk(KERN_INFO
- "ISP16: configuration cdrom interface, version %d.%d.\n",
- ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
-
- if (!strcmp(isp16_cdrom_type, "noisp16")) {
- printk("ISP16: no cdrom interface configured.\n");
- return 0;
- }
-
- if (!request_region(ISP16_IO_BASE, ISP16_IO_SIZE, "isp16")) {
- printk("ISP16: i/o ports already in use.\n");
- goto out;
- }
-
- if ((isp16_type = isp16_detect()) < 0) {
- printk("ISP16: no cdrom interface found.\n");
- goto cleanup_out;
- }
-
- printk(KERN_INFO
- "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
- (isp16_type == 2) ? 9 : 8);
-
- if (!strcmp(isp16_cdrom_type, "Sanyo"))
- expected_drive =
- (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
- else if (!strcmp(isp16_cdrom_type, "Sony"))
- expected_drive = ISP16_SONY;
- else if (!strcmp(isp16_cdrom_type, "Panasonic"))
- expected_drive =
- (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
- else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
- expected_drive = ISP16_MITSUMI;
- else {
- printk("ISP16: %s not supported by cdrom interface.\n",
- isp16_cdrom_type);
- goto cleanup_out;
- }
-
- if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
- isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
- printk
- ("ISP16: cdrom interface has not been properly configured.\n");
- goto cleanup_out;
- }
- printk(KERN_INFO
- "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
- " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
- isp16_cdrom_dma, isp16_cdrom_type);
- return 0;
-
-cleanup_out:
- release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
-out:
- return -EIO;
-}
-
-static short __init isp16_detect(void)
-{
-
- if (isp16_c929__detect() >= 0)
- return 2;
- else
- return (isp16_c928__detect());
-}
-
-static short __init isp16_c928__detect(void)
-{
- u_char ctrl;
- u_char enable_cdrom;
- u_char io;
- short i = -1;
-
- isp16_ctrl = ISP16_C928__CTRL;
- isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
- /* read' and write' are a special read and write, respectively */
-
- /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
- ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
- ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-
- /* read' 3,4 and 5-bit from the cdrom enable port */
- enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
-
- if (!(enable_cdrom & 0x20)) { /* 5-bit not set */
- /* read' last 2 bits of ISP16_IO_SET_PORT */
- io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
- if (((io & 0x01) << 1) == (io & 0x02)) { /* bits are the same */
- if (io == 0) { /* ...the same and 0 */
- i = 0;
- enable_cdrom |= 0x20;
- } else { /* ...the same and 1 *//* my card, first time 'round */
- i = 1;
- enable_cdrom |= 0x28;
- }
- ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
- } else { /* bits are not the same */
- ISP16_OUT(ISP16_CTRL_PORT, ctrl);
- return i; /* -> not detected: possibly incorrect conclusion */
- }
- } else if (enable_cdrom == 0x20)
- i = 0;
- else if (enable_cdrom == 0x28) /* my card, already initialised */
- i = 1;
-
- ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-
- return i;
-}
-
-static short __init isp16_c929__detect(void)
-{
- u_char ctrl;
- u_char tmp;
-
- isp16_ctrl = ISP16_C929__CTRL;
- isp16_enable_port = ISP16_C929__ENABLE_PORT;
-
- /* read' and write' are a special read and write, respectively */
-
- /* read' ISP16_CTRL_PORT and save */
- ctrl = ISP16_IN(ISP16_CTRL_PORT);
-
- /* write' zero to the ctrl port and get response */
- ISP16_OUT(ISP16_CTRL_PORT, 0);
- tmp = ISP16_IN(ISP16_CTRL_PORT);
-
- if (tmp != 2) /* isp16 with 82C929 not detected */
- return -1;
-
- /* restore ctrl port value */
- ISP16_OUT(ISP16_CTRL_PORT, ctrl);
-
- return 2;
-}
-
-static short __init
-isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
-{
- u_char base_code;
- u_char irq_code;
- u_char dma_code;
- u_char i;
-
- if ((drive_type == ISP16_MITSUMI) && (dma != 0))
- printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
-
- switch (base) {
- case 0x340:
- base_code = ISP16_BASE_340;
- break;
- case 0x330:
- base_code = ISP16_BASE_330;
- break;
- case 0x360:
- base_code = ISP16_BASE_360;
- break;
- case 0x320:
- base_code = ISP16_BASE_320;
- break;
- default:
- printk
- ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
- base);
- return -1;
- }
- switch (irq) {
- case 0:
- irq_code = ISP16_IRQ_X;
- break; /* disable irq */
- case 5:
- irq_code = ISP16_IRQ_5;
- printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
- " due to possible conflicts with the sound card.\n");
- break;
- case 7:
- irq_code = ISP16_IRQ_7;
- printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
- " due to possible conflicts with the sound card.\n");
- break;
- case 3:
- irq_code = ISP16_IRQ_3;
- break;
- case 9:
- irq_code = ISP16_IRQ_9;
- break;
- case 10:
- irq_code = ISP16_IRQ_10;
- break;
- case 11:
- irq_code = ISP16_IRQ_11;
- break;
- default:
- printk("ISP16: irq %d not supported by cdrom interface.\n",
- irq);
- return -1;
- }
- switch (dma) {
- case 0:
- dma_code = ISP16_DMA_X;
- break; /* disable dma */
- case 1:
- printk("ISP16: dma 1 cannot be used by cdrom interface,"
- " due to conflict with the sound card.\n");
- return -1;
- break;
- case 3:
- dma_code = ISP16_DMA_3;
- break;
- case 5:
- dma_code = ISP16_DMA_5;
- break;
- case 6:
- dma_code = ISP16_DMA_6;
- break;
- case 7:
- dma_code = ISP16_DMA_7;
- break;
- default:
- printk("ISP16: dma %d not supported by cdrom interface.\n",
- dma);
- return -1;
- }
-
- if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
- drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
- drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
- drive_type != ISP16_DRIVE_X) {
- printk
- ("ISP16: drive type (code 0x%02X) not supported by cdrom"
- " interface.\n", drive_type);
- return -1;
- }
-
- /* set type of interface */
- i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
- ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
-
- /* enable cdrom on interface with 82C929 chip */
- if (isp16_type > 1)
- ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
-
- /* set base address, irq and dma */
- i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
- ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
-
- return 0;
-}
-
-static void __exit isp16_exit(void)
-{
- release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
- printk(KERN_INFO "ISP16: module released.\n");
-}
-
-module_init(isp16_init);
-module_exit(isp16_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h
deleted file mode 100644
index 5bd22c8f7a96..000000000000
--- a/drivers/cdrom/isp16.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -- isp16.h
- *
- * Header for detection and initialisation of cdrom interface (only) on
- * ISP16 (MAD16, Mozart) sound card.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* These are the default values */
-#define ISP16_CDROM_TYPE "Sanyo"
-#define ISP16_CDROM_IO_BASE 0x340
-#define ISP16_CDROM_IRQ 0
-#define ISP16_CDROM_DMA 0
-
-/* Some (Media)Magic */
-/* define types of drive the interface on an ISP16 card may be looking at */
-#define ISP16_DRIVE_X 0x00
-#define ISP16_SONY 0x02
-#define ISP16_PANASONIC0 0x02
-#define ISP16_SANYO0 0x02
-#define ISP16_MITSUMI 0x04
-#define ISP16_PANASONIC1 0x06
-#define ISP16_SANYO1 0x06
-#define ISP16_DRIVE_NOT_USED 0x08 /* not used */
-#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/
-/* ...for port */
-#define ISP16_DRIVE_SET_PORT 0xF8D
-/* set io parameters */
-#define ISP16_BASE_340 0x00
-#define ISP16_BASE_330 0x40
-#define ISP16_BASE_360 0x80
-#define ISP16_BASE_320 0xC0
-#define ISP16_IRQ_X 0x00
-#define ISP16_IRQ_5 0x04 /* shouldn't be used to avoid sound card conflicts */
-#define ISP16_IRQ_7 0x08 /* shouldn't be used to avoid sound card conflicts */
-#define ISP16_IRQ_3 0x0C
-#define ISP16_IRQ_9 0x10
-#define ISP16_IRQ_10 0x14
-#define ISP16_IRQ_11 0x18
-#define ISP16_DMA_X 0x03
-#define ISP16_DMA_3 0x00
-#define ISP16_DMA_5 0x00
-#define ISP16_DMA_6 0x01
-#define ISP16_DMA_7 0x02
-#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */
-/* ...for port */
-#define ISP16_IO_SET_PORT 0xF8E
-/* enable the card */
-#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */
-#define ISP16_ENABLE_CDROM 0x80 /* seven bit */
-
-/* the magic stuff */
-#define ISP16_CTRL_PORT 0xF8F
-#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */
-
-#define ISP16_IO_BASE 0xF8D
-#define ISP16_IO_SIZE 5 /* ports used from 0xF8D up to 0xF91 */
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
deleted file mode 100644
index 4310cc84dfed..000000000000
--- a/drivers/cdrom/mcdx.c
+++ /dev/null
@@ -1,1943 +0,0 @@
-/*
- * The Mitsumi CDROM interface
- * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 2.14(hs)
- *
- * ... anyway, I'm back again, thanks to Marcin, he adopted
- * large portions of my code (at least the parts containing
- * my main thoughts ...)
- *
- ****************** H E L P *********************************
- * If you ever plan to update your CD ROM drive and perhaps
- * want to sell or simply give away your Mitsumi FX-001[DS]
- * -- Please --
- * mail me (heiko@lotte.sax.de). When my last drive goes
- * ballistic no more driver support will be available from me!
- *************************************************************
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Thanks to
- * The Linux Community at all and ...
- * Martin Harriss (he wrote the first Mitsumi Driver)
- * Eberhard Moenkeberg (he gave me much support and the initial kick)
- * Bernd Huebner, Ruediger Helsch (Unifix-Software GmbH, they
- * improved the original driver)
- * Jon Tombs, Bjorn Ekwall (module support)
- * Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
- * Gerd Knorr (he lent me his PhotoCD)
- * Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
- * Andreas Kies (testing the mysterious hang-ups)
- * Heiko Eissfeldt (VERIFY_READ/WRITE)
- * Marcin Dalecki (improved performance, shortened code)
- * ... somebody forgotten?
- *
- * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
- * Removed init_module & cleanup_module in favor of
- * module_init & module_exit.
- * Torben Mathiasen <tmm@image.dk>
- */
-
-
-#ifdef RCS
-static const char *mcdx_c_version
- = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
-#endif
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/current.h>
-#include <asm/uaccess.h>
-
-#include <linux/major.h>
-#define MAJOR_NR MITSUMI_X_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#include "mcdx.h"
-
-#ifndef HZ
-#error HZ not defined
-#endif
-
-#define xwarn(fmt, args...) printk(KERN_WARNING MCDX " " fmt, ## args)
-
-#if !MCDX_QUIET
-#define xinfo(fmt, args...) printk(KERN_INFO MCDX " " fmt, ## args)
-#else
-#define xinfo(fmt, args...) { ; }
-#endif
-
-#if MCDX_DEBUG
-#define xtrace(lvl, fmt, args...) \
- { if (lvl > 0) \
- { printk(KERN_DEBUG MCDX ":: " fmt, ## args); } }
-#define xdebug(fmt, args...) printk(KERN_DEBUG MCDX ":: " fmt, ## args)
-#else
-#define xtrace(lvl, fmt, args...) { ; }
-#define xdebug(fmt, args...) { ; }
-#endif
-
-/* CONSTANTS *******************************************************/
-
-/* Following are the number of sectors we _request_ from the drive
- every time an access outside the already requested range is done.
- The _direct_ size is the number of sectors we're allowed to skip
- directly (performing a read instead of requesting the new sector
- needed */
-static const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */
-static const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */
-
-enum drivemodes { TOC, DATA, RAW, COOKED };
-enum datamodes { MODE0, MODE1, MODE2 };
-enum resetmodes { SOFT, HARD };
-
-static const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
-static const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
-static const int DOOR = 0x04; /* door locking capability */
-static const int MULTI = 0x08; /* multi session capability */
-
-static const unsigned char READ1X = 0xc0;
-static const unsigned char READ2X = 0xc1;
-
-
-/* DECLARATIONS ****************************************************/
-struct s_subqcode {
- unsigned char control;
- unsigned char tno;
- unsigned char index;
- struct cdrom_msf0 tt;
- struct cdrom_msf0 dt;
-};
-
-struct s_diskinfo {
- unsigned int n_first;
- unsigned int n_last;
- struct cdrom_msf0 msf_leadout;
- struct cdrom_msf0 msf_first;
-};
-
-struct s_multi {
- unsigned char multi;
- struct cdrom_msf0 msf_last;
-};
-
-struct s_version {
- unsigned char code;
- unsigned char ver;
-};
-
-/* Per drive/controller stuff **************************************/
-
-struct s_drive_stuff {
- /* waitqueues */
- wait_queue_head_t busyq;
- wait_queue_head_t lockq;
- wait_queue_head_t sleepq;
-
- /* flags */
- volatile int introk; /* status of last irq operation */
- volatile int busy; /* drive performs an operation */
- volatile int lock; /* exclusive usage */
-
- /* cd infos */
- struct s_diskinfo di;
- struct s_multi multi;
- struct s_subqcode *toc; /* first entry of the toc array */
- struct s_subqcode start;
- struct s_subqcode stop;
- int xa; /* 1 if xa disk */
- int audio; /* 1 if audio disk */
- int audiostatus;
-
- /* `buffer' control */
- volatile int valid; /* pending, ..., values are valid */
- volatile int pending; /* next sector to be read */
- volatile int low_border; /* first sector not to be skipped direct */
- volatile int high_border; /* first sector `out of area' */
-#ifdef AK2
- volatile int int_err;
-#endif /* AK2 */
-
- /* adds and odds */
- unsigned wreg_data; /* w data */
- unsigned wreg_reset; /* w hardware reset */
- unsigned wreg_hcon; /* w hardware conf */
- unsigned wreg_chn; /* w channel */
- unsigned rreg_data; /* r data */
- unsigned rreg_status; /* r status */
-
- int irq; /* irq used by this drive */
- int present; /* drive present and its capabilities */
- unsigned char readcmd; /* read cmd depends on single/double speed */
- unsigned char playcmd; /* play should always be single speed */
- unsigned int xxx; /* set if changed, reset while open */
- unsigned int yyy; /* set if changed, reset by media_changed */
- int users; /* keeps track of open/close */
- int lastsector; /* last block accessible */
- int status; /* last operation's error / status */
- int readerrs; /* # of blocks read w/o error */
- struct cdrom_device_info info;
- struct gendisk *disk;
-};
-
-
-/* Prototypes ******************************************************/
-
-/* The following prototypes are already declared elsewhere. They are
- repeated here to show what's going on. And to sense, if they're
- changed elsewhere. */
-
-static int mcdx_init(void);
-
-static int mcdx_block_open(struct inode *inode, struct file *file)
-{
- struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_open(&p->info, inode, file);
-}
-
-static int mcdx_block_release(struct inode *inode, struct file *file)
-{
- struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_release(&p->info, file);
-}
-
-static int mcdx_block_ioctl(struct inode *inode, struct file *file,
- unsigned cmd, unsigned long arg)
-{
- struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_ioctl(file, &p->info, inode, cmd, arg);
-}
-
-static int mcdx_block_media_changed(struct gendisk *disk)
-{
- struct s_drive_stuff *p = disk->private_data;
- return cdrom_media_changed(&p->info);
-}
-
-static struct block_device_operations mcdx_bdops =
-{
- .owner = THIS_MODULE,
- .open = mcdx_block_open,
- .release = mcdx_block_release,
- .ioctl = mcdx_block_ioctl,
- .media_changed = mcdx_block_media_changed,
-};
-
-
-/* Indirect exported functions. These functions are exported by their
- addresses, such as mcdx_open and mcdx_close in the
- structure mcdx_dops. */
-
-/* exported by file_ops */
-static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
-static void mcdx_close(struct cdrom_device_info *cdi);
-static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
-static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
-static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
-static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
- unsigned int cmd, void *arg);
-
-/* misc internal support functions */
-static void log2msf(unsigned int, struct cdrom_msf0 *);
-static unsigned int msf2log(const struct cdrom_msf0 *);
-static unsigned int uint2bcd(unsigned int);
-static unsigned int bcd2uint(unsigned char);
-static unsigned port(int *);
-static int irq(int *);
-static void mcdx_delay(struct s_drive_stuff *, long jifs);
-static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
- int nr_sectors);
-static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
- int nr_sectors);
-
-static int mcdx_config(struct s_drive_stuff *, int);
-static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
- int);
-static int mcdx_stop(struct s_drive_stuff *, int);
-static int mcdx_hold(struct s_drive_stuff *, int);
-static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
-static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
-static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
-static int mcdx_requestsubqcode(struct s_drive_stuff *,
- struct s_subqcode *, int);
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
- struct s_multi *, int);
-static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
- int);
-static int mcdx_getstatus(struct s_drive_stuff *, int);
-static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
-static int mcdx_talk(struct s_drive_stuff *,
- const unsigned char *cmd, size_t,
- void *buffer, size_t size, unsigned int timeout, int);
-static int mcdx_readtoc(struct s_drive_stuff *);
-static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
-static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
-static int mcdx_setattentuator(struct s_drive_stuff *,
- struct cdrom_volctrl *, int);
-
-/* static variables ************************************************/
-
-static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
-static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
-static DEFINE_SPINLOCK(mcdx_lock);
-static struct request_queue *mcdx_queue;
-
-/* You can only set the first two pairs, from old MODULE_PARM code. */
-static int mcdx_set(const char *val, struct kernel_param *kp)
-{
- get_options((char *)val, 4, (int *)mcdx_drive_map);
- return 0;
-}
-module_param_call(mcdx, mcdx_set, NULL, NULL, 0);
-
-static struct cdrom_device_ops mcdx_dops = {
- .open = mcdx_open,
- .release = mcdx_close,
- .media_changed = mcdx_media_changed,
- .tray_move = mcdx_tray_move,
- .lock_door = mcdx_lockdoor,
- .audio_ioctl = mcdx_audio_ioctl,
- .capability = CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
- CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
-};
-
-/* KERNEL INTERFACE FUNCTIONS **************************************/
-
-
-static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
- unsigned int cmd, void *arg)
-{
- struct s_drive_stuff *stuffp = cdi->handle;
-
- if (!stuffp->present)
- return -ENXIO;
-
- if (stuffp->xxx) {
- if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
- stuffp->lastsector = -1;
- } else {
- stuffp->lastsector = (CD_FRAMESIZE / 512)
- * msf2log(&stuffp->di.msf_leadout) - 1;
- }
-
- if (stuffp->toc) {
- kfree(stuffp->toc);
- stuffp->toc = NULL;
- if (-1 == mcdx_readtoc(stuffp))
- return -1;
- }
-
- stuffp->xxx = 0;
- }
-
- switch (cmd) {
- case CDROMSTART:{
- xtrace(IOCTL, "ioctl() START\n");
- /* Spin up the drive. Don't think we can do this.
- * For now, ignore it.
- */
- return 0;
- }
-
- case CDROMSTOP:{
- xtrace(IOCTL, "ioctl() STOP\n");
- stuffp->audiostatus = CDROM_AUDIO_INVALID;
- if (-1 == mcdx_stop(stuffp, 1))
- return -EIO;
- return 0;
- }
-
- case CDROMPLAYTRKIND:{
- struct cdrom_ti *ti = (struct cdrom_ti *) arg;
-
- xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
- if ((ti->cdti_trk0 < stuffp->di.n_first)
- || (ti->cdti_trk0 > stuffp->di.n_last)
- || (ti->cdti_trk1 < stuffp->di.n_first))
- return -EINVAL;
- if (ti->cdti_trk1 > stuffp->di.n_last)
- ti->cdti_trk1 = stuffp->di.n_last;
- xtrace(PLAYTRK, "ioctl() track %d to %d\n",
- ti->cdti_trk0, ti->cdti_trk1);
- return mcdx_playtrk(stuffp, ti);
- }
-
- case CDROMPLAYMSF:{
- struct cdrom_msf *msf = (struct cdrom_msf *) arg;
-
- xtrace(IOCTL, "ioctl() PLAYMSF\n");
-
- if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
- && (-1 == mcdx_hold(stuffp, 1)))
- return -EIO;
-
- msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
- msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
- msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
-
- msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
- msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
- msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
-
- stuffp->stop.dt.minute = msf->cdmsf_min1;
- stuffp->stop.dt.second = msf->cdmsf_sec1;
- stuffp->stop.dt.frame = msf->cdmsf_frame1;
-
- return mcdx_playmsf(stuffp, msf);
- }
-
- case CDROMRESUME:{
- xtrace(IOCTL, "ioctl() RESUME\n");
- return mcdx_playtrk(stuffp, NULL);
- }
-
- case CDROMREADTOCENTRY:{
- struct cdrom_tocentry *entry =
- (struct cdrom_tocentry *) arg;
- struct s_subqcode *tp = NULL;
- xtrace(IOCTL, "ioctl() READTOCENTRY\n");
-
- if (-1 == mcdx_readtoc(stuffp))
- return -1;
- if (entry->cdte_track == CDROM_LEADOUT)
- tp = &stuffp->toc[stuffp->di.n_last -
- stuffp->di.n_first + 1];
- else if (entry->cdte_track > stuffp->di.n_last
- || entry->cdte_track < stuffp->di.n_first)
- return -EINVAL;
- else
- tp = &stuffp->toc[entry->cdte_track -
- stuffp->di.n_first];
-
- if (NULL == tp)
- return -EIO;
- entry->cdte_adr = tp->control;
- entry->cdte_ctrl = tp->control >> 4;
- /* Always return stuff in MSF, and let the Uniform cdrom driver
- worry about what the user actually wants */
- entry->cdte_addr.msf.minute =
- bcd2uint(tp->dt.minute);
- entry->cdte_addr.msf.second =
- bcd2uint(tp->dt.second);
- entry->cdte_addr.msf.frame =
- bcd2uint(tp->dt.frame);
- return 0;
- }
-
- case CDROMSUBCHNL:{
- struct cdrom_subchnl *sub =
- (struct cdrom_subchnl *) arg;
- struct s_subqcode q;
-
- xtrace(IOCTL, "ioctl() SUBCHNL\n");
-
- if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
- return -EIO;
-
- xtrace(SUBCHNL, "audiostatus: %x\n",
- stuffp->audiostatus);
- sub->cdsc_audiostatus = stuffp->audiostatus;
- sub->cdsc_adr = q.control;
- sub->cdsc_ctrl = q.control >> 4;
- sub->cdsc_trk = bcd2uint(q.tno);
- sub->cdsc_ind = bcd2uint(q.index);
-
- xtrace(SUBCHNL, "trk %d, ind %d\n",
- sub->cdsc_trk, sub->cdsc_ind);
- /* Always return stuff in MSF, and let the Uniform cdrom driver
- worry about what the user actually wants */
- sub->cdsc_absaddr.msf.minute =
- bcd2uint(q.dt.minute);
- sub->cdsc_absaddr.msf.second =
- bcd2uint(q.dt.second);
- sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
- sub->cdsc_reladdr.msf.minute =
- bcd2uint(q.tt.minute);
- sub->cdsc_reladdr.msf.second =
- bcd2uint(q.tt.second);
- sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
- xtrace(SUBCHNL,
- "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
- sub->cdsc_absaddr.msf.minute,
- sub->cdsc_absaddr.msf.second,
- sub->cdsc_absaddr.msf.frame,
- sub->cdsc_reladdr.msf.minute,
- sub->cdsc_reladdr.msf.second,
- sub->cdsc_reladdr.msf.frame);
-
- return 0;
- }
-
- case CDROMREADTOCHDR:{
- struct cdrom_tochdr *toc =
- (struct cdrom_tochdr *) arg;
-
- xtrace(IOCTL, "ioctl() READTOCHDR\n");
- toc->cdth_trk0 = stuffp->di.n_first;
- toc->cdth_trk1 = stuffp->di.n_last;
- xtrace(TOCHDR,
- "ioctl() track0 = %d, track1 = %d\n",
- stuffp->di.n_first, stuffp->di.n_last);
- return 0;
- }
-
- case CDROMPAUSE:{
- xtrace(IOCTL, "ioctl() PAUSE\n");
- if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
- return -EINVAL;
- if (-1 == mcdx_stop(stuffp, 1))
- return -EIO;
- stuffp->audiostatus = CDROM_AUDIO_PAUSED;
- if (-1 ==
- mcdx_requestsubqcode(stuffp, &stuffp->start,
- 1))
- return -EIO;
- return 0;
- }
-
- case CDROMMULTISESSION:{
- struct cdrom_multisession *ms =
- (struct cdrom_multisession *) arg;
- xtrace(IOCTL, "ioctl() MULTISESSION\n");
- /* Always return stuff in LBA, and let the Uniform cdrom driver
- worry about what the user actually wants */
- ms->addr.lba = msf2log(&stuffp->multi.msf_last);
- ms->xa_flag = !!stuffp->multi.multi;
- xtrace(MS,
- "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
- ms->xa_flag, ms->addr.lba,
- stuffp->multi.msf_last.minute,
- stuffp->multi.msf_last.second,
- stuffp->multi.msf_last.frame);
-
- return 0;
- }
-
- case CDROMEJECT:{
- xtrace(IOCTL, "ioctl() EJECT\n");
- if (stuffp->users > 1)
- return -EBUSY;
- return (mcdx_tray_move(cdi, 1));
- }
-
- case CDROMCLOSETRAY:{
- xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
- return (mcdx_tray_move(cdi, 0));
- }
-
- case CDROMVOLCTRL:{
- struct cdrom_volctrl *volctrl =
- (struct cdrom_volctrl *) arg;
- xtrace(IOCTL, "ioctl() VOLCTRL\n");
-
-#if 0 /* not tested! */
- /* adjust for the weirdness of workman (md) */
- /* can't test it (hs) */
- volctrl.channel2 = volctrl.channel1;
- volctrl.channel1 = volctrl.channel3 = 0x00;
-#endif
- return mcdx_setattentuator(stuffp, volctrl, 2);
- }
-
- default:
- return -EINVAL;
- }
-}
-
-static void do_mcdx_request(request_queue_t * q)
-{
- struct s_drive_stuff *stuffp;
- struct request *req;
-
- again:
-
- req = elv_next_request(q);
- if (!req)
- return;
-
- stuffp = req->rq_disk->private_data;
-
- if (!stuffp->present) {
- xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
- xtrace(REQUEST, "end_request(0): bad device\n");
- end_request(req, 0);
- return;
- }
-
- if (stuffp->audio) {
- xwarn("do_request() attempt to read from audio cd\n");
- xtrace(REQUEST, "end_request(0): read from audio\n");
- end_request(req, 0);
- return;
- }
-
- xtrace(REQUEST, "do_request() (%lu + %lu)\n",
- req->sector, req->nr_sectors);
-
- if (req->cmd != READ) {
- xwarn("do_request(): non-read command to cd!!\n");
- xtrace(REQUEST, "end_request(0): write\n");
- end_request(req, 0);
- return;
- }
- else {
- stuffp->status = 0;
- while (req->nr_sectors) {
- int i;
-
- i = mcdx_transfer(stuffp,
- req->buffer,
- req->sector,
- req->nr_sectors);
-
- if (i == -1) {
- end_request(req, 0);
- goto again;
- }
- req->sector += i;
- req->nr_sectors -= i;
- req->buffer += (i * 512);
- }
- end_request(req, 1);
- goto again;
-
- xtrace(REQUEST, "end_request(1)\n");
- end_request(req, 1);
- }
-
- goto again;
-}
-
-static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
-{
- struct s_drive_stuff *stuffp;
- xtrace(OPENCLOSE, "open()\n");
- stuffp = cdi->handle;
- if (!stuffp->present)
- return -ENXIO;
-
- /* Make the modules looking used ... (thanx bjorn).
- * But we shouldn't forget to decrement the module counter
- * on error return */
-
- /* this is only done to test if the drive talks with us */
- if (-1 == mcdx_getstatus(stuffp, 1))
- return -EIO;
-
- if (stuffp->xxx) {
-
- xtrace(OPENCLOSE, "open() media changed\n");
- stuffp->audiostatus = CDROM_AUDIO_INVALID;
- stuffp->readcmd = 0;
- xtrace(OPENCLOSE, "open() Request multisession info\n");
- if (-1 ==
- mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
- xinfo("No multidiskinfo\n");
- } else {
- /* multisession ? */
- if (!stuffp->multi.multi)
- stuffp->multi.msf_last.second = 2;
-
- xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
- stuffp->multi.multi,
- stuffp->multi.msf_last.minute,
- stuffp->multi.msf_last.second,
- stuffp->multi.msf_last.frame);
-
- {;
- } /* got multisession information */
- /* request the disks table of contents (aka diskinfo) */
- if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
-
- stuffp->lastsector = -1;
-
- } else {
-
- stuffp->lastsector = (CD_FRAMESIZE / 512)
- * msf2log(&stuffp->di.msf_leadout) - 1;
-
- xtrace(OPENCLOSE,
- "open() start %d (%02x:%02x.%02x) %d\n",
- stuffp->di.n_first,
- stuffp->di.msf_first.minute,
- stuffp->di.msf_first.second,
- stuffp->di.msf_first.frame,
- msf2log(&stuffp->di.msf_first));
- xtrace(OPENCLOSE,
- "open() last %d (%02x:%02x.%02x) %d\n",
- stuffp->di.n_last,
- stuffp->di.msf_leadout.minute,
- stuffp->di.msf_leadout.second,
- stuffp->di.msf_leadout.frame,
- msf2log(&stuffp->di.msf_leadout));
- }
-
- if (stuffp->toc) {
- xtrace(MALLOC, "open() free old toc @ %p\n",
- stuffp->toc);
- kfree(stuffp->toc);
-
- stuffp->toc = NULL;
- }
-
- xtrace(OPENCLOSE, "open() init irq generation\n");
- if (-1 == mcdx_config(stuffp, 1))
- return -EIO;
-#ifdef FALLBACK
- /* Set the read speed */
- xwarn("AAA %x AAA\n", stuffp->readcmd);
- if (stuffp->readerrs)
- stuffp->readcmd = READ1X;
- else
- stuffp->readcmd =
- stuffp->present | SINGLE ? READ1X : READ2X;
- xwarn("XXX %x XXX\n", stuffp->readcmd);
-#else
- stuffp->readcmd =
- stuffp->present | SINGLE ? READ1X : READ2X;
-#endif
-
- /* try to get the first sector, iff any ... */
- if (stuffp->lastsector >= 0) {
- char buf[512];
- int ans;
- int tries;
-
- stuffp->xa = 0;
- stuffp->audio = 0;
-
- for (tries = 6; tries; tries--) {
-
- stuffp->introk = 1;
-
- xtrace(OPENCLOSE, "open() try as %s\n",
- stuffp->xa ? "XA" : "normal");
- /* set data mode */
- if (-1 == (ans = mcdx_setdatamode(stuffp,
- stuffp->
- xa ?
- MODE2 :
- MODE1,
- 1))) {
- /* return -EIO; */
- stuffp->xa = 0;
- break;
- }
-
- if ((stuffp->audio = e_audio(ans)))
- break;
-
- while (0 ==
- (ans =
- mcdx_transfer(stuffp, buf, 0, 1)));
-
- if (ans == 1)
- break;
- stuffp->xa = !stuffp->xa;
- }
- }
- /* xa disks will be read in raw mode, others not */
- if (-1 == mcdx_setdrivemode(stuffp,
- stuffp->xa ? RAW : COOKED,
- 1))
- return -EIO;
- if (stuffp->audio) {
- xinfo("open() audio disk found\n");
- } else if (stuffp->lastsector >= 0) {
- xinfo("open() %s%s disk found\n",
- stuffp->xa ? "XA / " : "",
- stuffp->multi.
- multi ? "Multi Session" : "Single Session");
- }
- }
- stuffp->xxx = 0;
- stuffp->users++;
- return 0;
-}
-
-static void mcdx_close(struct cdrom_device_info *cdi)
-{
- struct s_drive_stuff *stuffp;
-
- xtrace(OPENCLOSE, "close()\n");
-
- stuffp = cdi->handle;
-
- --stuffp->users;
-}
-
-static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-/* Return: 1 if media changed since last call to this function
- 0 otherwise */
-{
- struct s_drive_stuff *stuffp;
-
- xinfo("mcdx_media_changed called for device %s\n", cdi->name);
-
- stuffp = cdi->handle;
- mcdx_getstatus(stuffp, 1);
-
- if (stuffp->yyy == 0)
- return 0;
-
- stuffp->yyy = 0;
- return 1;
-}
-
-#ifndef MODULE
-static int __init mcdx_setup(char *str)
-{
- int pi[4];
- (void) get_options(str, ARRAY_SIZE(pi), pi);
-
- if (pi[0] > 0)
- mcdx_drive_map[0][0] = pi[1];
- if (pi[0] > 1)
- mcdx_drive_map[0][1] = pi[2];
- return 1;
-}
-
-__setup("mcdx=", mcdx_setup);
-
-#endif
-
-/* DIRTY PART ******************************************************/
-
-static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
-/* This routine is used for sleeping.
- * A jifs value <0 means NO sleeping,
- * =0 means minimal sleeping (let the kernel
- * run for other processes)
- * >0 means at least sleep for that amount.
- * May be we could use a simple count loop w/ jumps to itself, but
- * I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
-{
- if (jifs < 0)
- return;
-
- xtrace(SLEEP, "*** delay: sleepq\n");
- interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
- xtrace(SLEEP, "delay awoken\n");
- if (signal_pending(current)) {
- xtrace(SLEEP, "got signal\n");
- }
-}
-
-static irqreturn_t mcdx_intr(int irq, void *dev_id)
-{
- struct s_drive_stuff *stuffp = dev_id;
- unsigned char b;
-
-#ifdef AK2
- if (!stuffp->busy && stuffp->pending)
- stuffp->int_err = 1;
-
-#endif /* AK2 */
- /* get the interrupt status */
- b = inb(stuffp->rreg_status);
- stuffp->introk = ~b & MCDX_RBIT_DTEN;
-
- /* NOTE: We only should get interrupts if the data we
- * requested are ready to transfer.
- * But the drive seems to generate ``asynchronous'' interrupts
- * on several error conditions too. (Despite the err int enable
- * setting during initialisation) */
-
- /* if not ok, read the next byte as the drives status */
- if (!stuffp->introk) {
- xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
- if (~b & MCDX_RBIT_STEN) {
- xinfo("intr() irq %d status 0x%02x\n",
- irq, inb(stuffp->rreg_data));
- } else {
- xinfo("intr() irq %d ambiguous hw status\n", irq);
- }
- } else {
- xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
- }
-
- stuffp->busy = 0;
- wake_up_interruptible(&stuffp->busyq);
- return IRQ_HANDLED;
-}
-
-
-static int mcdx_talk(struct s_drive_stuff *stuffp,
- const unsigned char *cmd, size_t cmdlen,
- void *buffer, size_t size, unsigned int timeout, int tries)
-/* Send a command to the drive, wait for the result.
- * returns -1 on timeout, drive status otherwise
- * If buffer is not zero, the result (length size) is stored there.
- * If buffer is zero the size should be the number of bytes to read
- * from the drive. These bytes are discarded.
- */
-{
- int st;
- char c;
- int discard;
-
- /* Somebody wants the data read? */
- if ((discard = (buffer == NULL)))
- buffer = &c;
-
- while (stuffp->lock) {
- xtrace(SLEEP, "*** talk: lockq\n");
- interruptible_sleep_on(&stuffp->lockq);
- xtrace(SLEEP, "talk: awoken\n");
- }
-
- stuffp->lock = 1;
-
- /* An operation other then reading data destroys the
- * data already requested and remembered in stuffp->request, ... */
- stuffp->valid = 0;
-
-#if MCDX_DEBUG & TALK
- {
- unsigned char i;
- xtrace(TALK,
- "talk() %d / %d tries, res.size %d, command 0x%02x",
- tries, timeout, size, (unsigned char) cmd[0]);
- for (i = 1; i < cmdlen; i++)
- xtrace(TALK, " 0x%02x", cmd[i]);
- xtrace(TALK, "\n");
- }
-#endif
-
- /* give up if all tries are done (bad) or if the status
- * st != -1 (good) */
- for (st = -1; st == -1 && tries; tries--) {
-
- char *bp = (char *) buffer;
- size_t sz = size;
-
- outsb(stuffp->wreg_data, cmd, cmdlen);
- xtrace(TALK, "talk() command sent\n");
-
- /* get the status byte */
- if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
- xinfo("talk() %02x timed out (status), %d tr%s left\n",
- cmd[0], tries - 1, tries == 2 ? "y" : "ies");
- continue;
- }
- st = *bp;
- sz--;
- if (!discard)
- bp++;
-
- xtrace(TALK, "talk() got status 0x%02x\n", st);
-
- /* command error? */
- if (e_cmderr(st)) {
- xwarn("command error cmd = %02x %s \n",
- cmd[0], cmdlen > 1 ? "..." : "");
- st = -1;
- continue;
- }
-
- /* audio status? */
- if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
- stuffp->audiostatus =
- e_audiobusy(st) ? CDROM_AUDIO_PLAY :
- CDROM_AUDIO_NO_STATUS;
- else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
- && e_audiobusy(st) == 0)
- stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
-
- /* media change? */
- if (e_changed(st)) {
- xinfo("talk() media changed\n");
- stuffp->xxx = stuffp->yyy = 1;
- }
-
- /* now actually get the data */
- while (sz--) {
- if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
- xinfo("talk() %02x timed out (data), %d tr%s left\n",
- cmd[0], tries - 1,
- tries == 2 ? "y" : "ies");
- st = -1;
- break;
- }
- if (!discard)
- bp++;
- xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
- }
- }
-
-#if !MCDX_QUIET
- if (!tries && st == -1)
- xinfo("talk() giving up\n");
-#endif
-
- stuffp->lock = 0;
- wake_up_interruptible(&stuffp->lockq);
-
- xtrace(TALK, "talk() done with 0x%02x\n", st);
- return st;
-}
-
-/* MODULE STUFF ***********************************************************/
-
-static int __init __mcdx_init(void)
-{
- int i;
- int drives = 0;
-
- mcdx_init();
- for (i = 0; i < MCDX_NDRIVES; i++) {
- if (mcdx_stuffp[i]) {
- xtrace(INIT, "init_module() drive %d stuff @ %p\n",
- i, mcdx_stuffp[i]);
- drives++;
- }
- }
-
- if (!drives)
- return -EIO;
-
- return 0;
-}
-
-static void __exit mcdx_exit(void)
-{
- int i;
-
- xinfo("cleanup_module called\n");
-
- for (i = 0; i < MCDX_NDRIVES; i++) {
- struct s_drive_stuff *stuffp = mcdx_stuffp[i];
- if (!stuffp)
- continue;
- del_gendisk(stuffp->disk);
- if (unregister_cdrom(&stuffp->info)) {
- printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
- continue;
- }
- put_disk(stuffp->disk);
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- free_irq(stuffp->irq, NULL);
- if (stuffp->toc) {
- xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
- stuffp->toc);
- kfree(stuffp->toc);
- }
- xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
- stuffp);
- mcdx_stuffp[i] = NULL;
- kfree(stuffp);
- }
-
- if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
- xwarn("cleanup() unregister_blkdev() failed\n");
- }
-#if !MCDX_QUIET
- else
- xinfo("cleanup() succeeded\n");
-#endif
- blk_cleanup_queue(mcdx_queue);
-}
-
-#ifdef MODULE
-module_init(__mcdx_init);
-#endif
-module_exit(mcdx_exit);
-
-
-/* Support functions ************************************************/
-
-static int __init mcdx_init_drive(int drive)
-{
- struct s_version version;
- struct gendisk *disk;
- struct s_drive_stuff *stuffp;
- int size = sizeof(*stuffp);
- char msg[80];
-
- xtrace(INIT, "init() try drive %d\n", drive);
-
- xtrace(INIT, "kmalloc space for stuffpt's\n");
- xtrace(MALLOC, "init() malloc %d bytes\n", size);
- if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
- xwarn("init() malloc failed\n");
- return 1;
- }
-
- disk = alloc_disk(1);
- if (!disk) {
- xwarn("init() malloc failed\n");
- kfree(stuffp);
- return 1;
- }
-
- xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
- sizeof(*stuffp), stuffp);
-
- /* set default values */
- stuffp->present = 0; /* this should be 0 already */
- stuffp->toc = NULL; /* this should be NULL already */
-
- /* setup our irq and i/o addresses */
- stuffp->irq = irq(mcdx_drive_map[drive]);
- stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
- stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
- stuffp->wreg_hcon = stuffp->wreg_reset + 1;
- stuffp->wreg_chn = stuffp->wreg_hcon + 1;
-
- init_waitqueue_head(&stuffp->busyq);
- init_waitqueue_head(&stuffp->lockq);
- init_waitqueue_head(&stuffp->sleepq);
-
- /* check if i/o addresses are available */
- if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
- xwarn("0x%03x,%d: Init failed. "
- "I/O ports (0x%03x..0x%03x) already in use.\n",
- stuffp->wreg_data, stuffp->irq,
- stuffp->wreg_data,
- stuffp->wreg_data + MCDX_IO_SIZE - 1);
- xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
- kfree(stuffp);
- put_disk(disk);
- xtrace(INIT, "init() continue at next drive\n");
- return 0; /* next drive */
- }
-
- xtrace(INIT, "init() i/o port is available at 0x%03x\n"
- stuffp->wreg_data);
- xtrace(INIT, "init() hardware reset\n");
- mcdx_reset(stuffp, HARD, 1);
-
- xtrace(INIT, "init() get version\n");
- if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
- /* failed, next drive */
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n",
- MCDX, stuffp->wreg_data, stuffp->irq);
- xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
- kfree(stuffp);
- put_disk(disk);
- xtrace(INIT, "init() continue at next drive\n");
- return 0;
- }
-
- switch (version.code) {
- case 'D':
- stuffp->readcmd = READ2X;
- stuffp->present = DOUBLE | DOOR | MULTI;
- break;
- case 'F':
- stuffp->readcmd = READ1X;
- stuffp->present = SINGLE | DOOR | MULTI;
- break;
- case 'M':
- stuffp->readcmd = READ1X;
- stuffp->present = SINGLE;
- break;
- default:
- stuffp->present = 0;
- break;
- }
-
- stuffp->playcmd = READ1X;
-
- if (!stuffp->present) {
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n",
- MCDX, stuffp->wreg_data, stuffp->irq);
- kfree(stuffp);
- put_disk(disk);
- return 0; /* next drive */
- }
-
- xtrace(INIT, "init() register blkdev\n");
- if (register_blkdev(MAJOR_NR, "mcdx")) {
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- kfree(stuffp);
- put_disk(disk);
- return 1;
- }
-
- mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock);
- if (!mcdx_queue) {
- unregister_blkdev(MAJOR_NR, "mcdx");
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- kfree(stuffp);
- put_disk(disk);
- return 1;
- }
-
- xtrace(INIT, "init() subscribe irq and i/o\n");
- if (request_irq(stuffp->irq, mcdx_intr, IRQF_DISABLED, "mcdx", stuffp)) {
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n",
- MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
- stuffp->irq = 0;
- blk_cleanup_queue(mcdx_queue);
- kfree(stuffp);
- put_disk(disk);
- return 0;
- }
-
- xtrace(INIT, "init() get garbage\n");
- {
- int i;
- mcdx_delay(stuffp, HZ / 2);
- for (i = 100; i; i--)
- (void) inb(stuffp->rreg_status);
- }
-
-
-#ifdef WE_KNOW_WHY
- /* irq 11 -> channel register */
- outb(0x50, stuffp->wreg_chn);
-#endif
-
- xtrace(INIT, "init() set non dma but irq mode\n");
- mcdx_config(stuffp, 1);
-
- stuffp->info.ops = &mcdx_dops;
- stuffp->info.speed = 2;
- stuffp->info.capacity = 1;
- stuffp->info.handle = stuffp;
- sprintf(stuffp->info.name, "mcdx%d", drive);
- disk->major = MAJOR_NR;
- disk->first_minor = drive;
- strcpy(disk->disk_name, stuffp->info.name);
- disk->fops = &mcdx_bdops;
- disk->flags = GENHD_FL_CD;
- stuffp->disk = disk;
-
- sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d."
- " (Firmware version %c %x)\n",
- stuffp->wreg_data, stuffp->irq, version.code, version.ver);
- mcdx_stuffp[drive] = stuffp;
- xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
- if (register_cdrom(&stuffp->info) != 0) {
- printk("Cannot register Mitsumi CD-ROM!\n");
- free_irq(stuffp->irq, NULL);
- release_region(stuffp->wreg_data, MCDX_IO_SIZE);
- kfree(stuffp);
- put_disk(disk);
- if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
- xwarn("cleanup() unregister_blkdev() failed\n");
- blk_cleanup_queue(mcdx_queue);
- return 2;
- }
- disk->private_data = stuffp;
- disk->queue = mcdx_queue;
- add_disk(disk);
- printk(msg);
- return 0;
-}
-
-static int __init mcdx_init(void)
-{
- int drive;
- xwarn("Version 2.14(hs) \n");
-
- xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");
-
- /* zero the pointer array */
- for (drive = 0; drive < MCDX_NDRIVES; drive++)
- mcdx_stuffp[drive] = NULL;
-
- /* do the initialisation */
- for (drive = 0; drive < MCDX_NDRIVES; drive++) {
- switch (mcdx_init_drive(drive)) {
- case 2:
- return -EIO;
- case 1:
- break;
- }
- }
- return 0;
-}
-
-static int mcdx_transfer(struct s_drive_stuff *stuffp,
- char *p, int sector, int nr_sectors)
-/* This seems to do the actually transfer. But it does more. It
- keeps track of errors occurred and will (if possible) fall back
- to single speed on error.
- Return: -1 on timeout or other error
- else status byte (as in stuff->st) */
-{
- int ans;
-
- ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
- return ans;
-#ifdef FALLBACK
- if (-1 == ans)
- stuffp->readerrs++;
- else
- return ans;
-
- if (stuffp->readerrs && stuffp->readcmd == READ1X) {
- xwarn("XXX Already reading 1x -- no chance\n");
- return -1;
- }
-
- xwarn("XXX Fallback to 1x\n");
-
- stuffp->readcmd = READ1X;
- return mcdx_transfer(stuffp, p, sector, nr_sectors);
-#endif
-
-}
-
-
-static int mcdx_xfer(struct s_drive_stuff *stuffp,
- char *p, int sector, int nr_sectors)
-/* This does actually the transfer from the drive.
- Return: -1 on timeout or other error
- else status byte (as in stuff->st) */
-{
- int border;
- int done = 0;
- long timeout;
-
- if (stuffp->audio) {
- xwarn("Attempt to read from audio CD.\n");
- return -1;
- }
-
- if (!stuffp->readcmd) {
- xinfo("Can't transfer from missing disk.\n");
- return -1;
- }
-
- while (stuffp->lock) {
- interruptible_sleep_on(&stuffp->lockq);
- }
-
- if (stuffp->valid && (sector >= stuffp->pending)
- && (sector < stuffp->low_border)) {
-
- /* All (or at least a part of the sectors requested) seems
- * to be already requested, so we don't need to bother the
- * drive with new requests ...
- * Wait for the drive become idle, but first
- * check for possible occurred errors --- the drive
- * seems to report them asynchronously */
-
-
- border = stuffp->high_border < (border =
- sector + nr_sectors)
- ? stuffp->high_border : border;
-
- stuffp->lock = current->pid;
-
- do {
-
- while (stuffp->busy) {
-
- timeout =
- interruptible_sleep_on_timeout
- (&stuffp->busyq, 5 * HZ);
-
- if (!stuffp->introk) {
- xtrace(XFER,
- "error via interrupt\n");
- } else if (!timeout) {
- xtrace(XFER, "timeout\n");
- } else if (signal_pending(current)) {
- xtrace(XFER, "signal\n");
- } else
- continue;
-
- stuffp->lock = 0;
- stuffp->busy = 0;
- stuffp->valid = 0;
-
- wake_up_interruptible(&stuffp->lockq);
- xtrace(XFER, "transfer() done (-1)\n");
- return -1;
- }
-
- /* check if we need to set the busy flag (as we
- * expect an interrupt */
- stuffp->busy = (3 == (stuffp->pending & 3));
-
- /* Test if it's the first sector of a block,
- * there we have to skip some bytes as we read raw data */
- if (stuffp->xa && (0 == (stuffp->pending & 3))) {
- const int HEAD =
- CD_FRAMESIZE_RAW - CD_XA_TAIL -
- CD_FRAMESIZE;
- insb(stuffp->rreg_data, p, HEAD);
- }
-
- /* now actually read the data */
- insb(stuffp->rreg_data, p, 512);
-
- /* test if it's the last sector of a block,
- * if so, we have to handle XA special */
- if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
- char dummy[CD_XA_TAIL];
- insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
- }
-
- if (stuffp->pending == sector) {
- p += 512;
- done++;
- sector++;
- }
- } while (++(stuffp->pending) < border);
-
- stuffp->lock = 0;
- wake_up_interruptible(&stuffp->lockq);
-
- } else {
-
- /* The requested sector(s) is/are out of the
- * already requested range, so we have to bother the drive
- * with a new request. */
-
- static unsigned char cmd[] = {
- 0,
- 0, 0, 0,
- 0, 0, 0
- };
-
- cmd[0] = stuffp->readcmd;
-
- /* The numbers held in ->pending, ..., should be valid */
- stuffp->valid = 1;
- stuffp->pending = sector & ~3;
-
- /* do some sanity checks */
- if (stuffp->pending > stuffp->lastsector) {
- xwarn
- ("transfer() sector %d from nirvana requested.\n",
- stuffp->pending);
- stuffp->status = MCDX_ST_EOM;
- stuffp->valid = 0;
- xtrace(XFER, "transfer() done (-1)\n");
- return -1;
- }
-
- if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
- > stuffp->lastsector + 1) {
- xtrace(XFER, "cut low_border\n");
- stuffp->low_border = stuffp->lastsector + 1;
- }
- if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
- > stuffp->lastsector + 1) {
- xtrace(XFER, "cut high_border\n");
- stuffp->high_border = stuffp->lastsector + 1;
- }
-
- { /* Convert the sector to be requested to MSF format */
- struct cdrom_msf0 pending;
- log2msf(stuffp->pending / 4, &pending);
- cmd[1] = pending.minute;
- cmd[2] = pending.second;
- cmd[3] = pending.frame;
- }
-
- cmd[6] =
- (unsigned
- char) ((stuffp->high_border - stuffp->pending) / 4);
- xtrace(XFER, "[%2d]\n", cmd[6]);
-
- stuffp->busy = 1;
- /* Now really issue the request command */
- outsb(stuffp->wreg_data, cmd, sizeof cmd);
-
- }
-#ifdef AK2
- if (stuffp->int_err) {
- stuffp->valid = 0;
- stuffp->int_err = 0;
- return -1;
- }
-#endif /* AK2 */
-
- stuffp->low_border = (stuffp->low_border +=
- done) <
- stuffp->high_border ? stuffp->low_border : stuffp->high_border;
-
- return done;
-}
-
-
-/* Access to elements of the mcdx_drive_map members */
-
-static unsigned port(int *ip)
-{
- return ip[0];
-}
-static int irq(int *ip)
-{
- return ip[1];
-}
-
-/* Misc number converters */
-
-static unsigned int bcd2uint(unsigned char c)
-{
- return (c >> 4) * 10 + (c & 0x0f);
-}
-
-static unsigned int uint2bcd(unsigned int ival)
-{
- return ((ival / 10) << 4) | (ival % 10);
-}
-
-static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
-{
- l += CD_MSF_OFFSET;
- pmsf->minute = uint2bcd(l / 4500), l %= 4500;
- pmsf->second = uint2bcd(l / 75);
- pmsf->frame = uint2bcd(l % 75);
-}
-
-static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
-{
- return bcd2uint(pmsf->frame)
- + bcd2uint(pmsf->second) * 75
- + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
-}
-
-int mcdx_readtoc(struct s_drive_stuff *stuffp)
-/* Read the toc entries from the CD,
- * Return: -1 on failure, else 0 */
-{
-
- if (stuffp->toc) {
- xtrace(READTOC, "ioctl() toc already read\n");
- return 0;
- }
-
- xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
- stuffp->di.n_last - stuffp->di.n_first + 1);
-
- if (-1 == mcdx_hold(stuffp, 1))
- return -1;
-
- xtrace(READTOC, "ioctl() tocmode\n");
- if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
- return -EIO;
-
- /* all seems to be ok so far ... malloc */
- {
- int size;
- size =
- sizeof(struct s_subqcode) * (stuffp->di.n_last -
- stuffp->di.n_first + 2);
-
- xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
- stuffp->toc = kmalloc(size, GFP_KERNEL);
- if (!stuffp->toc) {
- xwarn("Cannot malloc %d bytes for toc\n", size);
- mcdx_setdrivemode(stuffp, DATA, 1);
- return -EIO;
- }
- }
-
- /* now read actually the index */
- {
- int trk;
- int retries;
-
- for (trk = 0;
- trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
- trk++)
- stuffp->toc[trk].index = 0;
-
- for (retries = 300; retries; retries--) { /* why 300? */
- struct s_subqcode q;
- unsigned int idx;
-
- if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) {
- mcdx_setdrivemode(stuffp, DATA, 1);
- return -EIO;
- }
-
- idx = bcd2uint(q.index);
-
- if ((idx > 0)
- && (idx <= stuffp->di.n_last)
- && (q.tno == 0)
- && (stuffp->toc[idx - stuffp->di.n_first].
- index == 0)) {
- stuffp->toc[idx - stuffp->di.n_first] = q;
- xtrace(READTOC,
- "ioctl() toc idx %d (trk %d)\n",
- idx, trk);
- trk--;
- }
- if (trk == 0)
- break;
- }
- memset(&stuffp->
- toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
- sizeof(stuffp->toc[0]));
- stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
- 1].dt = stuffp->di.msf_leadout;
- }
-
- /* unset toc mode */
- xtrace(READTOC, "ioctl() undo toc mode\n");
- if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
- return -EIO;
-
-#if MCDX_DEBUG && READTOC
- {
- int trk;
- for (trk = 0;
- trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
- trk++)
- xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
- " %02x:%02x.%02x %02x:%02x.%02x\n",
- trk + stuffp->di.n_first,
- stuffp->toc[trk].control,
- stuffp->toc[trk].tno,
- stuffp->toc[trk].index,
- stuffp->toc[trk].tt.minute,
- stuffp->toc[trk].tt.second,
- stuffp->toc[trk].tt.frame,
- stuffp->toc[trk].dt.minute,
- stuffp->toc[trk].dt.second,
- stuffp->toc[trk].dt.frame);
- }
-#endif
-
- return 0;
-}
-
-static int
-mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
-{
- unsigned char cmd[7] = {
- 0, 0, 0, 0, 0, 0, 0
- };
-
- if (!stuffp->readcmd) {
- xinfo("Can't play from missing disk.\n");
- return -1;
- }
-
- cmd[0] = stuffp->playcmd;
-
- cmd[1] = msf->cdmsf_min0;
- cmd[2] = msf->cdmsf_sec0;
- cmd[3] = msf->cdmsf_frame0;
- cmd[4] = msf->cdmsf_min1;
- cmd[5] = msf->cdmsf_sec1;
- cmd[6] = msf->cdmsf_frame1;
-
- xtrace(PLAYMSF, "ioctl(): play %x "
- "%02x:%02x:%02x -- %02x:%02x:%02x\n",
- cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
-
- outsb(stuffp->wreg_data, cmd, sizeof cmd);
-
- if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
- xwarn("playmsf() timeout\n");
- return -1;
- }
-
- stuffp->audiostatus = CDROM_AUDIO_PLAY;
- return 0;
-}
-
-static int
-mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
-{
- struct s_subqcode *p;
- struct cdrom_msf msf;
-
- if (-1 == mcdx_readtoc(stuffp))
- return -1;
-
- if (ti)
- p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
- else
- p = &stuffp->start;
-
- msf.cdmsf_min0 = p->dt.minute;
- msf.cdmsf_sec0 = p->dt.second;
- msf.cdmsf_frame0 = p->dt.frame;
-
- if (ti) {
- p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
- stuffp->stop = *p;
- } else
- p = &stuffp->stop;
-
- msf.cdmsf_min1 = p->dt.minute;
- msf.cdmsf_sec1 = p->dt.second;
- msf.cdmsf_frame1 = p->dt.frame;
-
- return mcdx_playmsf(stuffp, &msf);
-}
-
-
-/* Drive functions ************************************************/
-
-static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
-{
- struct s_drive_stuff *stuffp = cdi->handle;
-
- if (!stuffp->present)
- return -ENXIO;
- if (!(stuffp->present & DOOR))
- return -ENOSYS;
-
- if (position) /* 1: eject */
- return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
- else /* 0: close */
- return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
- return 1;
-}
-
-static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
-{
- return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
-}
-
-static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
-{
- return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
-}
-
-static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
- struct s_subqcode *sub, int tries)
-{
- char buf[11];
- int ans;
-
- if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
- 2 * HZ, tries)))
- return -1;
- sub->control = buf[1];
- sub->tno = buf[2];
- sub->index = buf[3];
- sub->tt.minute = buf[4];
- sub->tt.second = buf[5];
- sub->tt.frame = buf[6];
- sub->dt.minute = buf[8];
- sub->dt.second = buf[9];
- sub->dt.frame = buf[10];
-
- return ans;
-}
-
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
- struct s_multi *multi, int tries)
-{
- char buf[5];
- int ans;
-
- if (stuffp->present & MULTI) {
- ans =
- mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
- tries);
- multi->multi = buf[1];
- multi->msf_last.minute = buf[2];
- multi->msf_last.second = buf[3];
- multi->msf_last.frame = buf[4];
- return ans;
- } else {
- multi->multi = 0;
- return 0;
- }
-}
-
-static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
- int tries)
-{
- char buf[9];
- int ans;
- ans =
- mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
- if (ans == -1) {
- info->n_first = 0;
- info->n_last = 0;
- } else {
- info->n_first = bcd2uint(buf[1]);
- info->n_last = bcd2uint(buf[2]);
- info->msf_leadout.minute = buf[3];
- info->msf_leadout.second = buf[4];
- info->msf_leadout.frame = buf[5];
- info->msf_first.minute = buf[6];
- info->msf_first.second = buf[7];
- info->msf_first.frame = buf[8];
- }
- return ans;
-}
-
-static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
- int tries)
-{
- char cmd[2];
- int ans;
-
- xtrace(HW, "setdrivemode() %d\n", mode);
-
- if (-1 == (ans = mcdx_talk(stuffp, "\xc2", 1, cmd, sizeof(cmd), 5 * HZ, tries)))
- return -1;
-
- switch (mode) {
- case TOC:
- cmd[1] |= 0x04;
- break;
- case DATA:
- cmd[1] &= ~0x04;
- break;
- case RAW:
- cmd[1] |= 0x40;
- break;
- case COOKED:
- cmd[1] &= ~0x40;
- break;
- default:
- break;
- }
- cmd[0] = 0x50;
- return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
-}
-
-static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
- int tries)
-{
- unsigned char cmd[2] = { 0xa0 };
- xtrace(HW, "setdatamode() %d\n", mode);
- switch (mode) {
- case MODE0:
- cmd[1] = 0x00;
- break;
- case MODE1:
- cmd[1] = 0x01;
- break;
- case MODE2:
- cmd[1] = 0x02;
- break;
- default:
- return -EINVAL;
- }
- return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
-}
-
-static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
-{
- char cmd[4];
-
- xtrace(HW, "config()\n");
-
- cmd[0] = 0x90;
-
- cmd[1] = 0x10; /* irq enable */
- cmd[2] = 0x05; /* pre, err irq enable */
-
- if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries))
- return -1;
-
- cmd[1] = 0x02; /* dma select */
- cmd[2] = 0x00; /* no dma */
-
- return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
-}
-
-static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
- int tries)
-{
- char buf[3];
- int ans;
-
- if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
- 1, buf, sizeof(buf), 2 * HZ, tries)))
- return ans;
-
- ver->code = buf[1];
- ver->ver = buf[2];
-
- return ans;
-}
-
-static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
-{
- if (mode == HARD) {
- outb(0, stuffp->wreg_chn); /* no dma, no irq -> hardware */
- outb(0, stuffp->wreg_reset); /* hw reset */
- return 0;
- } else
- return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
-}
-
-static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
-{
- struct s_drive_stuff *stuffp = cdi->handle;
- char cmd[2] = { 0xfe };
-
- if (!(stuffp->present & DOOR))
- return -ENOSYS;
- if (stuffp->present & DOOR) {
- cmd[1] = lock ? 0x01 : 0x00;
- return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
- } else
- return 0;
-}
-
-static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
-{
- return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
-}
-
-static int
-mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
-{
- unsigned long timeout = to + jiffies;
- char c;
-
- if (!buf)
- buf = &c;
-
- while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) {
- if (time_after(jiffies, timeout))
- return -1;
- mcdx_delay(stuffp, delay);
- }
-
- *buf = (unsigned char) inb(stuffp->rreg_data) & 0xff;
-
- return 0;
-}
-
-static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
- struct cdrom_volctrl *vol, int tries)
-{
- char cmd[5];
- cmd[0] = 0xae;
- cmd[1] = vol->channel0;
- cmd[2] = 0;
- cmd[3] = vol->channel1;
- cmd[4] = 0;
-
- return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR);
diff --git a/drivers/cdrom/mcdx.h b/drivers/cdrom/mcdx.h
deleted file mode 100644
index 83c364a74dc4..000000000000
--- a/drivers/cdrom/mcdx.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Definitions for the Mitsumi CDROM interface
- * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: @VERSION@
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Thanks to
- * The Linux Community at all and ...
- * Martin Harris (he wrote the first Mitsumi Driver)
- * Eberhard Moenkeberg (he gave me much support and the initial kick)
- * Bernd Huebner, Ruediger Helsch (Unifix-Software Gmbh, they
- * improved the original driver)
- * Jon Tombs, Bjorn Ekwall (module support)
- * Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
- * Gerd Knorr (he lent me his PhotoCD)
- * Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
- * Andreas Kies (testing the mysterious hang up's)
- * ... somebody forgotten?
- * Marcin Dalecki
- *
- */
-
-/*
- * The following lines are for user configuration
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * {0|1} -- 1 if you want the driver detect your drive, may crash and
- * needs a long time to seek. The higher the address the longer the
- * seek.
- *
- * WARNING: AUTOPROBE doesn't work.
- */
-#define MCDX_AUTOPROBE 0
-
-/*
- * Drive specific settings according to the jumpers on the controller
- * board(s).
- * o MCDX_NDRIVES : number of used entries of the following table
- * o MCDX_DRIVEMAP : table of {i/o base, irq} per controller
- *
- * NOTE: I didn't get a drive at irq 9(2) working. Not even alone.
- */
-#if MCDX_AUTOPROBE == 0
- #define MCDX_NDRIVES 1
- #define MCDX_DRIVEMAP { \
- {0x300, 11}, \
- {0x304, 05}, \
- {0x000, 00}, \
- {0x000, 00}, \
- {0x000, 00}, \
- }
-#else
- #error Autoprobing is not implemented yet.
-#endif
-
-#ifndef MCDX_QUIET
-#define MCDX_QUIET 1
-#endif
-
-#ifndef MCDX_DEBUG
-#define MCDX_DEBUG 0
-#endif
-
-/* *** make the following line uncommented, if you're sure,
- * *** all configuration is done */
-/* #define I_WAS_HERE */
-
-/* The name of the device */
-#define MCDX "mcdx"
-
-/* Flags for DEBUGGING */
-#define INIT 0
-#define MALLOC 0
-#define IOCTL 0
-#define PLAYTRK 0
-#define SUBCHNL 0
-#define TOCHDR 0
-#define MS 0
-#define PLAYMSF 0
-#define READTOC 0
-#define OPENCLOSE 0
-#define HW 0
-#define TALK 0
-#define IRQ 0
-#define XFER 0
-#define REQUEST 0
-#define SLEEP 0
-
-/* The following addresses are taken from the Mitsumi Reference
- * and describe the possible i/o range for the controller.
- */
-#define MCDX_IO_BEGIN ((char*) 0x300) /* first base of i/o addr */
-#define MCDX_IO_END ((char*) 0x3fc) /* last base of i/o addr */
-
-/* Per controller 4 bytes i/o are needed. */
-#define MCDX_IO_SIZE 4
-
-/*
- * Bits
- */
-
-/* The status byte, returned from every command, set if
- * the description is true */
-#define MCDX_RBIT_OPEN 0x80 /* door is open */
-#define MCDX_RBIT_DISKSET 0x40 /* disk set (recognised) */
-#define MCDX_RBIT_CHANGED 0x20 /* disk was changed */
-#define MCDX_RBIT_CHECK 0x10 /* disk rotates, servo is on */
-#define MCDX_RBIT_AUDIOTR 0x08 /* current track is audio */
-#define MCDX_RBIT_RDERR 0x04 /* read error, refer SENSE KEY */
-#define MCDX_RBIT_AUDIOBS 0x02 /* currently playing audio */
-#define MCDX_RBIT_CMDERR 0x01 /* command, param or format error */
-
-/* The I/O Register holding the h/w status of the drive,
- * can be read at i/o base + 1 */
-#define MCDX_RBIT_DOOR 0x10 /* door is open */
-#define MCDX_RBIT_STEN 0x04 /* if 0, i/o base contains drive status */
-#define MCDX_RBIT_DTEN 0x02 /* if 0, i/o base contains data */
-
-/*
- * The commands.
- */
-
-#define OPCODE 1 /* offset of opcode */
-#define MCDX_CMD_REQUEST_TOC 1, 0x10
-#define MCDX_CMD_REQUEST_STATUS 1, 0x40
-#define MCDX_CMD_RESET 1, 0x60
-#define MCDX_CMD_REQUEST_DRIVE_MODE 1, 0xc2
-#define MCDX_CMD_SET_INTERLEAVE 2, 0xc8, 0
-#define MCDX_CMD_DATAMODE_SET 2, 0xa0, 0
- #define MCDX_DATAMODE1 0x01
- #define MCDX_DATAMODE2 0x02
-#define MCDX_CMD_LOCK_DOOR 2, 0xfe, 0
-
-#define READ_AHEAD 4 /* 8 Sectors (4K) */
-
-/* Useful macros */
-#define e_door(x) ((x) & MCDX_RBIT_OPEN)
-#define e_check(x) (~(x) & MCDX_RBIT_CHECK)
-#define e_notset(x) (~(x) & MCDX_RBIT_DISKSET)
-#define e_changed(x) ((x) & MCDX_RBIT_CHANGED)
-#define e_audio(x) ((x) & MCDX_RBIT_AUDIOTR)
-#define e_audiobusy(x) ((x) & MCDX_RBIT_AUDIOBS)
-#define e_cmderr(x) ((x) & MCDX_RBIT_CMDERR)
-#define e_readerr(x) ((x) & MCDX_RBIT_RDERR)
-
-/** no drive specific */
-#define MCDX_CDBLK 2048 /* 2048 cooked data each blk */
-
-#define MCDX_DATA_TIMEOUT (HZ/10) /* 0.1 second */
-
-/*
- * Access to the msf array
- */
-#define MSF_MIN 0 /* minute */
-#define MSF_SEC 1 /* second */
-#define MSF_FRM 2 /* frame */
-
-/*
- * Errors
- */
-#define MCDX_E 1 /* unspec error */
-#define MCDX_ST_EOM 0x0100 /* end of media */
-#define MCDX_ST_DRV 0x00ff /* mask to query the drive status */
-
-#ifndef I_WAS_HERE
-#ifndef MODULE
-#warning You have not edited mcdx.h
-#warning Perhaps irq and i/o settings are wrong.
-#endif
-#endif
-
-/* ex:set ts=4 sw=4: */
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
deleted file mode 100644
index 3541690a77d4..000000000000
--- a/drivers/cdrom/optcd.c
+++ /dev/null
@@ -1,2105 +0,0 @@
-/* linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver
- $Id: optcd.c,v 1.11 1997/01/26 07:13:00 davem Exp $
-
- Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
-
-
- Based on Aztech CD268 CDROM driver by Werner Zimmermann and preworks
- by Eberhard Moenkeberg (emoenke@gwdg.de).
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Revision history
-
-
- 14-5-95 v0.0 Plays sound tracks. No reading of data CDs yet.
- Detection of disk change doesn't work.
- 21-5-95 v0.1 First ALPHA version. CD can be mounted. The
- device major nr is borrowed from the Aztech
- driver. Speed is around 240 kb/s, as measured
- with "time dd if=/dev/cdrom of=/dev/null \
- bs=2048 count=4096".
- 24-6-95 v0.2 Reworked the #defines for the command codes
- and the like, as well as the structure of
- the hardware communication protocol, to
- reflect the "official" documentation, kindly
- supplied by C.K. Tan, Optics Storage Pte. Ltd.
- Also tidied up the state machine somewhat.
- 28-6-95 v0.3 Removed the ISP-16 interface code, as this
- should go into its own driver. The driver now
- has its own major nr.
- Disk change detection now seems to work, too.
- This version became part of the standard
- kernel as of version 1.3.7
- 24-9-95 v0.4 Re-inserted ISP-16 interface code which I
- copied from sjcd.c, with a few changes.
- Updated README.optcd. Submitted for
- inclusion in 1.3.21
- 29-9-95 v0.4a Fixed bug that prevented compilation as module
- 25-10-95 v0.5 Started multisession code. Implementation
- copied from Werner Zimmermann, who copied it
- from Heiko Schlittermann's mcdx.
- 17-1-96 v0.6 Multisession works; some cleanup too.
- 18-4-96 v0.7 Increased some timing constants;
- thanks to Luke McFarlane. Also tidied up some
- printk behaviour. ISP16 initialization
- is now handled by a separate driver.
-
- 09-11-99 Make kernel-parameter implementation work with 2.3.x
- Removed init_module & cleanup_module in favor of
- module_init & module_exit.
- Torben Mathiasen <tmm@image.dk>
-*/
-
-/* Includes */
-
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <linux/blkdev.h>
-
-#include <linux/cdrom.h>
-#include "optcd.h"
-
-#include <asm/uaccess.h>
-
-#define MAJOR_NR OPTICS_CDROM_MAJOR
-#define QUEUE (opt_queue)
-#define CURRENT elv_next_request(opt_queue)
-
-
-/* Debug support */
-
-
-/* Don't forget to add new debug flags here. */
-#if DEBUG_DRIVE_IF | DEBUG_VFS | DEBUG_CONV | DEBUG_TOC | \
- DEBUG_BUFFERS | DEBUG_REQUEST | DEBUG_STATE | DEBUG_MULTIS
-#define DEBUG(x) debug x
-static void debug(int debug_this, const char* fmt, ...)
-{
- char s[1024];
- va_list args;
-
- if (!debug_this)
- return;
-
- va_start(args, fmt);
- vsnprintf(s, sizeof(s), fmt, args);
- printk(KERN_DEBUG "optcd: %s\n", s);
- va_end(args);
-}
-#else
-#define DEBUG(x)
-#endif
-
-
-/* Drive hardware/firmware characteristics
- Identifiers in accordance with Optics Storage documentation */
-
-
-#define optcd_port optcd /* Needed for the modutils. */
-static short optcd_port = OPTCD_PORTBASE; /* I/O base of drive. */
-module_param(optcd_port, short, 0);
-/* Drive registers, read */
-#define DATA_PORT optcd_port /* Read data/status */
-#define STATUS_PORT optcd_port+1 /* Indicate data/status availability */
-
-/* Drive registers, write */
-#define COMIN_PORT optcd_port /* For passing command/parameter */
-#define RESET_PORT optcd_port+1 /* Write anything and wait 0.5 sec */
-#define HCON_PORT optcd_port+2 /* Host Xfer Configuration */
-
-
-/* Command completion/status read from DATA register */
-#define ST_DRVERR 0x80
-#define ST_DOOR_OPEN 0x40
-#define ST_MIXEDMODE_DISK 0x20
-#define ST_MODE_BITS 0x1c
-#define ST_M_STOP 0x00
-#define ST_M_READ 0x04
-#define ST_M_AUDIO 0x04
-#define ST_M_PAUSE 0x08
-#define ST_M_INITIAL 0x0c
-#define ST_M_ERROR 0x10
-#define ST_M_OTHERS 0x14
-#define ST_MODE2TRACK 0x02
-#define ST_DSK_CHG 0x01
-#define ST_L_LOCK 0x01
-#define ST_CMD_OK 0x00
-#define ST_OP_OK 0x01
-#define ST_PA_OK 0x02
-#define ST_OP_ERROR 0x05
-#define ST_PA_ERROR 0x06
-
-
-/* Error codes (appear as command completion code from DATA register) */
-/* Player related errors */
-#define ERR_ILLCMD 0x11 /* Illegal command to player module */
-#define ERR_ILLPARM 0x12 /* Illegal parameter to player module */
-#define ERR_SLEDGE 0x13
-#define ERR_FOCUS 0x14
-#define ERR_MOTOR 0x15
-#define ERR_RADIAL 0x16
-#define ERR_PLL 0x17 /* PLL lock error */
-#define ERR_SUB_TIM 0x18 /* Subcode timeout error */
-#define ERR_SUB_NF 0x19 /* Subcode not found error */
-#define ERR_TRAY 0x1a
-#define ERR_TOC 0x1b /* Table of Contents read error */
-#define ERR_JUMP 0x1c
-/* Data errors */
-#define ERR_MODE 0x21
-#define ERR_FORM 0x22
-#define ERR_HEADADDR 0x23 /* Header Address not found */
-#define ERR_CRC 0x24
-#define ERR_ECC 0x25 /* Uncorrectable ECC error */
-#define ERR_CRC_UNC 0x26 /* CRC error and uncorrectable error */
-#define ERR_ILLBSYNC 0x27 /* Illegal block sync error */
-#define ERR_VDST 0x28 /* VDST not found */
-/* Timeout errors */
-#define ERR_READ_TIM 0x31 /* Read timeout error */
-#define ERR_DEC_STP 0x32 /* Decoder stopped */
-#define ERR_DEC_TIM 0x33 /* Decoder interrupt timeout error */
-/* Function abort codes */
-#define ERR_KEY 0x41 /* Key -Detected abort */
-#define ERR_READ_FINISH 0x42 /* Read Finish */
-/* Second Byte diagnostic codes */
-#define ERR_NOBSYNC 0x01 /* No block sync */
-#define ERR_SHORTB 0x02 /* Short block */
-#define ERR_LONGB 0x03 /* Long block */
-#define ERR_SHORTDSP 0x04 /* Short DSP word */
-#define ERR_LONGDSP 0x05 /* Long DSP word */
-
-
-/* Status availability flags read from STATUS register */
-#define FL_EJECT 0x20
-#define FL_WAIT 0x10 /* active low */
-#define FL_EOP 0x08 /* active low */
-#define FL_STEN 0x04 /* Status available when low */
-#define FL_DTEN 0x02 /* Data available when low */
-#define FL_DRQ 0x01 /* active low */
-#define FL_RESET 0xde /* These bits are high after a reset */
-#define FL_STDT (FL_STEN|FL_DTEN)
-
-
-/* Transfer mode, written to HCON register */
-#define HCON_DTS 0x08
-#define HCON_SDRQB 0x04
-#define HCON_LOHI 0x02
-#define HCON_DMA16 0x01
-
-
-/* Drive command set, written to COMIN register */
-/* Quick response commands */
-#define COMDRVST 0x20 /* Drive Status Read */
-#define COMERRST 0x21 /* Error Status Read */
-#define COMIOCTLISTAT 0x22 /* Status Read; reset disk changed bit */
-#define COMINITSINGLE 0x28 /* Initialize Single Speed */
-#define COMINITDOUBLE 0x29 /* Initialize Double Speed */
-#define COMUNLOCK 0x30 /* Unlock */
-#define COMLOCK 0x31 /* Lock */
-#define COMLOCKST 0x32 /* Lock/Unlock Status */
-#define COMVERSION 0x40 /* Get Firmware Revision */
-#define COMVOIDREADMODE 0x50 /* Void Data Read Mode */
-/* Read commands */
-#define COMFETCH 0x60 /* Prefetch Data */
-#define COMREAD 0x61 /* Read */
-#define COMREADRAW 0x62 /* Read Raw Data */
-#define COMREADALL 0x63 /* Read All 2646 Bytes */
-/* Player control commands */
-#define COMLEADIN 0x70 /* Seek To Lead-in */
-#define COMSEEK 0x71 /* Seek */
-#define COMPAUSEON 0x80 /* Pause On */
-#define COMPAUSEOFF 0x81 /* Pause Off */
-#define COMSTOP 0x82 /* Stop */
-#define COMOPEN 0x90 /* Open Tray Door */
-#define COMCLOSE 0x91 /* Close Tray Door */
-#define COMPLAY 0xa0 /* Audio Play */
-#define COMPLAY_TNO 0xa2 /* Audio Play By Track Number */
-#define COMSUBQ 0xb0 /* Read Sub-q Code */
-#define COMLOCATION 0xb1 /* Read Head Position */
-/* Audio control commands */
-#define COMCHCTRL 0xc0 /* Audio Channel Control */
-/* Miscellaneous (test) commands */
-#define COMDRVTEST 0xd0 /* Write Test Bytes */
-#define COMTEST 0xd1 /* Diagnostic Test */
-
-/* Low level drive interface. Only here we do actual I/O
- Waiting for status / data available */
-
-
-/* Busy wait until FLAG goes low. Return 0 on timeout. */
-static inline int flag_low(int flag, unsigned long timeout)
-{
- int flag_high;
- unsigned long count = 0;
-
- while ((flag_high = (inb(STATUS_PORT) & flag)))
- if (++count >= timeout)
- break;
-
- DEBUG((DEBUG_DRIVE_IF, "flag_low 0x%x count %ld%s",
- flag, count, flag_high ? " timeout" : ""));
- return !flag_high;
-}
-
-
-/* Timed waiting for status or data */
-static int sleep_timeout; /* max # of ticks to sleep */
-static DECLARE_WAIT_QUEUE_HEAD(waitq);
-static void sleep_timer(unsigned long data);
-static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0);
-static DEFINE_SPINLOCK(optcd_lock);
-static struct request_queue *opt_queue;
-
-/* Timer routine: wake up when desired flag goes low,
- or when timeout expires. */
-static void sleep_timer(unsigned long data)
-{
- int flags = inb(STATUS_PORT) & FL_STDT;
-
- if (flags == FL_STDT && --sleep_timeout > 0) {
- mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */
- } else
- wake_up(&waitq);
-}
-
-
-/* Sleep until FLAG goes low. Return 0 on timeout or wrong flag low. */
-static int sleep_flag_low(int flag, unsigned long timeout)
-{
- int flag_high;
-
- DEBUG((DEBUG_DRIVE_IF, "sleep_flag_low"));
-
- sleep_timeout = timeout;
- flag_high = inb(STATUS_PORT) & flag;
- if (flag_high && sleep_timeout > 0) {
- mod_timer(&delay_timer, jiffies + HZ/100);
- sleep_on(&waitq);
- flag_high = inb(STATUS_PORT) & flag;
- }
-
- DEBUG((DEBUG_DRIVE_IF, "flag 0x%x count %ld%s",
- flag, timeout, flag_high ? " timeout" : ""));
- return !flag_high;
-}
-
-/* Low level drive interface. Only here we do actual I/O
- Sending commands and parameters */
-
-
-/* Errors in the command protocol */
-#define ERR_IF_CMD_TIMEOUT 0x100
-#define ERR_IF_ERR_TIMEOUT 0x101
-#define ERR_IF_RESP_TIMEOUT 0x102
-#define ERR_IF_DATA_TIMEOUT 0x103
-#define ERR_IF_NOSTAT 0x104
-
-
-/* Send command code. Return <0 indicates error */
-static int send_cmd(int cmd)
-{
- unsigned char ack;
-
- DEBUG((DEBUG_DRIVE_IF, "sending command 0x%02x\n", cmd));
-
- outb(HCON_DTS, HCON_PORT); /* Enable Suspend Data Transfer */
- outb(cmd, COMIN_PORT); /* Send command code */
- if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
- return -ERR_IF_CMD_TIMEOUT;
- ack = inb(DATA_PORT); /* read command acknowledge */
- outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */
- return ack==ST_OP_OK ? 0 : -ack;
-}
-
-
-/* Send command parameters. Return <0 indicates error */
-static int send_params(struct cdrom_msf *params)
-{
- unsigned char ack;
-
- DEBUG((DEBUG_DRIVE_IF, "sending parameters"
- " %02x:%02x:%02x"
- " %02x:%02x:%02x",
- params->cdmsf_min0,
- params->cdmsf_sec0,
- params->cdmsf_frame0,
- params->cdmsf_min1,
- params->cdmsf_sec1,
- params->cdmsf_frame1));
-
- outb(params->cdmsf_min0, COMIN_PORT);
- outb(params->cdmsf_sec0, COMIN_PORT);
- outb(params->cdmsf_frame0, COMIN_PORT);
- outb(params->cdmsf_min1, COMIN_PORT);
- outb(params->cdmsf_sec1, COMIN_PORT);
- outb(params->cdmsf_frame1, COMIN_PORT);
- if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
- return -ERR_IF_CMD_TIMEOUT;
- ack = inb(DATA_PORT); /* read command acknowledge */
- return ack==ST_PA_OK ? 0 : -ack;
-}
-
-
-/* Send parameters for SEEK command. Return <0 indicates error */
-static int send_seek_params(struct cdrom_msf *params)
-{
- unsigned char ack;
-
- DEBUG((DEBUG_DRIVE_IF, "sending seek parameters"
- " %02x:%02x:%02x",
- params->cdmsf_min0,
- params->cdmsf_sec0,
- params->cdmsf_frame0));
-
- outb(params->cdmsf_min0, COMIN_PORT);
- outb(params->cdmsf_sec0, COMIN_PORT);
- outb(params->cdmsf_frame0, COMIN_PORT);
- if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
- return -ERR_IF_CMD_TIMEOUT;
- ack = inb(DATA_PORT); /* read command acknowledge */
- return ack==ST_PA_OK ? 0 : -ack;
-}
-
-
-/* Wait for command execution status. Choice between busy waiting
- and sleeping. Return value <0 indicates timeout. */
-static inline int get_exec_status(int busy_waiting)
-{
- unsigned char exec_status;
-
- if (busy_waiting
- ? !flag_low(FL_STEN, BUSY_TIMEOUT)
- : !sleep_flag_low(FL_STEN, SLEEP_TIMEOUT))
- return -ERR_IF_CMD_TIMEOUT;
-
- exec_status = inb(DATA_PORT);
- DEBUG((DEBUG_DRIVE_IF, "returned exec status 0x%02x", exec_status));
- return exec_status;
-}
-
-
-/* Wait busy for extra byte of data that a command returns.
- Return value <0 indicates timeout. */
-static inline int get_data(int short_timeout)
-{
- unsigned char data;
-
- if (!flag_low(FL_STEN, short_timeout ? FAST_TIMEOUT : BUSY_TIMEOUT))
- return -ERR_IF_DATA_TIMEOUT;
-
- data = inb(DATA_PORT);
- DEBUG((DEBUG_DRIVE_IF, "returned data 0x%02x", data));
- return data;
-}
-
-
-/* Returns 0 if failed */
-static int reset_drive(void)
-{
- unsigned long count = 0;
- int flags;
-
- DEBUG((DEBUG_DRIVE_IF, "reset drive"));
-
- outb(0, RESET_PORT);
- while (++count < RESET_WAIT)
- inb(DATA_PORT);
-
- count = 0;
- while ((flags = (inb(STATUS_PORT) & FL_RESET)) != FL_RESET)
- if (++count >= BUSY_TIMEOUT)
- break;
-
- DEBUG((DEBUG_DRIVE_IF, "reset %s",
- flags == FL_RESET ? "succeeded" : "failed"));
-
- if (flags != FL_RESET)
- return 0; /* Reset failed */
- outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */
- return 1; /* Reset succeeded */
-}
-
-
-/* Facilities for asynchronous operation */
-
-/* Read status/data availability flags FL_STEN and FL_DTEN */
-static inline int stdt_flags(void)
-{
- return inb(STATUS_PORT) & FL_STDT;
-}
-
-
-/* Fetch status that has previously been waited for. <0 means not available */
-static inline int fetch_status(void)
-{
- unsigned char status;
-
- if (inb(STATUS_PORT) & FL_STEN)
- return -ERR_IF_NOSTAT;
-
- status = inb(DATA_PORT);
- DEBUG((DEBUG_DRIVE_IF, "fetched exec status 0x%02x", status));
- return status;
-}
-
-
-/* Fetch data that has previously been waited for. */
-static inline void fetch_data(char *buf, int n)
-{
- insb(DATA_PORT, buf, n);
- DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n));
-}
-
-
-/* Flush status and data fifos */
-static inline void flush_data(void)
-{
- while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT)
- inb(DATA_PORT);
- DEBUG((DEBUG_DRIVE_IF, "flushed fifos"));
-}
-
-/* Command protocol */
-
-
-/* Send a simple command and wait for response. Command codes < COMFETCH
- are quick response commands */
-static inline int exec_cmd(int cmd)
-{
- int ack = send_cmd(cmd);
- if (ack < 0)
- return ack;
- return get_exec_status(cmd < COMFETCH);
-}
-
-
-/* Send a command with parameters. Don't wait for the response,
- * which consists of data blocks read from the CD. */
-static inline int exec_read_cmd(int cmd, struct cdrom_msf *params)
-{
- int ack = send_cmd(cmd);
- if (ack < 0)
- return ack;
- return send_params(params);
-}
-
-
-/* Send a seek command with parameters and wait for response */
-static inline int exec_seek_cmd(int cmd, struct cdrom_msf *params)
-{
- int ack = send_cmd(cmd);
- if (ack < 0)
- return ack;
- ack = send_seek_params(params);
- if (ack < 0)
- return ack;
- return 0;
-}
-
-
-/* Send a command with parameters and wait for response */
-static inline int exec_long_cmd(int cmd, struct cdrom_msf *params)
-{
- int ack = exec_read_cmd(cmd, params);
- if (ack < 0)
- return ack;
- return get_exec_status(0);
-}
-
-/* Address conversion routines */
-
-
-/* Binary to BCD (2 digits) */
-static inline void single_bin2bcd(u_char *p)
-{
- DEBUG((DEBUG_CONV, "bin2bcd %02d", *p));
- *p = (*p % 10) | ((*p / 10) << 4);
-}
-
-
-/* Convert entire msf struct */
-static void bin2bcd(struct cdrom_msf *msf)
-{
- single_bin2bcd(&msf->cdmsf_min0);
- single_bin2bcd(&msf->cdmsf_sec0);
- single_bin2bcd(&msf->cdmsf_frame0);
- single_bin2bcd(&msf->cdmsf_min1);
- single_bin2bcd(&msf->cdmsf_sec1);
- single_bin2bcd(&msf->cdmsf_frame1);
-}
-
-
-/* Linear block address to minute, second, frame form */
-#define CD_FPM (CD_SECS * CD_FRAMES) /* frames per minute */
-
-static void lba2msf(int lba, struct cdrom_msf *msf)
-{
- DEBUG((DEBUG_CONV, "lba2msf %d", lba));
- lba += CD_MSF_OFFSET;
- msf->cdmsf_min0 = lba / CD_FPM; lba %= CD_FPM;
- msf->cdmsf_sec0 = lba / CD_FRAMES;
- msf->cdmsf_frame0 = lba % CD_FRAMES;
- msf->cdmsf_min1 = 0;
- msf->cdmsf_sec1 = 0;
- msf->cdmsf_frame1 = 0;
- bin2bcd(msf);
-}
-
-
-/* Two BCD digits to binary */
-static inline u_char bcd2bin(u_char bcd)
-{
- DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd));
- return (bcd >> 4) * 10 + (bcd & 0x0f);
-}
-
-
-static void msf2lba(union cdrom_addr *addr)
-{
- addr->lba = addr->msf.minute * CD_FPM
- + addr->msf.second * CD_FRAMES
- + addr->msf.frame - CD_MSF_OFFSET;
-}
-
-
-/* Minute, second, frame address BCD to binary or to linear address,
- depending on MODE */
-static void msf_bcd2bin(union cdrom_addr *addr)
-{
- addr->msf.minute = bcd2bin(addr->msf.minute);
- addr->msf.second = bcd2bin(addr->msf.second);
- addr->msf.frame = bcd2bin(addr->msf.frame);
-}
-
-/* High level drive commands */
-
-
-static int audio_status = CDROM_AUDIO_NO_STATUS;
-static char toc_uptodate = 0;
-static char disk_changed = 1;
-
-/* Get drive status, flagging completion of audio play and disk changes. */
-static int drive_status(void)
-{
- int status;
-
- status = exec_cmd(COMIOCTLISTAT);
- DEBUG((DEBUG_DRIVE_IF, "IOCTLISTAT: %03x", status));
- if (status < 0)
- return status;
- if (status == 0xff) /* No status available */
- return -ERR_IF_NOSTAT;
-
- if (((status & ST_MODE_BITS) != ST_M_AUDIO) &&
- (audio_status == CDROM_AUDIO_PLAY)) {
- audio_status = CDROM_AUDIO_COMPLETED;
- }
-
- if (status & ST_DSK_CHG) {
- toc_uptodate = 0;
- disk_changed = 1;
- audio_status = CDROM_AUDIO_NO_STATUS;
- }
-
- return status;
-}
-
-
-/* Read the current Q-channel info. Also used for reading the
- table of contents. qp->cdsc_format must be set on entry to
- indicate the desired address format */
-static int get_q_channel(struct cdrom_subchnl *qp)
-{
- int status, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10;
-
- status = drive_status();
- if (status < 0)
- return status;
- qp->cdsc_audiostatus = audio_status;
-
- status = exec_cmd(COMSUBQ);
- if (status < 0)
- return status;
-
- d1 = get_data(0);
- if (d1 < 0)
- return d1;
- qp->cdsc_adr = d1;
- qp->cdsc_ctrl = d1 >> 4;
-
- d2 = get_data(0);
- if (d2 < 0)
- return d2;
- qp->cdsc_trk = bcd2bin(d2);
-
- d3 = get_data(0);
- if (d3 < 0)
- return d3;
- qp->cdsc_ind = bcd2bin(d3);
-
- d4 = get_data(0);
- if (d4 < 0)
- return d4;
- qp->cdsc_reladdr.msf.minute = d4;
-
- d5 = get_data(0);
- if (d5 < 0)
- return d5;
- qp->cdsc_reladdr.msf.second = d5;
-
- d6 = get_data(0);
- if (d6 < 0)
- return d6;
- qp->cdsc_reladdr.msf.frame = d6;
-
- d7 = get_data(0);
- if (d7 < 0)
- return d7;
- /* byte not used */
-
- d8 = get_data(0);
- if (d8 < 0)
- return d8;
- qp->cdsc_absaddr.msf.minute = d8;
-
- d9 = get_data(0);
- if (d9 < 0)
- return d9;
- qp->cdsc_absaddr.msf.second = d9;
-
- d10 = get_data(0);
- if (d10 < 0)
- return d10;
- qp->cdsc_absaddr.msf.frame = d10;
-
- DEBUG((DEBUG_TOC, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- d1, d2, d3, d4, d5, d6, d7, d8, d9, d10));
-
- msf_bcd2bin(&qp->cdsc_absaddr);
- msf_bcd2bin(&qp->cdsc_reladdr);
- if (qp->cdsc_format == CDROM_LBA) {
- msf2lba(&qp->cdsc_absaddr);
- msf2lba(&qp->cdsc_reladdr);
- }
-
- return 0;
-}
-
-/* Table of contents handling */
-
-
-/* Errors in table of contents */
-#define ERR_TOC_MISSINGINFO 0x120
-#define ERR_TOC_MISSINGENTRY 0x121
-
-
-struct cdrom_disk_info {
- unsigned char first;
- unsigned char last;
- struct cdrom_msf0 disk_length;
- struct cdrom_msf0 first_track;
- /* Multisession info: */
- unsigned char next;
- struct cdrom_msf0 next_session;
- struct cdrom_msf0 last_session;
- unsigned char multi;
- unsigned char xa;
- unsigned char audio;
-};
-static struct cdrom_disk_info disk_info;
-
-#define MAX_TRACKS 111
-static struct cdrom_subchnl toc[MAX_TRACKS];
-
-#define QINFO_FIRSTTRACK 100 /* bcd2bin(0xa0) */
-#define QINFO_LASTTRACK 101 /* bcd2bin(0xa1) */
-#define QINFO_DISKLENGTH 102 /* bcd2bin(0xa2) */
-#define QINFO_NEXTSESSION 110 /* bcd2bin(0xb0) */
-
-#define I_FIRSTTRACK 0x01
-#define I_LASTTRACK 0x02
-#define I_DISKLENGTH 0x04
-#define I_NEXTSESSION 0x08
-#define I_ALL (I_FIRSTTRACK | I_LASTTRACK | I_DISKLENGTH)
-
-
-#if DEBUG_TOC
-static void toc_debug_info(int i)
-{
- printk(KERN_DEBUG "#%3d ctl %1x, adr %1x, track %2d index %3d"
- " %2d:%02d.%02d %2d:%02d.%02d\n",
- i, toc[i].cdsc_ctrl, toc[i].cdsc_adr,
- toc[i].cdsc_trk, toc[i].cdsc_ind,
- toc[i].cdsc_reladdr.msf.minute,
- toc[i].cdsc_reladdr.msf.second,
- toc[i].cdsc_reladdr.msf.frame,
- toc[i].cdsc_absaddr.msf.minute,
- toc[i].cdsc_absaddr.msf.second,
- toc[i].cdsc_absaddr.msf.frame);
-}
-#endif
-
-
-static int read_toc(void)
-{
- int status, limit, count;
- unsigned char got_info = 0;
- struct cdrom_subchnl q_info;
-#if DEBUG_TOC
- int i;
-#endif
-
- DEBUG((DEBUG_TOC, "starting read_toc"));
-
- count = 0;
- for (limit = 60; limit > 0; limit--) {
- int index;
-
- q_info.cdsc_format = CDROM_MSF;
- status = get_q_channel(&q_info);
- if (status < 0)
- return status;
-
- index = q_info.cdsc_ind;
- if (index > 0 && index < MAX_TRACKS
- && q_info.cdsc_trk == 0 && toc[index].cdsc_ind == 0) {
- toc[index] = q_info;
- DEBUG((DEBUG_TOC, "got %d", index));
- if (index < 100)
- count++;
-
- switch (q_info.cdsc_ind) {
- case QINFO_FIRSTTRACK:
- got_info |= I_FIRSTTRACK;
- break;
- case QINFO_LASTTRACK:
- got_info |= I_LASTTRACK;
- break;
- case QINFO_DISKLENGTH:
- got_info |= I_DISKLENGTH;
- break;
- case QINFO_NEXTSESSION:
- got_info |= I_NEXTSESSION;
- break;
- }
- }
-
- if ((got_info & I_ALL) == I_ALL
- && toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
- >= toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
- break;
- }
-
- /* Construct disk_info from TOC */
- if (disk_info.first == 0) {
- disk_info.first = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
- disk_info.first_track.minute =
- toc[disk_info.first].cdsc_absaddr.msf.minute;
- disk_info.first_track.second =
- toc[disk_info.first].cdsc_absaddr.msf.second;
- disk_info.first_track.frame =
- toc[disk_info.first].cdsc_absaddr.msf.frame;
- }
- disk_info.last = toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute;
- disk_info.disk_length.minute =
- toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.minute;
- disk_info.disk_length.second =
- toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.second-2;
- disk_info.disk_length.frame =
- toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.frame;
- disk_info.next_session.minute =
- toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.minute;
- disk_info.next_session.second =
- toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.second;
- disk_info.next_session.frame =
- toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.frame;
- disk_info.next = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
- disk_info.last_session.minute =
- toc[disk_info.next].cdsc_absaddr.msf.minute;
- disk_info.last_session.second =
- toc[disk_info.next].cdsc_absaddr.msf.second;
- disk_info.last_session.frame =
- toc[disk_info.next].cdsc_absaddr.msf.frame;
- toc[disk_info.last + 1].cdsc_absaddr.msf.minute =
- disk_info.disk_length.minute;
- toc[disk_info.last + 1].cdsc_absaddr.msf.second =
- disk_info.disk_length.second;
- toc[disk_info.last + 1].cdsc_absaddr.msf.frame =
- disk_info.disk_length.frame;
-#if DEBUG_TOC
- for (i = 1; i <= disk_info.last + 1; i++)
- toc_debug_info(i);
- toc_debug_info(QINFO_FIRSTTRACK);
- toc_debug_info(QINFO_LASTTRACK);
- toc_debug_info(QINFO_DISKLENGTH);
- toc_debug_info(QINFO_NEXTSESSION);
-#endif
-
- DEBUG((DEBUG_TOC, "exiting read_toc, got_info %x, count %d",
- got_info, count));
- if ((got_info & I_ALL) != I_ALL
- || toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
- < toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
- return -ERR_TOC_MISSINGINFO;
- return 0;
-}
-
-
-#ifdef MULTISESSION
-static int get_multi_disk_info(void)
-{
- int sessions, status;
- struct cdrom_msf multi_index;
-
-
- for (sessions = 2; sessions < 10 /* %%for now */; sessions++) {
- int count;
-
- for (count = 100; count < MAX_TRACKS; count++)
- toc[count].cdsc_ind = 0;
-
- multi_index.cdmsf_min0 = disk_info.next_session.minute;
- multi_index.cdmsf_sec0 = disk_info.next_session.second;
- multi_index.cdmsf_frame0 = disk_info.next_session.frame;
- if (multi_index.cdmsf_sec0 >= 20)
- multi_index.cdmsf_sec0 -= 20;
- else {
- multi_index.cdmsf_sec0 += 40;
- multi_index.cdmsf_min0--;
- }
- DEBUG((DEBUG_MULTIS, "Try %d: %2d:%02d.%02d", sessions,
- multi_index.cdmsf_min0,
- multi_index.cdmsf_sec0,
- multi_index.cdmsf_frame0));
- bin2bcd(&multi_index);
- multi_index.cdmsf_min1 = 0;
- multi_index.cdmsf_sec1 = 0;
- multi_index.cdmsf_frame1 = 1;
-
- status = exec_read_cmd(COMREAD, &multi_index);
- if (status < 0) {
- DEBUG((DEBUG_TOC, "exec_read_cmd COMREAD: %02x",
- -status));
- break;
- }
- status = sleep_flag_low(FL_DTEN, MULTI_SEEK_TIMEOUT) ?
- 0 : -ERR_TOC_MISSINGINFO;
- flush_data();
- if (status < 0) {
- DEBUG((DEBUG_TOC, "sleep_flag_low: %02x", -status));
- break;
- }
-
- status = read_toc();
- if (status < 0) {
- DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
- break;
- }
-
- disk_info.multi = 1;
- }
-
- exec_cmd(COMSTOP);
-
- if (status < 0)
- return -EIO;
- return 0;
-}
-#endif /* MULTISESSION */
-
-
-static int update_toc(void)
-{
- int status, count;
-
- if (toc_uptodate)
- return 0;
-
- DEBUG((DEBUG_TOC, "starting update_toc"));
-
- disk_info.first = 0;
- for (count = 0; count < MAX_TRACKS; count++)
- toc[count].cdsc_ind = 0;
-
- status = exec_cmd(COMLEADIN);
- if (status < 0)
- return -EIO;
-
- status = read_toc();
- if (status < 0) {
- DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
- return -EIO;
- }
-
- /* Audio disk detection. Look at first track. */
- disk_info.audio =
- (toc[disk_info.first].cdsc_ctrl & CDROM_DATA_TRACK) ? 0 : 1;
-
- /* XA detection */
- disk_info.xa = drive_status() & ST_MODE2TRACK;
-
- /* Multisession detection: if we want this, define MULTISESSION */
- disk_info.multi = 0;
-#ifdef MULTISESSION
- if (disk_info.xa)
- get_multi_disk_info(); /* Here disk_info.multi is set */
-#endif /* MULTISESSION */
- if (disk_info.multi)
- printk(KERN_WARNING "optcd: Multisession support experimental, "
- "see Documentation/cdrom/optcd\n");
-
- DEBUG((DEBUG_TOC, "exiting update_toc"));
-
- toc_uptodate = 1;
- return 0;
-}
-
-/* Request handling */
-
-static int current_valid(void)
-{
- return CURRENT &&
- CURRENT->cmd == READ &&
- CURRENT->sector != -1;
-}
-
-/* Buffers for block size conversion. */
-#define NOBUF -1
-
-static char buf[CD_FRAMESIZE * N_BUFS];
-static volatile int buf_bn[N_BUFS], next_bn;
-static volatile int buf_in = 0, buf_out = NOBUF;
-
-static inline void opt_invalidate_buffers(void)
-{
- int i;
-
- DEBUG((DEBUG_BUFFERS, "executing opt_invalidate_buffers"));
-
- for (i = 0; i < N_BUFS; i++)
- buf_bn[i] = NOBUF;
- buf_out = NOBUF;
-}
-
-
-/* Take care of the different block sizes between cdrom and Linux.
- When Linux gets variable block sizes this will probably go away. */
-static void transfer(void)
-{
-#if DEBUG_BUFFERS | DEBUG_REQUEST
- printk(KERN_DEBUG "optcd: executing transfer\n");
-#endif
-
- if (!current_valid())
- return;
- while (CURRENT -> nr_sectors) {
- int bn = CURRENT -> sector / 4;
- int i, offs, nr_sectors;
- for (i = 0; i < N_BUFS && buf_bn[i] != bn; ++i);
-
- DEBUG((DEBUG_REQUEST, "found %d", i));
-
- if (i >= N_BUFS) {
- buf_out = NOBUF;
- break;
- }
-
- offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
- nr_sectors = 4 - (CURRENT -> sector & 3);
-
- if (buf_out != i) {
- buf_out = i;
- if (buf_bn[i] != bn) {
- buf_out = NOBUF;
- continue;
- }
- }
-
- if (nr_sectors > CURRENT -> nr_sectors)
- nr_sectors = CURRENT -> nr_sectors;
- memcpy(CURRENT -> buffer, buf + offs, nr_sectors * 512);
- CURRENT -> nr_sectors -= nr_sectors;
- CURRENT -> sector += nr_sectors;
- CURRENT -> buffer += nr_sectors * 512;
- }
-}
-
-
-/* State machine for reading disk blocks */
-
-enum state_e {
- S_IDLE, /* 0 */
- S_START, /* 1 */
- S_READ, /* 2 */
- S_DATA, /* 3 */
- S_STOP, /* 4 */
- S_STOPPING /* 5 */
-};
-
-static volatile enum state_e state = S_IDLE;
-#if DEBUG_STATE
-static volatile enum state_e state_old = S_STOP;
-static volatile int flags_old = 0;
-static volatile long state_n = 0;
-#endif
-
-
-/* Used as mutex to keep do_optcd_request (and other processes calling
- ioctl) out while some process is inside a VFS call.
- Reverse is accomplished by checking if state = S_IDLE upon entry
- of opt_ioctl and opt_media_change. */
-static int in_vfs = 0;
-
-
-static volatile int transfer_is_active = 0;
-static volatile int error = 0; /* %% do something with this?? */
-static int tries; /* ibid?? */
-static int timeout = 0;
-
-static void poll(unsigned long data);
-static struct timer_list req_timer = {.function = poll};
-
-
-static void poll(unsigned long data)
-{
- static volatile int read_count = 1;
- int flags;
- int loop_again = 1;
- int status = 0;
- int skip = 0;
-
- if (error) {
- printk(KERN_ERR "optcd: I/O error 0x%02x\n", error);
- opt_invalidate_buffers();
- if (!tries--) {
- printk(KERN_ERR "optcd: read block %d failed;"
- " Giving up\n", next_bn);
- if (transfer_is_active)
- loop_again = 0;
- if (current_valid())
- end_request(CURRENT, 0);
- tries = 5;
- }
- error = 0;
- state = S_STOP;
- }
-
- while (loop_again)
- {
- loop_again = 0; /* each case must flip this back to 1 if we want
- to come back up here */
-
-#if DEBUG_STATE
- if (state == state_old)
- state_n++;
- else {
- state_old = state;
- if (++state_n > 1)
- printk(KERN_DEBUG "optcd: %ld times "
- "in previous state\n", state_n);
- printk(KERN_DEBUG "optcd: state %d\n", state);
- state_n = 0;
- }
-#endif
-
- switch (state) {
- case S_IDLE:
- return;
- case S_START:
- if (in_vfs)
- break;
- if (send_cmd(COMDRVST)) {
- state = S_IDLE;
- while (current_valid())
- end_request(CURRENT, 0);
- return;
- }
- state = S_READ;
- timeout = READ_TIMEOUT;
- break;
- case S_READ: {
- struct cdrom_msf msf;
- if (!skip) {
- status = fetch_status();
- if (status < 0)
- break;
- if (status & ST_DSK_CHG) {
- toc_uptodate = 0;
- opt_invalidate_buffers();
- }
- }
- skip = 0;
- if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
- toc_uptodate = 0;
- opt_invalidate_buffers();
- printk(KERN_WARNING "optcd: %s\n",
- (status & ST_DOOR_OPEN)
- ? "door open"
- : "disk removed");
- state = S_IDLE;
- while (current_valid())
- end_request(CURRENT, 0);
- return;
- }
- if (!current_valid()) {
- state = S_STOP;
- loop_again = 1;
- break;
- }
- next_bn = CURRENT -> sector / 4;
- lba2msf(next_bn, &msf);
- read_count = N_BUFS;
- msf.cdmsf_frame1 = read_count; /* Not BCD! */
-
- DEBUG((DEBUG_REQUEST, "reading %x:%x.%x %x:%x.%x",
- msf.cdmsf_min0,
- msf.cdmsf_sec0,
- msf.cdmsf_frame0,
- msf.cdmsf_min1,
- msf.cdmsf_sec1,
- msf.cdmsf_frame1));
- DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d"
- " buf_out:%d buf_bn:%d",
- next_bn,
- buf_in,
- buf_out,
- buf_bn[buf_in]));
-
- exec_read_cmd(COMREAD, &msf);
- state = S_DATA;
- timeout = READ_TIMEOUT;
- break;
- }
- case S_DATA:
- flags = stdt_flags() & (FL_STEN|FL_DTEN);
-
-#if DEBUG_STATE
- if (flags != flags_old) {
- flags_old = flags;
- printk(KERN_DEBUG "optcd: flags:%x\n", flags);
- }
- if (flags == FL_STEN)
- printk(KERN_DEBUG "timeout cnt: %d\n", timeout);
-#endif
-
- switch (flags) {
- case FL_DTEN: /* only STEN low */
- if (!tries--) {
- printk(KERN_ERR
- "optcd: read block %d failed; "
- "Giving up\n", next_bn);
- if (transfer_is_active) {
- tries = 0;
- break;
- }
- if (current_valid())
- end_request(CURRENT, 0);
- tries = 5;
- }
- state = S_START;
- timeout = READ_TIMEOUT;
- loop_again = 1;
- case (FL_STEN|FL_DTEN): /* both high */
- break;
- default: /* DTEN low */
- tries = 5;
- if (!current_valid() && buf_in == buf_out) {
- state = S_STOP;
- loop_again = 1;
- break;
- }
- if (read_count<=0)
- printk(KERN_WARNING
- "optcd: warning - try to read"
- " 0 frames\n");
- while (read_count) {
- buf_bn[buf_in] = NOBUF;
- if (!flag_low(FL_DTEN, BUSY_TIMEOUT)) {
- /* should be no waiting here!?? */
- printk(KERN_ERR
- "read_count:%d "
- "CURRENT->nr_sectors:%ld "
- "buf_in:%d\n",
- read_count,
- CURRENT->nr_sectors,
- buf_in);
- printk(KERN_ERR
- "transfer active: %x\n",
- transfer_is_active);
- read_count = 0;
- state = S_STOP;
- loop_again = 1;
- end_request(CURRENT, 0);
- break;
- }
- fetch_data(buf+
- CD_FRAMESIZE*buf_in,
- CD_FRAMESIZE);
- read_count--;
-
- DEBUG((DEBUG_REQUEST,
- "S_DATA; ---I've read data- "
- "read_count: %d",
- read_count));
- DEBUG((DEBUG_REQUEST,
- "next_bn:%d buf_in:%d "
- "buf_out:%d buf_bn:%d",
- next_bn,
- buf_in,
- buf_out,
- buf_bn[buf_in]));
-
- buf_bn[buf_in] = next_bn++;
- if (buf_out == NOBUF)
- buf_out = buf_in;
- buf_in = buf_in + 1 ==
- N_BUFS ? 0 : buf_in + 1;
- }
- if (!transfer_is_active) {
- while (current_valid()) {
- transfer();
- if (CURRENT -> nr_sectors == 0)
- end_request(CURRENT, 1);
- else
- break;
- }
- }
-
- if (current_valid()
- && (CURRENT -> sector / 4 < next_bn ||
- CURRENT -> sector / 4 >
- next_bn + N_BUFS)) {
- state = S_STOP;
- loop_again = 1;
- break;
- }
- timeout = READ_TIMEOUT;
- if (read_count == 0) {
- state = S_STOP;
- loop_again = 1;
- break;
- }
- }
- break;
- case S_STOP:
- if (read_count != 0)
- printk(KERN_ERR
- "optcd: discard data=%x frames\n",
- read_count);
- flush_data();
- if (send_cmd(COMDRVST)) {
- state = S_IDLE;
- while (current_valid())
- end_request(CURRENT, 0);
- return;
- }
- state = S_STOPPING;
- timeout = STOP_TIMEOUT;
- break;
- case S_STOPPING:
- status = fetch_status();
- if (status < 0 && timeout)
- break;
- if ((status >= 0) && (status & ST_DSK_CHG)) {
- toc_uptodate = 0;
- opt_invalidate_buffers();
- }
- if (current_valid()) {
- if (status >= 0) {
- state = S_READ;
- loop_again = 1;
- skip = 1;
- break;
- } else {
- state = S_START;
- timeout = 1;
- }
- } else {
- state = S_IDLE;
- return;
- }
- break;
- default:
- printk(KERN_ERR "optcd: invalid state %d\n", state);
- return;
- } /* case */
- } /* while */
-
- if (!timeout--) {
- printk(KERN_ERR "optcd: timeout in state %d\n", state);
- state = S_STOP;
- if (exec_cmd(COMSTOP) < 0) {
- state = S_IDLE;
- while (current_valid())
- end_request(CURRENT, 0);
- return;
- }
- }
-
- mod_timer(&req_timer, jiffies + HZ/100);
-}
-
-
-static void do_optcd_request(request_queue_t * q)
-{
- DEBUG((DEBUG_REQUEST, "do_optcd_request(%ld+%ld)",
- CURRENT -> sector, CURRENT -> nr_sectors));
-
- if (disk_info.audio) {
- printk(KERN_WARNING "optcd: tried to mount an Audio CD\n");
- end_request(CURRENT, 0);
- return;
- }
-
- transfer_is_active = 1;
- while (current_valid()) {
- transfer(); /* First try to transfer block from buffers */
- if (CURRENT -> nr_sectors == 0) {
- end_request(CURRENT, 1);
- } else { /* Want to read a block not in buffer */
- buf_out = NOBUF;
- if (state == S_IDLE) {
- /* %% Should this block the request queue?? */
- if (update_toc() < 0) {
- while (current_valid())
- end_request(CURRENT, 0);
- break;
- }
- /* Start state machine */
- state = S_START;
- timeout = READ_TIMEOUT;
- tries = 5;
- /* %% why not start right away?? */
- mod_timer(&req_timer, jiffies + HZ/100);
- }
- break;
- }
- }
- transfer_is_active = 0;
-
- DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d buf_out:%d buf_bn:%d",
- next_bn, buf_in, buf_out, buf_bn[buf_in]));
- DEBUG((DEBUG_REQUEST, "do_optcd_request ends"));
-}
-
-/* IOCTLs */
-
-
-static char auto_eject = 0;
-
-static int cdrompause(void)
-{
- int status;
-
- if (audio_status != CDROM_AUDIO_PLAY)
- return -EINVAL;
-
- status = exec_cmd(COMPAUSEON);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEON: %02x", -status));
- return -EIO;
- }
- audio_status = CDROM_AUDIO_PAUSED;
- return 0;
-}
-
-
-static int cdromresume(void)
-{
- int status;
-
- if (audio_status != CDROM_AUDIO_PAUSED)
- return -EINVAL;
-
- status = exec_cmd(COMPAUSEOFF);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEOFF: %02x", -status));
- audio_status = CDROM_AUDIO_ERROR;
- return -EIO;
- }
- audio_status = CDROM_AUDIO_PLAY;
- return 0;
-}
-
-
-static int cdromplaymsf(void __user *arg)
-{
- int status;
- struct cdrom_msf msf;
-
- if (copy_from_user(&msf, arg, sizeof msf))
- return -EFAULT;
-
- bin2bcd(&msf);
- status = exec_long_cmd(COMPLAY, &msf);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
- audio_status = CDROM_AUDIO_ERROR;
- return -EIO;
- }
-
- audio_status = CDROM_AUDIO_PLAY;
- return 0;
-}
-
-
-static int cdromplaytrkind(void __user *arg)
-{
- int status;
- struct cdrom_ti ti;
- struct cdrom_msf msf;
-
- if (copy_from_user(&ti, arg, sizeof ti))
- return -EFAULT;
-
- if (ti.cdti_trk0 < disk_info.first
- || ti.cdti_trk0 > disk_info.last
- || ti.cdti_trk1 < ti.cdti_trk0)
- return -EINVAL;
- if (ti.cdti_trk1 > disk_info.last)
- ti.cdti_trk1 = disk_info.last;
-
- msf.cdmsf_min0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.minute;
- msf.cdmsf_sec0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.second;
- msf.cdmsf_frame0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.frame;
- msf.cdmsf_min1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.minute;
- msf.cdmsf_sec1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.second;
- msf.cdmsf_frame1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.frame;
-
- DEBUG((DEBUG_VFS, "play %02d:%02d.%02d to %02d:%02d.%02d",
- msf.cdmsf_min0,
- msf.cdmsf_sec0,
- msf.cdmsf_frame0,
- msf.cdmsf_min1,
- msf.cdmsf_sec1,
- msf.cdmsf_frame1));
-
- bin2bcd(&msf);
- status = exec_long_cmd(COMPLAY, &msf);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
- audio_status = CDROM_AUDIO_ERROR;
- return -EIO;
- }
-
- audio_status = CDROM_AUDIO_PLAY;
- return 0;
-}
-
-
-static int cdromreadtochdr(void __user *arg)
-{
- struct cdrom_tochdr tochdr;
-
- tochdr.cdth_trk0 = disk_info.first;
- tochdr.cdth_trk1 = disk_info.last;
-
- return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
-}
-
-
-static int cdromreadtocentry(void __user *arg)
-{
- struct cdrom_tocentry entry;
- struct cdrom_subchnl *tocptr;
-
- if (copy_from_user(&entry, arg, sizeof entry))
- return -EFAULT;
-
- if (entry.cdte_track == CDROM_LEADOUT)
- tocptr = &toc[disk_info.last + 1];
- else if (entry.cdte_track > disk_info.last
- || entry.cdte_track < disk_info.first)
- return -EINVAL;
- else
- tocptr = &toc[entry.cdte_track];
-
- entry.cdte_adr = tocptr->cdsc_adr;
- entry.cdte_ctrl = tocptr->cdsc_ctrl;
- entry.cdte_addr.msf.minute = tocptr->cdsc_absaddr.msf.minute;
- entry.cdte_addr.msf.second = tocptr->cdsc_absaddr.msf.second;
- entry.cdte_addr.msf.frame = tocptr->cdsc_absaddr.msf.frame;
- /* %% What should go into entry.cdte_datamode? */
-
- if (entry.cdte_format == CDROM_LBA)
- msf2lba(&entry.cdte_addr);
- else if (entry.cdte_format != CDROM_MSF)
- return -EINVAL;
-
- return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0;
-}
-
-
-static int cdromvolctrl(void __user *arg)
-{
- int status;
- struct cdrom_volctrl volctrl;
- struct cdrom_msf msf;
-
- if (copy_from_user(&volctrl, arg, sizeof volctrl))
- return -EFAULT;
-
- msf.cdmsf_min0 = 0x10;
- msf.cdmsf_sec0 = 0x32;
- msf.cdmsf_frame0 = volctrl.channel0;
- msf.cdmsf_min1 = volctrl.channel1;
- msf.cdmsf_sec1 = volctrl.channel2;
- msf.cdmsf_frame1 = volctrl.channel3;
-
- status = exec_long_cmd(COMCHCTRL, &msf);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_long_cmd COMCHCTRL: %02x", -status));
- return -EIO;
- }
- return 0;
-}
-
-
-static int cdromsubchnl(void __user *arg)
-{
- int status;
- struct cdrom_subchnl subchnl;
-
- if (copy_from_user(&subchnl, arg, sizeof subchnl))
- return -EFAULT;
-
- if (subchnl.cdsc_format != CDROM_LBA
- && subchnl.cdsc_format != CDROM_MSF)
- return -EINVAL;
-
- status = get_q_channel(&subchnl);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "get_q_channel: %02x", -status));
- return -EIO;
- }
-
- if (copy_to_user(arg, &subchnl, sizeof subchnl))
- return -EFAULT;
- return 0;
-}
-
-
-static struct gendisk *optcd_disk;
-
-
-static int cdromread(void __user *arg, int blocksize, int cmd)
-{
- int status;
- struct cdrom_msf msf;
-
- if (copy_from_user(&msf, arg, sizeof msf))
- return -EFAULT;
-
- bin2bcd(&msf);
- msf.cdmsf_min1 = 0;
- msf.cdmsf_sec1 = 0;
- msf.cdmsf_frame1 = 1; /* read only one frame */
- status = exec_read_cmd(cmd, &msf);
-
- DEBUG((DEBUG_VFS, "read cmd status 0x%x", status));
-
- if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT))
- return -EIO;
-
- fetch_data(optcd_disk->private_data, blocksize);
-
- if (copy_to_user(arg, optcd_disk->private_data, blocksize))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int cdromseek(void __user *arg)
-{
- int status;
- struct cdrom_msf msf;
-
- if (copy_from_user(&msf, arg, sizeof msf))
- return -EFAULT;
-
- bin2bcd(&msf);
- status = exec_seek_cmd(COMSEEK, &msf);
-
- DEBUG((DEBUG_VFS, "COMSEEK status 0x%x", status));
-
- if (status < 0)
- return -EIO;
- return 0;
-}
-
-
-#ifdef MULTISESSION
-static int cdrommultisession(void __user *arg)
-{
- struct cdrom_multisession ms;
-
- if (copy_from_user(&ms, arg, sizeof ms))
- return -EFAULT;
-
- ms.addr.msf.minute = disk_info.last_session.minute;
- ms.addr.msf.second = disk_info.last_session.second;
- ms.addr.msf.frame = disk_info.last_session.frame;
-
- if (ms.addr_format != CDROM_LBA
- && ms.addr_format != CDROM_MSF)
- return -EINVAL;
- if (ms.addr_format == CDROM_LBA)
- msf2lba(&ms.addr);
-
- ms.xa_flag = disk_info.xa;
-
- if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession)))
- return -EFAULT;
-
-#if DEBUG_MULTIS
- if (ms.addr_format == CDROM_MSF)
- printk(KERN_DEBUG
- "optcd: multisession xa:%d, msf:%02d:%02d.%02d\n",
- ms.xa_flag,
- ms.addr.msf.minute,
- ms.addr.msf.second,
- ms.addr.msf.frame);
- else
- printk(KERN_DEBUG
- "optcd: multisession %d, lba:0x%08x [%02d:%02d.%02d])\n",
- ms.xa_flag,
- ms.addr.lba,
- disk_info.last_session.minute,
- disk_info.last_session.second,
- disk_info.last_session.frame);
-#endif /* DEBUG_MULTIS */
-
- return 0;
-}
-#endif /* MULTISESSION */
-
-
-static int cdromreset(void)
-{
- if (state != S_IDLE) {
- error = 1;
- tries = 0;
- }
-
- toc_uptodate = 0;
- disk_changed = 1;
- opt_invalidate_buffers();
- audio_status = CDROM_AUDIO_NO_STATUS;
-
- if (!reset_drive())
- return -EIO;
- return 0;
-}
-
-/* VFS calls */
-
-
-static int opt_ioctl(struct inode *ip, struct file *fp,
- unsigned int cmd, unsigned long arg)
-{
- int status, err, retval = 0;
- void __user *argp = (void __user *)arg;
-
- DEBUG((DEBUG_VFS, "starting opt_ioctl"));
-
- if (!ip)
- return -EINVAL;
-
- if (cmd == CDROMRESET)
- return cdromreset();
-
- /* is do_optcd_request or another ioctl busy? */
- if (state != S_IDLE || in_vfs)
- return -EBUSY;
-
- in_vfs = 1;
-
- status = drive_status();
- if (status < 0) {
- DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
- in_vfs = 0;
- return -EIO;
- }
-
- if (status & ST_DOOR_OPEN)
- switch (cmd) { /* Actions that can be taken with door open */
- case CDROMCLOSETRAY:
- /* We do this before trying to read the toc. */
- err = exec_cmd(COMCLOSE);
- if (err < 0) {
- DEBUG((DEBUG_VFS,
- "exec_cmd COMCLOSE: %02x", -err));
- in_vfs = 0;
- return -EIO;
- }
- break;
- default: in_vfs = 0;
- return -EBUSY;
- }
-
- err = update_toc();
- if (err < 0) {
- DEBUG((DEBUG_VFS, "update_toc: %02x", -err));
- in_vfs = 0;
- return -EIO;
- }
-
- DEBUG((DEBUG_VFS, "ioctl cmd 0x%x", cmd));
-
- switch (cmd) {
- case CDROMPAUSE: retval = cdrompause(); break;
- case CDROMRESUME: retval = cdromresume(); break;
- case CDROMPLAYMSF: retval = cdromplaymsf(argp); break;
- case CDROMPLAYTRKIND: retval = cdromplaytrkind(argp); break;
- case CDROMREADTOCHDR: retval = cdromreadtochdr(argp); break;
- case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break;
-
- case CDROMSTOP: err = exec_cmd(COMSTOP);
- if (err < 0) {
- DEBUG((DEBUG_VFS,
- "exec_cmd COMSTOP: %02x",
- -err));
- retval = -EIO;
- } else
- audio_status = CDROM_AUDIO_NO_STATUS;
- break;
- case CDROMSTART: break; /* This is a no-op */
- case CDROMEJECT: err = exec_cmd(COMUNLOCK);
- if (err < 0) {
- DEBUG((DEBUG_VFS,
- "exec_cmd COMUNLOCK: %02x",
- -err));
- retval = -EIO;
- break;
- }
- err = exec_cmd(COMOPEN);
- if (err < 0) {
- DEBUG((DEBUG_VFS,
- "exec_cmd COMOPEN: %02x",
- -err));
- retval = -EIO;
- }
- break;
-
- case CDROMVOLCTRL: retval = cdromvolctrl(argp); break;
- case CDROMSUBCHNL: retval = cdromsubchnl(argp); break;
-
- /* The drive detects the mode and automatically delivers the
- correct 2048 bytes, so we don't need these IOCTLs */
- case CDROMREADMODE2: retval = -EINVAL; break;
- case CDROMREADMODE1: retval = -EINVAL; break;
-
- /* Drive doesn't support reading audio */
- case CDROMREADAUDIO: retval = -EINVAL; break;
-
- case CDROMEJECT_SW: auto_eject = (char) arg;
- break;
-
-#ifdef MULTISESSION
- case CDROMMULTISESSION: retval = cdrommultisession(argp); break;
-#endif
-
- case CDROM_GET_MCN: retval = -EINVAL; break; /* not implemented */
- case CDROMVOLREAD: retval = -EINVAL; break; /* not implemented */
-
- case CDROMREADRAW:
- /* this drive delivers 2340 bytes in raw mode */
- retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW);
- break;
- case CDROMREADCOOKED:
- retval = cdromread(argp, CD_FRAMESIZE, COMREAD);
- break;
- case CDROMREADALL:
- retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL);
- break;
-
- case CDROMSEEK: retval = cdromseek(argp); break;
- case CDROMPLAYBLK: retval = -EINVAL; break; /* not implemented */
- case CDROMCLOSETRAY: break; /* The action was taken earlier */
- default: retval = -EINVAL;
- }
- in_vfs = 0;
- return retval;
-}
-
-
-static int open_count = 0;
-
-/* Open device special file; check that a disk is in. */
-static int opt_open(struct inode *ip, struct file *fp)
-{
- DEBUG((DEBUG_VFS, "starting opt_open"));
-
- if (!open_count && state == S_IDLE) {
- int status;
- char *buf;
-
- buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL);
- if (!buf) {
- printk(KERN_INFO "optcd: cannot allocate read buffer\n");
- return -ENOMEM;
- }
- optcd_disk->private_data = buf; /* save read buffer */
-
- toc_uptodate = 0;
- opt_invalidate_buffers();
-
- status = exec_cmd(COMCLOSE); /* close door */
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_cmd COMCLOSE: %02x", -status));
- }
-
- status = drive_status();
- if (status < 0) {
- DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
- goto err_out;
- }
- DEBUG((DEBUG_VFS, "status: %02x", status));
- if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
- printk(KERN_INFO "optcd: no disk or door open\n");
- goto err_out;
- }
- status = exec_cmd(COMLOCK); /* Lock door */
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_cmd COMLOCK: %02x", -status));
- }
- status = update_toc(); /* Read table of contents */
- if (status < 0) {
- DEBUG((DEBUG_VFS, "update_toc: %02x", -status));
- status = exec_cmd(COMUNLOCK); /* Unlock door */
- if (status < 0) {
- DEBUG((DEBUG_VFS,
- "exec_cmd COMUNLOCK: %02x", -status));
- }
- goto err_out;
- }
- open_count++;
- }
-
- DEBUG((DEBUG_VFS, "exiting opt_open"));
-
- return 0;
-
-err_out:
- return -EIO;
-}
-
-
-/* Release device special file; flush all blocks from the buffer cache */
-static int opt_release(struct inode *ip, struct file *fp)
-{
- int status;
-
- DEBUG((DEBUG_VFS, "executing opt_release"));
- DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n",
- ip, ip->i_bdev->bd_disk->disk_name, fp));
-
- if (!--open_count) {
- toc_uptodate = 0;
- opt_invalidate_buffers();
- status = exec_cmd(COMUNLOCK); /* Unlock door */
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status));
- }
- if (auto_eject) {
- status = exec_cmd(COMOPEN);
- DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status));
- }
- kfree(optcd_disk->private_data);
- del_timer(&delay_timer);
- del_timer(&req_timer);
- }
- return 0;
-}
-
-
-/* Check if disk has been changed */
-static int opt_media_change(struct gendisk *disk)
-{
- DEBUG((DEBUG_VFS, "executing opt_media_change"));
- DEBUG((DEBUG_VFS, "dev: %s; disk_changed = %d\n",
- disk->disk_name, disk_changed));
-
- if (disk_changed) {
- disk_changed = 0;
- return 1;
- }
- return 0;
-}
-
-/* Driver initialisation */
-
-
-/* Returns 1 if a drive is detected with a version string
- starting with "DOLPHIN". Otherwise 0. */
-static int __init version_ok(void)
-{
- char devname[100];
- int count, i, ch, status;
-
- status = exec_cmd(COMVERSION);
- if (status < 0) {
- DEBUG((DEBUG_VFS, "exec_cmd COMVERSION: %02x", -status));
- return 0;
- }
- if ((count = get_data(1)) < 0) {
- DEBUG((DEBUG_VFS, "get_data(1): %02x", -count));
- return 0;
- }
- for (i = 0, ch = -1; count > 0; count--) {
- if ((ch = get_data(1)) < 0) {
- DEBUG((DEBUG_VFS, "get_data(1): %02x", -ch));
- break;
- }
- if (i < 99)
- devname[i++] = ch;
- }
- devname[i] = '\0';
- if (ch < 0)
- return 0;
-
- printk(KERN_INFO "optcd: Device %s detected\n", devname);
- return ((devname[0] == 'D')
- && (devname[1] == 'O')
- && (devname[2] == 'L')
- && (devname[3] == 'P')
- && (devname[4] == 'H')
- && (devname[5] == 'I')
- && (devname[6] == 'N'));
-}
-
-
-static struct block_device_operations opt_fops = {
- .owner = THIS_MODULE,
- .open = opt_open,
- .release = opt_release,
- .ioctl = opt_ioctl,
- .media_changed = opt_media_change,
-};
-
-#ifndef MODULE
-/* Get kernel parameter when used as a kernel driver */
-static int optcd_setup(char *str)
-{
- int ints[4];
- (void)get_options(str, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0)
- optcd_port = ints[1];
-
- return 1;
-}
-
-__setup("optcd=", optcd_setup);
-
-#endif /* MODULE */
-
-/* Test for presence of drive and initialize it. Called at boot time
- or during module initialisation. */
-static int __init optcd_init(void)
-{
- int status;
-
- if (optcd_port <= 0) {
- printk(KERN_INFO
- "optcd: no Optics Storage CDROM Initialization\n");
- return -EIO;
- }
- optcd_disk = alloc_disk(1);
- if (!optcd_disk) {
- printk(KERN_ERR "optcd: can't allocate disk\n");
- return -ENOMEM;
- }
- optcd_disk->major = MAJOR_NR;
- optcd_disk->first_minor = 0;
- optcd_disk->fops = &opt_fops;
- sprintf(optcd_disk->disk_name, "optcd");
-
- if (!request_region(optcd_port, 4, "optcd")) {
- printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
- optcd_port);
- put_disk(optcd_disk);
- return -EIO;
- }
-
- if (!reset_drive()) {
- printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
- release_region(optcd_port, 4);
- put_disk(optcd_disk);
- return -EIO;
- }
- if (!version_ok()) {
- printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
- release_region(optcd_port, 4);
- put_disk(optcd_disk);
- return -EIO;
- }
- status = exec_cmd(COMINITDOUBLE);
- if (status < 0) {
- printk(KERN_ERR "optcd: cannot init double speed mode\n");
- release_region(optcd_port, 4);
- DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
- put_disk(optcd_disk);
- return -EIO;
- }
- if (register_blkdev(MAJOR_NR, "optcd")) {
- release_region(optcd_port, 4);
- put_disk(optcd_disk);
- return -EIO;
- }
-
-
- opt_queue = blk_init_queue(do_optcd_request, &optcd_lock);
- if (!opt_queue) {
- unregister_blkdev(MAJOR_NR, "optcd");
- release_region(optcd_port, 4);
- put_disk(optcd_disk);
- return -ENOMEM;
- }
-
- blk_queue_hardsect_size(opt_queue, 2048);
- optcd_disk->queue = opt_queue;
- add_disk(optcd_disk);
-
- printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
- return 0;
-}
-
-
-static void __exit optcd_exit(void)
-{
- del_gendisk(optcd_disk);
- put_disk(optcd_disk);
- if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) {
- printk(KERN_ERR "optcd: what's that: can't unregister\n");
- return;
- }
- blk_cleanup_queue(opt_queue);
- release_region(optcd_port, 4);
- printk(KERN_INFO "optcd: module released.\n");
-}
-
-module_init(optcd_init);
-module_exit(optcd_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR);
diff --git a/drivers/cdrom/optcd.h b/drivers/cdrom/optcd.h
deleted file mode 100644
index 1911bb92ee28..000000000000
--- a/drivers/cdrom/optcd.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver
- $Id: optcd.h,v 1.2 1996/01/15 18:43:44 root Exp root $
-
- Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
-
-
- Configuration file for linux/drivers/cdrom/optcd.c
-*/
-
-#ifndef _LINUX_OPTCD_H
-#define _LINUX_OPTCD_H
-
-
-/* I/O base of drive. Drive uses base to base+2.
- This setting can be overridden with the kernel or insmod command
- line option 'optcd=<portbase>'. Use address of 0 to disable driver. */
-#define OPTCD_PORTBASE 0x340
-
-
-/* enable / disable parts of driver by define / undef */
-#define MULTISESSION /* multisession support (ALPHA) */
-
-
-/* Change 0 to 1 to debug various parts of the driver */
-#define DEBUG_DRIVE_IF 0 /* Low level drive interface */
-#define DEBUG_CONV 0 /* Address conversions */
-#define DEBUG_BUFFERS 0 /* Buffering and block size conversion */
-#define DEBUG_REQUEST 0 /* Request mechanism */
-#define DEBUG_STATE 0 /* State machine */
-#define DEBUG_TOC 0 /* Q-channel and Table of Contents */
-#define DEBUG_MULTIS 0 /* Multisession code */
-#define DEBUG_VFS 0 /* VFS interface */
-
-
-/* Don't touch these unless you know what you're doing. */
-
-/* Various timeout loop repetition counts. */
-#define BUSY_TIMEOUT 10000000 /* for busy wait */
-#define FAST_TIMEOUT 100000 /* ibid. for probing */
-#define SLEEP_TIMEOUT 6000 /* for timer wait */
-#define MULTI_SEEK_TIMEOUT 1000 /* for timer wait */
-#define READ_TIMEOUT 6000 /* for poll wait */
-#define STOP_TIMEOUT 2000 /* for poll wait */
-#define RESET_WAIT 5000 /* busy wait at drive reset */
-
-/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
- giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
- setting */
-#define N_BUFS 6
-
-
-#endif /* _LINUX_OPTCD_H */
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
deleted file mode 100644
index a1283b1ef989..000000000000
--- a/drivers/cdrom/sbpcd.c
+++ /dev/null
@@ -1,5966 +0,0 @@
-/*
- * sbpcd.c CD-ROM device driver for the whole family of traditional,
- * non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives.
- * Works with SoundBlaster compatible cards and with "no-sound"
- * interface cards like Lasermate, Panasonic CI-101P, Teac, ...
- * Also for the Longshine LCS-7260 drive.
- * Also for the IBM "External ISA CD-Rom" drive.
- * Also for the CreativeLabs CD200 drive.
- * Also for the TEAC CD-55A drive.
- * Also for the ECS-AT "Vertos 100" drive.
- * Not for Sanyo drives (but for the H94A, sjcd is there...).
- * Not for any other Funai drives than the CD200 types (sometimes
- * labelled E2550UA or MK4015 or 2800F).
- */
-
-#define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"
-
-/* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg <emoenke@gwdg.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * If you change this software, you should mail a .diff file with some
- * description lines to emoenke@gwdg.de. I want to know about it.
- *
- * If you are the editor of a Linux CD, you should enable sbpcd.c within
- * your boot floppy kernel and send me one of your CDs for free.
- *
- * If you would like to port the driver to an other operating system (f.e.
- * FreeBSD or NetBSD) or use it as an information source, you shall not be
- * restricted by the GPL under the following conditions:
- * a) the source code of your work is freely available
- * b) my part of the work gets mentioned at all places where your
- * authorship gets mentioned
- * c) I receive a copy of your code together with a full installation
- * package of your operating system for free.
- *
- *
- * VERSION HISTORY
- *
- * 0.1 initial release, April/May 93, after mcd.c (Martin Harriss)
- *
- * 0.2 thek "repeat:"-loop in do_sbpcd_request did not check for
- * end-of-request_queue (resulting in kernel panic).
- * Flow control seems stable, but throughput is not better.
- *
- * 0.3 interrupt locking totally eliminated (maybe "inb" and "outb"
- * are still locking) - 0.2 made keyboard-type-ahead losses.
- * check_sbpcd_media_change added (to use by isofs/inode.c)
- * - but it detects almost nothing.
- *
- * 0.4 use MAJOR 25 definitely.
- * Almost total re-design to support double-speed drives and
- * "naked" (no sound) interface cards ("LaserMate" interface type).
- * Flow control should be exact now.
- * Don't occupy the SbPro IRQ line (not needed either); will
- * live together with Hannu Savolainen's sndkit now.
- * Speeded up data transfer to 150 kB/sec, with help from Kai
- * Makisara, the "provider" of the "mt" tape utility.
- * Give "SpinUp" command if necessary.
- * First steps to support up to 4 drives (but currently only one).
- * Implemented audio capabilities - workman should work, xcdplayer
- * gives some problems.
- * This version is still consuming too much CPU time, and
- * sleeping still has to be worked on.
- * During "long" implied seeks, it seems possible that a
- * ReadStatus command gets ignored. That gives the message
- * "ResponseStatus timed out" (happens about 6 times here during
- * a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
- * handled without data error, but it should get done better.
- *
- * 0.5 Free CPU during waits (again with help from Kai Makisara).
- * Made it work together with the LILO/kernel setup standard.
- * Included auto-probing code, as suggested by YGGDRASIL.
- * Formal redesign to add DDI debugging.
- * There are still flaws in IOCTL (workman with double speed drive).
- *
- * 1.0 Added support for all drive IDs (0...3, no longer only 0)
- * and up to 4 drives on one controller.
- * Added "#define MANY_SESSION" for "old" multi session CDs.
- *
- * 1.1 Do SpinUp for new drives, too.
- * Revised for clean compile under "old" kernels (0.99pl9).
- *
- * 1.2 Found the "workman with double-speed drive" bug: use the driver's
- * audio_state, not what the drive is reporting with ReadSubQ.
- *
- * 1.3 Minor cleanups.
- * Refinements regarding Workman.
- *
- * 1.4 Read XA disks (PhotoCDs) with "old" drives, too (but only the first
- * session - no chance to fully access a "multi-session" CD).
- * This currently still is too slow (50 kB/sec) - but possibly
- * the old drives won't do it faster.
- * Implemented "door (un)lock" for new drives (still does not work
- * as wanted - no lock possible after an unlock).
- * Added some debugging printout for the UPC/EAN code - but my drives
- * return only zeroes. Is there no UPC/EAN code written?
- *
- * 1.5 Laborate with UPC/EAN code (not better yet).
- * Adapt to kernel 1.1.8 change (have to explicitly include
- * <linux/string.h> now).
- *
- * 1.6 Trying to read audio frames as data. Impossible with the current
- * drive firmware levels, as it seems. Awaiting any hint. ;-)
- * Changed "door unlock": repeat it until success.
- * Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
- * won't get confused).
- * Added a third interface type: Sequoia S-1000, as used with the SPEA
- * Media FX sound card. This interface (usable for Sony and Mitsumi
- * drives, too) needs a special configuration setup and behaves like a
- * LaserMate type after that. Still experimental - I do not have such
- * an interface.
- * Use the "variable BLOCK_SIZE" feature (2048). But it does only work
- * if you give the mount option "block=2048".
- * The media_check routine is currently disabled; now that it gets
- * called as it should I fear it must get synchronized for not to
- * disturb the normal driver's activity.
- *
- * 2.0 Version number bumped - two reasons:
- * - reading audio tracks as data works now with CR-562 and CR-563. We
- * currently do it by an IOCTL (yet has to get standardized), one frame
- * at a time; that is pretty slow. But it works.
- * - we are maintaining now up to 4 interfaces (each up to 4 drives):
- * did it the easy way - a different MAJOR (25, 26, ...) and a different
- * copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
- * distinguished by the value of SBPCD_ISSUE and the driver's name),
- * and a common sbpcd.h file.
- * Bettered the "ReadCapacity error" problem with old CR-52x drives (the
- * drives sometimes need a manual "eject/insert" before work): just
- * reset the drive and do again. Needs lots of resets here and sometimes
- * that does not cure, so this can't be the solution.
- *
- * 2.1 Found bug with multisession CDs (accessing frame 16).
- * "read audio" works now with address type CDROM_MSF, too.
- * Bigger audio frame buffer: allows reading max. 4 frames at time; this
- * gives a significant speedup, but reading more than one frame at once
- * gives missing chunks at each single frame boundary.
- *
- * 2.2 Kernel interface cleanups: timers, init, setup, media check.
- *
- * 2.3 Let "door lock" and "eject" live together.
- * Implemented "close tray" (done automatically during open).
- *
- * 2.4 Use different names for device registering.
- *
- * 2.5 Added "#if EJECT" code (default: enabled) to automatically eject
- * the tray during last call to "sbpcd_release".
- * Added "#if JUKEBOX" code (default: disabled) to automatically eject
- * the tray during call to "sbpcd_open" if no disk is in.
- * Turn on the CD volume of "compatible" sound cards, too; just define
- * SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
- *
- * 2.6 Nothing new.
- *
- * 2.7 Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
- * 0 disables, 1 enables auto-ejecting. Useful to keep the tray in
- * during shutdown.
- *
- * 2.8 Added first support (still BETA, I need feedback or a drive) for
- * the Longshine LCS-7260 drives. They appear as double-speed drives
- * using the "old" command scheme, extended by tray control and door
- * lock functions.
- * Found (and fixed preliminary) a flaw with some multisession CDs: we
- * have to re-direct not only the accesses to frame 16 (the isofs
- * routines drive it up to max. 100), but also those to the continuation
- * (repetition) frames (as far as they exist - currently set fix as
- * 16..20).
- * Changed default of the "JUKEBOX" define. If you use this default,
- * your tray will eject if you try to mount without a disk in. Next
- * mount command will insert the tray - so, just fill in a disk. ;-)
- *
- * 2.9 Fulfilled the Longshine LCS-7260 support; with great help and
- * experiments by Serge Robyns.
- * First attempts to support the TEAC CD-55A drives; but still not
- * usable yet.
- * Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
- * multi session CDs more "transparent" (redirection handling has to be
- * done within the isofs routines, and only for the special purpose of
- * obtaining the "right" volume descriptor; accesses to the raw device
- * should not get redirected).
- *
- * 3.0 Just a "normal" increment, with some provisions to do it better. ;-)
- * Introduced "#define READ_AUDIO" to specify the maximum number of
- * audio frames to grab with one request. This defines a buffer size
- * within kernel space; a value of 0 will reserve no such space and
- * disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
- * of a whole second with one command, but will use a buffer of more
- * than 172 kB.
- * Started CD200 support. Drive detection should work, but nothing
- * more.
- *
- * 3.1 Working to support the CD200 and the Teac CD-55A drives.
- * AT-BUS style device numbering no longer used: use SCSI style now.
- * So, the first "found" device has MINOR 0, regardless of the
- * jumpered drive ID. This implies modifications to the /dev/sbpcd*
- * entries for some people, but will help the DAU (german TLA, english:
- * "newbie", maybe ;-) to install his "first" system from a CD.
- *
- * 3.2 Still testing with CD200 and CD-55A drives.
- *
- * 3.3 Working with CD200 support.
- *
- * 3.4 Auto-probing stops if an address of 0 is seen (to be entered with
- * the kernel command line).
- * Made the driver "loadable". If used as a module, "audio copy" is
- * disabled, and the internal read ahead data buffer has a reduced size
- * of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
- *
- * 3.5 Provisions to handle weird photoCDs which have an interrupted
- * "formatting" immediately after the last frames of some files: simply
- * never "read ahead" with MultiSession CDs. By this, CPU usage may be
- * increased with those CDs, and there may be a loss in speed.
- * Re-structured the messaging system.
- * The "loadable" version no longer has a limited READ_AUDIO buffer
- * size.
- * Removed "MANY_SESSION" handling for "old" multi session CDs.
- * Added "private" IOCTLs CDROMRESET and CDROMVOLREAD.
- * Started again to support the TEAC CD-55A drives, now that I found
- * the money for "my own" drive. ;-)
- * The TEAC CD-55A support is fairly working now.
- * I have measured that the drive "delivers" at 600 kB/sec (even with
- * bigger requests than the drive's 64 kB buffer can satisfy), but
- * the "real" rate does not exceed 520 kB/sec at the moment.
- * Caused by the various changes to build in TEAC support, the timed
- * loops are de-optimized at the moment (less throughput with CR-52x
- * drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64).
- *
- * 3.6 Fixed TEAC data read problems with SbPro interfaces.
- * Initial size of the READ_AUDIO buffer is 0. Can get set to any size
- * during runtime.
- *
- * 3.7 Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
- * drives) which allow only one drive (ID 0); this avoids repetitive
- * detection under IDs 1..3.
- * Elongated cmd_out_T response waiting; necessary for photo CDs with
- * a lot of sessions.
- * Bettered the sbpcd_open() behavior with TEAC drives.
- *
- * 3.8 Elongated max_latency for CR-56x drives.
- *
- * 3.9 Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface
- * configuration bug.
- * Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
- * the config_spea() routine into their drivers. ;-)
- *
- * 4.0 No "big step" - normal version increment.
- * Adapted the benefits from 1.3.33.
- * Fiddled with CDROMREADAUDIO flaws.
- * Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
- * seems not to support it).
- * Fulfilled "read audio" for CD200 drives, with help of Pete Heist
- * (heistp@rpi.edu).
- *
- * 4.1 Use loglevel KERN_INFO with printk().
- * Added support for "Vertos 100" drive ("ECS-AT") - it is very similar
- * to the Longshine LCS-7260. Give feedback if you can - I never saw
- * such a drive, and I have no specs.
- *
- * 4.2 Support for Teac 16-bit interface cards. Can't get auto-detected,
- * so you have to jumper your card to 0x2C0. Still not 100% - come
- * in contact if you can give qualified feedback.
- * Use loglevel KERN_NOTICE with printk(). If you get annoyed by a
- * flood of unwanted messages and the accompanied delay, try to read
- * my documentation. Especially the Linux CDROM drivers have to do an
- * important job for the newcomers, so the "distributed" version has
- * to fit some special needs. Since generations, the flood of messages
- * is user-configurable (even at runtime), but to get aware of this, one
- * needs a special mental quality: the ability to read.
- *
- * 4.3 CD200F does not like to receive a command while the drive is
- * reading the ToC; still trying to solve it.
- * Removed some redundant verify_area calls (yes, Heiko Eissfeldt
- * is visiting all the Linux CDROM drivers ;-).
- *
- * 4.4 Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down"
- * experiments: "KLOGD_PAUSE".
- * Inhibited "play audio" attempts with data CDs. Provisions for a
- * "data-safe" handling of "mixed" (data plus audio) Cds.
- *
- * 4.5 Meanwhile Gonzalo Tornaria <tornaria@cmat.edu.uy> (GTL) built a
- * special end_request routine: we seem to have to take care for not
- * to have two processes working at the request list. My understanding
- * was and is that ll_rw_blk should not call do_sbpcd_request as long
- * as there is still one call active (the first call will care for all
- * outstanding I/Os, and if a second call happens, that is a bug in
- * ll_rw_blk.c).
- * "Check media change" without touching any drive.
- *
- * 4.6 Use a semaphore to synchronize multi-activity; elaborated by Rob
- * Riggs <rriggs@tesser.com>. At the moment, we simply block "read"
- * against "ioctl" and vice versa. This could be refined further, but
- * I guess with almost no performance increase.
- * Experiments to speed up the CD-55A; again with help of Rob Riggs
- * (to be true, he gave both, idea & code. ;-)
- *
- * 4.61 Ported to Uniform CD-ROM driver by
- * Heiko Eissfeldt <heiko@colossus.escape.de> with additional
- * changes by Erik Andersen <andersee@debian.org>
- *
- * 4.62 Fix a bug where playing audio left the drive in an unusable state.
- * Heiko Eissfeldt <heiko@colossus.escape.de>
- *
- * November 1999 -- Make kernel-parameter implementation work with 2.3.x
- * Removed init_module & cleanup_module in favor of
- * module_init & module_exit.
- * Torben Mathiasen <tmm@image.dk>
- *
- * 4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer.
- * Annoying things fixed:
- * TOC reread on automated disk changes
- * TOC reread on manual cd changes
- * Play IOCTL tries to play CD before it's actually ready... sometimes.
- * CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
- * Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
- *
- * 4.64 Fix module parameters - were being completely ignored.
- * Can also specify max_drives=N as a setup int to get rid of
- * "ghost" drives on crap hardware (aren't they all?) Paul Gortmaker
- *
- * TODO
- * implement "read all subchannel data" (96 bytes per frame)
- * remove alot of the virtual status bits and deal with hardware status
- * move the change of cd for audio to a better place
- * add debug levels to insmod parameters (trivial)
- *
- * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
- * elaborated speed-up experiments (and the fabulous results!), for
- * the "push" towards load-free wait loops, and for the extensive mail
- * thread which brought additional hints and bug fixes.
- *
- */
-
-/*
- * Trying to merge requests breaks this driver horribly (as in it goes
- * boom and apparently has done so since 2.3.41). As it is a legacy
- * driver for a horribly slow double speed CD on a hideous interface
- * designed for polled operation, I won't lose any sleep in simply
- * disallowing merging. Paul G. 02/2001
- *
- * Thu May 30 14:14:47 CEST 2002:
- *
- * I have presumably found the reson for the above - there was a bogous
- * end_request substitute, which was manipulating the request queues
- * incorrectly. If someone has access to the actual hardware, and it's
- * still operations - well please free to test it.
- *
- * Marcin Dalecki
- */
-
-/*
- * Add bio/kdev_t changes for 2.5.x required to make it work again.
- * Still room for improvement in the request handling here if anyone
- * actually cares. Bring your own chainsaw. Paul G. 02/2002
- */
-
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <stdarg.h>
-#include "sbpcd.h"
-
-#define MAJOR_NR MATSUSHITA_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-/*==========================================================================*/
-#if SBPCD_DIS_IRQ
-# define SBPCD_CLI cli()
-# define SBPCD_STI sti()
-#else
-# define SBPCD_CLI
-# define SBPCD_STI
-#endif
-
-/*==========================================================================*/
-/*
- * auto-probing address list
- * inspired by Adam J. Richter from Yggdrasil
- *
- * still not good enough - can cause a hang.
- * example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
- * if that happens, reboot and use the LILO (kernel) command line.
- * The possibly conflicting ethernet card addresses get NOT probed
- * by default - to minimize the hang possibilities.
- *
- * The SB Pro addresses get "mirrored" at 0x6xx and some more locations - to
- * avoid a type error, the 0x2xx-addresses must get checked before 0x6xx.
- *
- * send mail to emoenke@gwdg.de if your interface card is not FULLY
- * represented here.
- */
-static int sbpcd[] =
-{
- CDROM_PORT, SBPRO, /* probe with user's setup first */
-#if DISTRIBUTION
- 0x230, 1, /* Soundblaster Pro and 16 (default) */
-#if 0
- 0x300, 0, /* CI-101P (default), WDH-7001C (default),
- Galaxy (default), Reveal (one default) */
- 0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
- 0x2C0, 3, /* Teac 16-bit cards */
- 0x260, 1, /* OmniCD */
- 0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default),
- Longshine LCS-6853 (default) */
- 0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */
- 0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */
- 0x360, 0, /* Lasermate, CI-101P */
- 0x270, 1, /* Soundblaster 16 */
- 0x670, 0, /* "sound card #9" */
- 0x690, 0, /* "sound card #9" */
- 0x338, 2, /* SPEA Media FX, Ensonic SoundScape (default) */
- 0x328, 2, /* SPEA Media FX */
- 0x348, 2, /* SPEA Media FX */
- 0x634, 0, /* some newer sound cards */
- 0x638, 0, /* some newer sound cards */
- 0x230, 1, /* some newer sound cards */
- /* due to incomplete address decoding of the SbPro card, these must be last */
- 0x630, 0, /* "sound card #9" (default) */
- 0x650, 0, /* "sound card #9" */
-#ifdef MODULE
- /*
- * some "hazardous" locations (no harm with the loadable version)
- * (will stop the bus if a NE2000 ethernet card resides at offset -0x10)
- */
- 0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
- 0x350, 0, /* Lasermate, CI-101P */
- 0x358, 2, /* SPEA Media FX */
- 0x370, 0, /* Lasermate, CI-101P */
- 0x290, 1, /* Soundblaster 16 */
- 0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
-#endif /* MODULE */
-#endif
-#endif /* DISTRIBUTION */
-};
-
-/*
- * Protects access to global structures etc.
- */
-static __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock);
-static struct request_queue *sbpcd_queue;
-
-/* You can only set the first pair, from old MODULE_PARM code. */
-static int sbpcd_set(const char *val, struct kernel_param *kp)
-{
- get_options((char *)val, 2, (int *)sbpcd);
- return 0;
-}
-module_param_call(sbpcd, sbpcd_set, NULL, NULL, 0);
-
-#define NUM_PROBE (sizeof(sbpcd) / sizeof(int))
-
-/*==========================================================================*/
-
-#define INLINE inline
-
-/*==========================================================================*/
-/*
- * the forward references:
- */
-static void sbp_sleep(u_int);
-static void mark_timeout_delay(u_long);
-static void mark_timeout_data(u_long);
-#if 0
-static void mark_timeout_audio(u_long);
-#endif
-static void sbp_read_cmd(struct request *req);
-static int sbp_data(struct request *req);
-static int cmd_out(void);
-static int DiskInfo(void);
-
-/*==========================================================================*/
-
-/*
- * pattern for printk selection:
- *
- * (1<<DBG_INF) necessary information
- * (1<<DBG_BSZ) BLOCK_SIZE trace
- * (1<<DBG_REA) "read" status trace
- * (1<<DBG_CHK) "media check" trace
- * (1<<DBG_TIM) datarate timer test
- * (1<<DBG_INI) initialization trace
- * (1<<DBG_TOC) tell TocEntry values
- * (1<<DBG_IOC) ioctl trace
- * (1<<DBG_STA) "ResponseStatus" trace
- * (1<<DBG_ERR) "cc_ReadError" trace
- * (1<<DBG_CMD) "cmd_out" trace
- * (1<<DBG_WRN) give explanation before auto-probing
- * (1<<DBG_MUL) multi session code test
- * (1<<DBG_IDX) "drive_id != 0" test code
- * (1<<DBG_IOX) some special information
- * (1<<DBG_DID) drive ID test
- * (1<<DBG_RES) drive reset info
- * (1<<DBG_SPI) SpinUp test info
- * (1<<DBG_IOS) ioctl trace: "subchannel"
- * (1<<DBG_IO2) ioctl trace: general
- * (1<<DBG_UPC) show UPC info
- * (1<<DBG_XA1) XA mode debugging
- * (1<<DBG_LCK) door (un)lock info
- * (1<<DBG_SQ1) dump SubQ frame
- * (1<<DBG_AUD) "read audio" debugging
- * (1<<DBG_SEQ) Sequoia interface configuration trace
- * (1<<DBG_LCS) Longshine LCS-7260 debugging trace
- * (1<<DBG_CD2) MKE/Funai CD200 debugging trace
- * (1<<DBG_TEA) TEAC CD-55A debugging trace
- * (1<<DBG_ECS) ECS-AT (Vertos-100) debugging trace
- * (1<<DBG_000) unnecessary information
- */
-#if DISTRIBUTION
-static int sbpcd_debug = (1<<DBG_INF);
-#else
-static int sbpcd_debug = 0 & ((1<<DBG_INF) |
- (1<<DBG_TOC) |
- (1<<DBG_MUL) |
- (1<<DBG_UPC));
-#endif /* DISTRIBUTION */
-
-static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */
-static int sbpro_type = SBPRO;
-static unsigned char f_16bit;
-static unsigned char do_16bit;
-static int CDo_command, CDo_reset;
-static int CDo_sel_i_d, CDo_enable;
-static int CDi_info, CDi_status, CDi_data;
-static struct cdrom_msf msf;
-static struct cdrom_ti ti;
-static struct cdrom_tochdr tochdr;
-static struct cdrom_tocentry tocentry;
-static struct cdrom_subchnl SC;
-static struct cdrom_volctrl volctrl;
-static struct cdrom_read_audio read_audio;
-
-static unsigned char msgnum;
-static char msgbuf[80];
-
-static int max_drives = MAX_DRIVES;
-module_param(max_drives, int, 0);
-#ifndef MODULE
-static unsigned char setup_done;
-static const char *str_sb_l = "soundblaster";
-static const char *str_sp_l = "spea";
-static const char *str_ss_l = "soundscape";
-static const char *str_t16_l = "teac16bit";
-static const char *str_ss = "SoundScape";
-#endif
-static const char *str_sb = "SoundBlaster";
-static const char *str_lm = "LaserMate";
-static const char *str_sp = "SPEA";
-static const char *str_t16 = "Teac16bit";
-static const char *type;
-static const char *major_name="sbpcd";
-
-/*==========================================================================*/
-
-#ifdef FUTURE
-static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
-#endif /* FUTURE */
-
-static int teac=SBP_TEAC_SPEED;
-static int buffers=SBP_BUFFER_FRAMES;
-
-static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
-static u_char family1[]="CR-56"; /* MKE CR-562, CR-563 */
-static u_char family2[]="CD200"; /* MKE CD200, Funai CD200F */
-static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
-static u_char familyT[]="CD-55"; /* TEAC CD-55A */
-static u_char familyV[]="ECS-AT"; /* ECS Vertos 100 */
-
-static u_int recursion; /* internal testing only */
-static u_int fatal_err; /* internal testing only */
-static u_int response_count;
-static u_int flags_cmd_out;
-static u_char cmd_type;
-static u_char drvcmd[10];
-static u_char infobuf[20];
-static u_char xa_head_buf[CD_XA_HEAD];
-static u_char xa_tail_buf[CD_XA_TAIL];
-
-#if OLD_BUSY
-static volatile u_char busy_data;
-static volatile u_char busy_audio; /* true semaphores would be safer */
-#endif /* OLD_BUSY */
-static DECLARE_MUTEX(ioctl_read_sem);
-static u_long timeout;
-static volatile u_char timed_out_delay;
-static volatile u_char timed_out_data;
-#if 0
-static volatile u_char timed_out_audio;
-#endif
-static u_int datarate= 1000000;
-static u_int maxtim16=16000000;
-static u_int maxtim04= 4000000;
-static u_int maxtim02= 2000000;
-static u_int maxtim_8= 30000;
-#if LONG_TIMING
-static u_int maxtim_data= 9000;
-#else
-static u_int maxtim_data= 3000;
-#endif /* LONG_TIMING */
-#if DISTRIBUTION
-static int n_retries=6;
-#else
-static int n_retries=6;
-#endif
-/*==========================================================================*/
-
-static int ndrives;
-static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto};
-
-/*==========================================================================*/
-/*
- * drive space begins here (needed separate for each unit)
- */
-static struct sbpcd_drive {
- char drv_id; /* "jumpered" drive ID or -1 */
- char drv_sel; /* drive select lines bits */
-
- char drive_model[9];
- u_char firmware_version[4];
- char f_eject; /* auto-eject flag: 0 or 1 */
- u_char *sbp_buf; /* Pointer to internal data buffer,
- space allocated during sbpcd_init() */
- u_int sbp_bufsiz; /* size of sbp_buf (# of frames) */
- int sbp_first_frame; /* First frame in buffer */
- int sbp_last_frame; /* Last frame in buffer */
- int sbp_read_frames; /* Number of frames being read to buffer */
- int sbp_current; /* Frame being currently read */
-
- u_char mode; /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
- u_char *aud_buf; /* Pointer to audio data buffer,
- space allocated during sbpcd_init() */
- u_int sbp_audsiz; /* size of aud_buf (# of raw frames) */
- u_int drv_type;
- u_char drv_options;
- int status_bits;
- u_char diskstate_flags;
- u_char sense_byte;
-
- u_char CD_changed;
- char open_count;
- u_char error_byte;
-
- u_char f_multisession;
- u_int lba_multi;
- int first_session;
- int last_session;
- int track_of_last_session;
-
- u_char audio_state;
- u_int pos_audio_start;
- u_int pos_audio_end;
- char vol_chan0;
- u_char vol_ctrl0;
- char vol_chan1;
- u_char vol_ctrl1;
-#if 000 /* no supported drive has it */
- char vol_chan2;
- u_char vol_ctrl2;
- char vol_chan3;
- u_char vol_ctrl3;
-#endif /*000 */
- u_char volume_control; /* TEAC on/off bits */
-
- u_char SubQ_ctl_adr;
- u_char SubQ_trk;
- u_char SubQ_pnt_idx;
- u_int SubQ_run_tot;
- u_int SubQ_run_trk;
- u_char SubQ_whatisthis;
-
- u_char UPC_ctl_adr;
- u_char UPC_buf[7];
-
- int frame_size;
- int CDsize_frm;
-
- u_char xa_byte; /* 0x20: XA capabilities */
- u_char n_first_track; /* binary */
- u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
- u_int size_msf; /* time of whole CD, position of LeadOut track */
- u_int size_blk;
-
- u_char TocEnt_nixbyte; /* em */
- u_char TocEnt_ctl_adr;
- u_char TocEnt_number;
- u_char TocEnt_format; /* em */
- u_int TocEnt_address;
-#ifdef SAFE_MIXED
- char has_data;
-#endif /* SAFE_MIXED */
- u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
-
- struct {
- u_char nixbyte; /* em */
- u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
- u_char number;
- u_char format; /* em */ /* 0x00: lba, 0x01: msf */
- u_int address;
- } TocBuffer[MAX_TRACKS+1]; /* last entry faked */
-
- int in_SpinUp; /* CR-52x test flag */
- int n_bytes; /* TEAC awaited response count */
- u_char error_state, b3, b4; /* TEAC command error state */
- u_char f_drv_error; /* TEAC command error flag */
- u_char speed_byte;
- int frmsiz;
- u_char f_XA; /* 1: XA */
- u_char type_byte; /* 0, 1, 3 */
- u_char mode_xb_6;
- u_char mode_yb_7;
- u_char mode_xb_8;
- u_char delay;
- struct cdrom_device_info *sbpcd_infop;
- struct gendisk *disk;
-} D_S[NR_SBPCD];
-
-static struct sbpcd_drive *current_drive = D_S;
-
-/*
- * drive space ends here (needed separate for each unit)
- */
-/*==========================================================================*/
-#if 0
-unsigned long cli_sti; /* for saving the processor flags */
-#endif
-/*==========================================================================*/
-static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0);
-static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0);
-#if 0
-static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0);
-#endif
-/*==========================================================================*/
-/*
- * DDI interface
- */
-static void msg(int level, const char *fmt, ...)
-{
-#if DISTRIBUTION
-#define MSG_LEVEL KERN_NOTICE
-#else
-#define MSG_LEVEL KERN_INFO
-#endif /* DISTRIBUTION */
-
- char buf[256];
- va_list args;
-
- if (!(sbpcd_debug&(1<<level))) return;
-
- msgnum++;
- if (msgnum>99) msgnum=0;
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- printk(MSG_LEVEL "%s-%d [%02d]: %s", major_name, current_drive - D_S, msgnum, buf);
-#if KLOGD_PAUSE
- sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
-#endif /* KLOGD_PAUSE */
- return;
-}
-/*==========================================================================*/
-/*
- * DDI interface: runtime trace bit pattern maintenance
- */
-static int sbpcd_dbg_ioctl(unsigned long arg, int level)
-{
- switch(arg)
- {
- case 0: /* OFF */
- sbpcd_debug = DBG_INF;
- break;
-
- default:
- if (arg>=128) sbpcd_debug &= ~(1<<(arg-128));
- else sbpcd_debug |= (1<<arg);
- }
- return (arg);
-}
-/*==========================================================================*/
-static void mark_timeout_delay(u_long i)
-{
- timed_out_delay=1;
-#if 0
- msg(DBG_TIM,"delay timer expired.\n");
-#endif
-}
-/*==========================================================================*/
-static void mark_timeout_data(u_long i)
-{
- timed_out_data=1;
-#if 0
- msg(DBG_TIM,"data timer expired.\n");
-#endif
-}
-/*==========================================================================*/
-#if 0
-static void mark_timeout_audio(u_long i)
-{
- timed_out_audio=1;
-#if 0
- msg(DBG_TIM,"audio timer expired.\n");
-#endif
-}
-#endif
-/*==========================================================================*/
-/*
- * Wait a little while (used for polling the drive).
- */
-static void sbp_sleep(u_int time)
-{
- sti();
- schedule_timeout_interruptible(time);
- sti();
-}
-/*==========================================================================*/
-#define RETURN_UP(rc) {up(&ioctl_read_sem); return(rc);}
-/*==========================================================================*/
-/*
- * convert logical_block_address to m-s-f_number (3 bytes only)
- */
-static INLINE void lba2msf(int lba, u_char *msf)
-{
- lba += CD_MSF_OFFSET;
- msf[0] = lba / (CD_SECS*CD_FRAMES);
- lba %= CD_SECS*CD_FRAMES;
- msf[1] = lba / CD_FRAMES;
- msf[2] = lba % CD_FRAMES;
-}
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * convert msf-bin to msf-bcd
- */
-static INLINE void bin2bcdx(u_char *p) /* must work only up to 75 or 99 */
-{
- *p=((*p/10)<<4)|(*p%10);
-}
-/*==========================================================================*/
-static INLINE u_int blk2msf(u_int blk)
-{
- MSF msf;
- u_int mm;
-
- msf.c[3] = 0;
- msf.c[2] = (blk + CD_MSF_OFFSET) / (CD_SECS * CD_FRAMES);
- mm = (blk + CD_MSF_OFFSET) % (CD_SECS * CD_FRAMES);
- msf.c[1] = mm / CD_FRAMES;
- msf.c[0] = mm % CD_FRAMES;
- return (msf.n);
-}
-/*==========================================================================*/
-static INLINE u_int make16(u_char rh, u_char rl)
-{
- return ((rh<<8)|rl);
-}
-/*==========================================================================*/
-static INLINE u_int make32(u_int rh, u_int rl)
-{
- return ((rh<<16)|rl);
-}
-/*==========================================================================*/
-static INLINE u_char swap_nibbles(u_char i)
-{
- return ((i<<4)|(i>>4));
-}
-/*==========================================================================*/
-static INLINE u_char byt2bcd(u_char i)
-{
- return (((i/10)<<4)+i%10);
-}
-/*==========================================================================*/
-static INLINE u_char bcd2bin(u_char bcd)
-{
- return ((bcd>>4)*10+(bcd&0x0F));
-}
-/*==========================================================================*/
-static INLINE int msf2blk(int msfx)
-{
- MSF msf;
- int i;
-
- msf.n=msfx;
- i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET;
- if (i<0) return (0);
- return (i);
-}
-/*==========================================================================*/
-/*
- * convert m-s-f_number (3 bytes only) to logical_block_address
- */
-static INLINE int msf2lba(u_char *msf)
-{
- int i;
-
- i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET;
- if (i<0) return (0);
- return (i);
-}
-/*==========================================================================*/
-/* evaluate cc_ReadError code */
-static int sta2err(int sta)
-{
- if (famT_drive)
- {
- if (sta==0x00) return (0);
- if (sta==0x01) return (-604); /* CRC error */
- if (sta==0x02) return (-602); /* drive not ready */
- if (sta==0x03) return (-607); /* unknown media */
- if (sta==0x04) return (-612); /* general failure */
- if (sta==0x05) return (0);
- if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */
- if (sta==0x0b) return (-612); /* general failure */
- if (sta==0xff) return (-612); /* general failure */
- return (0);
- }
- else
- {
- if (sta<=2) return (sta);
- if (sta==0x05) return (-604); /* CRC error */
- if (sta==0x06) return (-606); /* seek error */
- if (sta==0x0d) return (-606); /* seek error */
- if (sta==0x0e) return (-603); /* unknown command */
- if (sta==0x14) return (-603); /* unknown command */
- if (sta==0x0c) return (-611); /* read fault */
- if (sta==0x0f) return (-611); /* read fault */
- if (sta==0x10) return (-611); /* read fault */
- if (sta>=0x16) return (-612); /* general failure */
- if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */
- if (famL_drive)
- if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */
- return (-602); /* drive not ready */
- }
-}
-/*==========================================================================*/
-static INLINE void clr_cmdbuf(void)
-{
- int i;
-
- for (i=0;i<10;i++) drvcmd[i]=0;
- cmd_type=0;
-}
-/*==========================================================================*/
-static void flush_status(void)
-{
- int i;
-
- sbp_sleep(15*HZ/10);
- for (i=maxtim_data;i!=0;i--) inb(CDi_status);
-}
-/*====================================================================*/
-/*
- * CDi status loop for Teac CD-55A (Rob Riggs)
- *
- * This is needed because for some strange reason
- * the CD-55A can take a real long time to give a
- * status response. This seems to happen after we
- * issue a READ command where a long seek is involved.
- *
- * I tried to ensure that we get max throughput with
- * minimal busy waiting. We busy wait at first, then
- * "switch gears" and start sleeping. We sleep for
- * longer periods of time the longer we wait.
- *
- */
-static int CDi_stat_loop_T(void)
-{
- int i, gear=1;
- u_long timeout_1, timeout_2, timeout_3, timeout_4;
-
- timeout_1 = jiffies + HZ / 50; /* sbp_sleep(0) for a short period */
- timeout_2 = jiffies + HZ / 5; /* nap for no more than 200ms */
- timeout_3 = jiffies + 5 * HZ; /* sleep for up to 5s */
- timeout_4 = jiffies + 45 * HZ; /* long sleep for up to 45s. */
- do
- {
- i = inb(CDi_status);
- if (!(i&s_not_data_ready)) return (i);
- if (!(i&s_not_result_ready)) return (i);
- switch(gear)
- {
- case 4:
- sbp_sleep(HZ);
- if (time_after(jiffies, timeout_4)) gear++;
- msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n");
- break;
- case 3:
- sbp_sleep(HZ/10);
- if (time_after(jiffies, timeout_3)) gear++;
- break;
- case 2:
- sbp_sleep(HZ/100);
- if (time_after(jiffies, timeout_2)) gear++;
- break;
- case 1:
- sbp_sleep(0);
- if (time_after(jiffies, timeout_1)) gear++;
- }
- } while (gear < 5);
- return -1;
-}
-/*==========================================================================*/
-static int CDi_stat_loop(void)
-{
- int i,j;
-
- for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); )
- {
- for ( ;i!=0;i--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) return (j);
- if (!(j&s_not_result_ready)) return (j);
- if (fam0L_drive) if (j&s_attention) return (j);
- }
- sbp_sleep(1);
- i = 1;
- }
- msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__);
- return (-1);
-}
-/*==========================================================================*/
-#if 00000
-/*==========================================================================*/
-static int tst_DataReady(void)
-{
- int i;
-
- i=inb(CDi_status);
- if (i&s_not_data_ready) return (0);
- return (1);
-}
-/*==========================================================================*/
-static int tst_ResultReady(void)
-{
- int i;
-
- i=inb(CDi_status);
- if (i&s_not_result_ready) return (0);
- return (1);
-}
-/*==========================================================================*/
-static int tst_Attention(void)
-{
- int i;
-
- i=inb(CDi_status);
- if (i&s_attention) return (1);
- return (0);
-}
-/*==========================================================================*/
-#endif
-/*==========================================================================*/
-static int ResponseInfo(void)
-{
- int i,j,st=0;
- u_long timeout;
-
- for (i=0,timeout=jiffies+HZ;i<response_count;i++)
- {
- for (j=maxtim_data; ; )
- {
- for ( ;j!=0;j-- )
- {
- st=inb(CDi_status);
- if (!(st&s_not_result_ready)) break;
- }
- if ((j!=0)||time_after_eq(jiffies, timeout)) break;
- sbp_sleep(1);
- j = 1;
- }
- if (time_after_eq(jiffies, timeout)) break;
- infobuf[i]=inb(CDi_info);
- }
-#if 000
- while (!(inb(CDi_status)&s_not_result_ready))
- {
- infobuf[i++]=inb(CDi_info);
- }
- j=i-response_count;
- if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
-#endif /* 000 */
- for (j=0;j<i;j++)
- sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
- msgbuf[j*3]=0;
- msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
- j=response_count-i;
- if (j>0) return (-j);
- else return (i);
-}
-/*==========================================================================*/
-static void EvaluateStatus(int st)
-{
- current_drive->status_bits=0;
- if (fam1_drive) current_drive->status_bits=st|p_success;
- else if (fam0_drive)
- {
- if (st&p_caddin_old) current_drive->status_bits |= p_door_closed|p_caddy_in;
- if (st&p_spinning) current_drive->status_bits |= p_spinning;
- if (st&p_check) current_drive->status_bits |= p_check;
- if (st&p_success_old) current_drive->status_bits |= p_success;
- if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
- if (st&p_disk_ok) current_drive->status_bits |= p_disk_ok;
- }
- else if (famLV_drive)
- {
- current_drive->status_bits |= p_success;
- if (st&p_caddin_old) current_drive->status_bits |= p_disk_ok|p_caddy_in;
- if (st&p_spinning) current_drive->status_bits |= p_spinning;
- if (st&p_check) current_drive->status_bits |= p_check;
- if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
- if (st&p_lcs_door_closed) current_drive->status_bits |= p_door_closed;
- if (st&p_lcs_door_locked) current_drive->status_bits |= p_door_locked;
- }
- else if (fam2_drive)
- {
- current_drive->status_bits |= p_success;
- if (st&p2_check) current_drive->status_bits |= p1_check;
- if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
- if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
- if (st&p2_busy1) current_drive->status_bits |= p1_busy;
- if (st&p2_busy2) current_drive->status_bits |= p1_busy;
- if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
- if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
- if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
- }
- else if (famT_drive)
- {
- return; /* still needs to get coded */
- current_drive->status_bits |= p_success;
- if (st&p2_check) current_drive->status_bits |= p1_check;
- if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
- if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
- if (st&p2_busy1) current_drive->status_bits |= p1_busy;
- if (st&p2_busy2) current_drive->status_bits |= p1_busy;
- if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
- if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
- if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
- }
- return;
-}
-/*==========================================================================*/
-static int cmd_out_T(void);
-
-static int get_state_T(void)
-{
- int i;
-
- clr_cmdbuf();
- current_drive->n_bytes=1;
- drvcmd[0]=CMDT_STATUS;
- i=cmd_out_T();
- if (i>=0) i=infobuf[0];
- else
- {
- msg(DBG_TEA,"get_state_T error %d\n", i);
- return (i);
- }
- if (i>=0)
- /* 2: closed, disk in */
- current_drive->status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
- else if (current_drive->error_state==6)
- {
- /* 3: closed, disk in, changed ("06 xx xx") */
- current_drive->status_bits=p1_door_closed|p1_disk_in;
- current_drive->CD_changed=0xFF;
- current_drive->diskstate_flags &= ~toc_bit;
- }
- else if ((current_drive->error_state!=2)||(current_drive->b3!=0x3A)||(current_drive->b4==0x00))
- {
- /* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
- current_drive->status_bits=p1_door_closed;
- current_drive->open_count=0;
- }
- else if (current_drive->b4==0x01)
- {
- /* 0: open ("02 3A 01") */
- current_drive->status_bits=0;
- current_drive->open_count=0;
- }
- else
- {
- /* 1: closed, no disk ("02 3A xx") */
- current_drive->status_bits=p1_door_closed;
- current_drive->open_count=0;
- }
- return (current_drive->status_bits);
-}
-/*==========================================================================*/
-static int ResponseStatus(void)
-{
- int i,j;
- u_long timeout;
-
- msg(DBG_STA,"doing ResponseStatus...\n");
- if (famT_drive) return (get_state_T());
- if (flags_cmd_out & f_respo3) timeout = jiffies;
- else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
- else timeout = jiffies + 4*HZ;
- j=maxtim_8;
- do
- {
- for ( ;j!=0;j--)
- {
- i=inb(CDi_status);
- if (!(i&s_not_result_ready)) break;
- }
- if ((j!=0)||time_after(jiffies, timeout)) break;
- sbp_sleep(1);
- j = 1;
- }
- while (1);
- if (j==0)
- {
- if ((flags_cmd_out & f_respo3) == 0)
- msg(DBG_STA,"ResponseStatus: timeout.\n");
- current_drive->status_bits=0;
- return (-401);
- }
- i=inb(CDi_info);
- msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
- EvaluateStatus(i);
- msg(DBG_STA,"status_bits=%02X, i=%02X\n",current_drive->status_bits,i);
- return (current_drive->status_bits);
-}
-/*==========================================================================*/
-static void cc_ReadStatus(void)
-{
- int i;
-
- msg(DBG_STA,"giving cc_ReadStatus command\n");
- if (famT_drive) return;
- SBPCD_CLI;
- if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS);
- else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
- else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
- if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
- SBPCD_STI;
-}
-/*==========================================================================*/
-static int cc_ReadError(void)
-{
- int i;
-
- clr_cmdbuf();
- msg(DBG_ERR,"giving cc_ReadError command.\n");
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_READ_ERR;
- response_count=8;
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (fam0LV_drive)
- {
- drvcmd[0]=CMD0_READ_ERR;
- response_count=6;
- if (famLV_drive)
- flags_cmd_out=f_putcmd;
- else
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_READ_ERR;
- response_count=6;
- flags_cmd_out=f_putcmd;
- }
- else if (famT_drive)
- {
- response_count=5;
- drvcmd[0]=CMDT_READ_ERR;
- }
- i=cmd_out();
- current_drive->error_byte=0;
- msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
- if (i<0) return (i);
- if (fam0V_drive) i=1;
- else i=2;
- current_drive->error_byte=infobuf[i];
- msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,current_drive->error_byte,current_drive->error_byte);
- i=sta2err(infobuf[i]);
- if (i==-ERR_DISKCHANGE)
- {
- current_drive->CD_changed=0xFF;
- current_drive->diskstate_flags &= ~toc_bit;
- }
- return (i);
-}
-/*==========================================================================*/
-static int cc_DriveReset(void);
-
-static int cmd_out_T(void)
-{
-#undef CMDT_TRIES
-#define CMDT_TRIES 1000
-#define TEST_FALSE_FF 1
-
- int i, j, l=0, m, ntries;
- unsigned long flags;
-
- current_drive->error_state=0;
- current_drive->b3=0;
- current_drive->b4=0;
- current_drive->f_drv_error=0;
- for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
- msgbuf[i*3]=0;
- msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);
-
- OUT(CDo_sel_i_d,0);
- OUT(CDo_enable,current_drive->drv_sel);
- i=inb(CDi_status);
- do_16bit=0;
- if ((f_16bit)&&(!(i&0x80)))
- {
- do_16bit=1;
- msg(DBG_TEA,"cmd_out_T: do_16bit set.\n");
- }
- if (!(i&s_not_result_ready))
- do
- {
- j=inb(CDi_info);
- i=inb(CDi_status);
- sbp_sleep(0);
- msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j);
- }
- while (!(i&s_not_result_ready));
- save_flags(flags); cli();
- for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]);
- restore_flags(flags);
- for (ntries=CMDT_TRIES;ntries>0;ntries--)
- {
- if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
-#if 01
- OUT(CDo_sel_i_d,1);
-#endif /* 01 */
- if (teac==2)
- {
- if ((i=CDi_stat_loop_T()) == -1) break;
- }
- else
- {
-#if 0
- OUT(CDo_sel_i_d,1);
-#endif /* 0 */
- i=inb(CDi_status);
- }
- if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
- {
- OUT(CDo_sel_i_d,1);
- if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
- if (drvcmd[0]==CMDT_DISKINFO)
- {
- l=0;
- do
- {
- if (do_16bit)
- {
- i=inw(CDi_data);
- infobuf[l++]=i&0x0ff;
- infobuf[l++]=i>>8;
-#if TEST_FALSE_FF
- if ((l==2)&&(infobuf[0]==0x0ff))
- {
- infobuf[0]=infobuf[1];
- l=1;
- msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
- }
-#endif /* TEST_FALSE_FF */
- }
- else infobuf[l++]=inb(CDi_data);
- i=inb(CDi_status);
- }
- while (!(i&s_not_data_ready));
- for (j=0;j<l;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
- msgbuf[j*3]=0;
- msg(DBG_CMD,"cmd_out_T data response:%s\n", msgbuf);
- }
- else
- {
- msg(DBG_TEA,"cmd_out_T: data response with cmd_%02X!\n",
- drvcmd[0]);
- j=0;
- do
- {
- if (do_16bit) i=inw(CDi_data);
- else i=inb(CDi_data);
- j++;
- i=inb(CDi_status);
- }
- while (!(i&s_not_data_ready));
- msg(DBG_TEA,"cmd_out_T: data response: discarded %d bytes/words.\n", j);
- fatal_err++;
- }
- }
- i=inb(CDi_status);
- if (!(i&s_not_result_ready))
- {
- OUT(CDo_sel_i_d,0);
- if (drvcmd[0]==CMDT_DISKINFO) m=l;
- else m=0;
- do
- {
- infobuf[m++]=inb(CDi_info);
- i=inb(CDi_status);
- }
- while (!(i&s_not_result_ready));
- for (j=0;j<m;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
- msgbuf[j*3]=0;
- msg(DBG_CMD,"cmd_out_T info response:%s\n", msgbuf);
- if (drvcmd[0]==CMDT_DISKINFO)
- {
- infobuf[0]=infobuf[l];
- if (infobuf[0]!=0x02) return (l); /* data length */
- }
- else if (infobuf[0]!=0x02) return (m); /* info length */
- do
- {
- ++recursion;
- if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion);
- clr_cmdbuf();
- drvcmd[0]=CMDT_READ_ERR;
- j=cmd_out_T(); /* !!! recursive here !!! */
- --recursion;
- sbp_sleep(1);
- }
- while (j<0);
- current_drive->error_state=infobuf[2];
- current_drive->b3=infobuf[3];
- current_drive->b4=infobuf[4];
- if (current_drive->f_drv_error)
- {
- current_drive->f_drv_error=0;
- cc_DriveReset();
- current_drive->error_state=2;
- }
- return (-current_drive->error_state-400);
- }
- if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
- if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
- else sbp_sleep(HZ/100);
- if (ntries>(CMDT_TRIES-50)) continue;
- msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
- }
- current_drive->f_drv_error=1;
- cc_DriveReset();
- current_drive->error_state=2;
- return (-99);
-}
-/*==========================================================================*/
-static int cmd_out(void)
-{
- int i=0;
-
- if (famT_drive) return(cmd_out_T());
-
- if (flags_cmd_out&f_putcmd)
- {
- unsigned long flags;
- for (i=0;i<7;i++)
- sprintf(&msgbuf[i*3], " %02X", drvcmd[i]);
- msgbuf[i*3]=0;
- msg(DBG_CMD,"cmd_out:%s\n", msgbuf);
- save_flags(flags); cli();
- for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
- restore_flags(flags);
- }
- if (response_count!=0)
- {
- if (cmd_type!=0)
- {
- if (sbpro_type==1) OUT(CDo_sel_i_d,1);
- msg(DBG_INF,"misleaded to try ResponseData.\n");
- if (sbpro_type==1) OUT(CDo_sel_i_d,0);
- return (-22);
- }
- else i=ResponseInfo();
- if (i<0) return (i);
- }
- if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
- if (flags_cmd_out&f_lopsta)
- {
- i=CDi_stat_loop();
- if ((i<0)||!(i&s_attention)) return (-8);
- }
- if (!(flags_cmd_out&f_getsta)) goto LOC_229;
-
- LOC_228:
- if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
- cc_ReadStatus();
-
- LOC_229:
- if (flags_cmd_out&f_ResponseStatus)
- {
- if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
- i=ResponseStatus();
- /* builds status_bits, returns orig. status or p_busy_new */
- if (i<0) return (i);
- if (flags_cmd_out&(f_bit1|f_wait_if_busy))
- {
- if (!st_check)
- {
- if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232;
- if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228;
- }
- }
- }
- LOC_232:
- if (!(flags_cmd_out&f_obey_p_check)) return (0);
- if (!st_check) return (0);
- if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
- i=cc_ReadError();
- if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
- msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
- return (i);
-}
-/*==========================================================================*/
-static int cc_Seek(u_int pos, char f_blk_msf)
-{
- int i;
-
- clr_cmdbuf();
- if (f_blk_msf>1) return (-3);
- if (fam0V_drive)
- {
- drvcmd[0]=CMD0_SEEK;
- if (f_blk_msf==1) pos=msf2blk(pos);
- drvcmd[2]=(pos>>16)&0x00FF;
- drvcmd[3]=(pos>>8)&0x00FF;
- drvcmd[4]=pos&0x00FF;
- if (fam0_drive)
- flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
- f_ResponseStatus | f_obey_p_check | f_bit1;
- else
- flags_cmd_out = f_putcmd;
- }
- else if (fam1L_drive)
- {
- drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
- if (f_blk_msf==0) pos=blk2msf(pos);
- drvcmd[1]=(pos>>16)&0x00FF;
- drvcmd[2]=(pos>>8)&0x00FF;
- drvcmd[3]=pos&0x00FF;
- if (famL_drive)
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
- else
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_SEEK;
- if (f_blk_msf==0) pos=blk2msf(pos);
- drvcmd[2]=(pos>>24)&0x00FF;
- drvcmd[3]=(pos>>16)&0x00FF;
- drvcmd[4]=(pos>>8)&0x00FF;
- drvcmd[5]=pos&0x00FF;
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_SEEK;
- if (f_blk_msf==1) pos=msf2blk(pos);
- drvcmd[2]=(pos>>24)&0x00FF;
- drvcmd[3]=(pos>>16)&0x00FF;
- drvcmd[4]=(pos>>8)&0x00FF;
- drvcmd[5]=pos&0x00FF;
- current_drive->n_bytes=1;
- }
- response_count=0;
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int cc_SpinUp(void)
-{
- int i;
-
- msg(DBG_SPI,"SpinUp.\n");
- current_drive->in_SpinUp = 1;
- clr_cmdbuf();
- if (fam0LV_drive)
- {
- drvcmd[0]=CMD0_SPINUP;
- if (fam0L_drive)
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
- f_ResponseStatus|f_obey_p_check|f_bit1;
- else
- flags_cmd_out=f_putcmd;
- }
- else if (fam1_drive)
- {
- drvcmd[0]=CMD1_SPINUP;
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_TRAY_CTL;
- drvcmd[4]=0x01; /* "spinup" */
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_TRAY_CTL;
- drvcmd[4]=0x03; /* "insert", it hopefully spins the drive up */
- }
- response_count=0;
- i=cmd_out();
- current_drive->in_SpinUp = 0;
- return (i);
-}
-/*==========================================================================*/
-static int cc_SpinDown(void)
-{
- int i;
-
- if (fam0_drive) return (0);
- clr_cmdbuf();
- response_count=0;
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_SPINDOWN;
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_TRAY_CTL;
- drvcmd[4]=0x02; /* "eject" */
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (famL_drive)
- {
- drvcmd[0]=CMDL_SPINDOWN;
- drvcmd[1]=1;
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
- }
- else if (famV_drive)
- {
- drvcmd[0]=CMDV_SPINDOWN;
- flags_cmd_out=f_putcmd;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_TRAY_CTL;
- drvcmd[4]=0x02; /* "eject" */
- }
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int cc_get_mode_T(void)
-{
- int i;
-
- clr_cmdbuf();
- response_count=10;
- drvcmd[0]=CMDT_GETMODE;
- drvcmd[4]=response_count;
- i=cmd_out_T();
- return (i);
-}
-/*==========================================================================*/
-static int cc_set_mode_T(void)
-{
- int i;
-
- clr_cmdbuf();
- response_count=1;
- drvcmd[0]=CMDT_SETMODE;
- drvcmd[1]=current_drive->speed_byte;
- drvcmd[2]=current_drive->frmsiz>>8;
- drvcmd[3]=current_drive->frmsiz&0x0FF;
- drvcmd[4]=current_drive->f_XA; /* 1: XA */
- drvcmd[5]=current_drive->type_byte; /* 0, 1, 3 */
- drvcmd[6]=current_drive->mode_xb_6;
- drvcmd[7]=current_drive->mode_yb_7|current_drive->volume_control;
- drvcmd[8]=current_drive->mode_xb_8;
- drvcmd[9]=current_drive->delay;
- i=cmd_out_T();
- return (i);
-}
-/*==========================================================================*/
-static int cc_prep_mode_T(void)
-{
- int i, j;
-
- i=cc_get_mode_T();
- if (i<0) return (i);
- for (i=0;i<10;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
- current_drive->speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
- current_drive->frmsiz=make16(infobuf[2],infobuf[3]);
- current_drive->f_XA=infobuf[4];
- if (current_drive->f_XA==0) current_drive->type_byte=0;
- else current_drive->type_byte=1;
- current_drive->mode_xb_6=infobuf[6];
- current_drive->mode_yb_7=1;
- current_drive->mode_xb_8=infobuf[8];
- current_drive->delay=0; /* 0, 1, 2, 3 */
- j=cc_set_mode_T();
- i=cc_get_mode_T();
- for (i=0;i<10;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
- return (j);
-}
-/*==========================================================================*/
-static int cc_SetSpeed(u_char speed, u_char x1, u_char x2)
-{
- int i;
-
- if (fam0LV_drive) return (0);
- clr_cmdbuf();
- response_count=0;
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_SETMODE;
- drvcmd[1]=0x03;
- drvcmd[2]=speed;
- drvcmd[3]=x1;
- drvcmd[4]=x2;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_SETSPEED;
- if (speed&speed_auto)
- {
- drvcmd[2]=0xFF;
- drvcmd[3]=0xFF;
- }
- else
- {
- drvcmd[2]=0;
- drvcmd[3]=150;
- }
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- return (0);
- }
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int cc_SetVolume(void)
-{
- int i;
- u_char channel0,channel1,volume0,volume1;
- u_char control0,value0,control1,value1;
-
- current_drive->diskstate_flags &= ~volume_bit;
- clr_cmdbuf();
- channel0=current_drive->vol_chan0;
- volume0=current_drive->vol_ctrl0;
- channel1=control1=current_drive->vol_chan1;
- volume1=value1=current_drive->vol_ctrl1;
- control0=value0=0;
-
- if (famV_drive) return (0);
-
- if (((current_drive->drv_options&audio_mono)!=0)&&(current_drive->drv_type>=drv_211))
- {
- if ((volume0!=0)&&(volume1==0))
- {
- volume1=volume0;
- channel1=channel0;
- }
- else if ((volume0==0)&&(volume1!=0))
- {
- volume0=volume1;
- channel0=channel1;
- }
- }
- if (channel0>1)
- {
- channel0=0;
- volume0=0;
- }
- if (channel1>1)
- {
- channel1=1;
- volume1=0;
- }
-
- if (fam1_drive)
- {
- control0=channel0+1;
- control1=channel1+1;
- value0=(volume0>volume1)?volume0:volume1;
- value1=value0;
- if (volume0==0) control0=0;
- if (volume1==0) control1=0;
- drvcmd[0]=CMD1_SETMODE;
- drvcmd[1]=0x05;
- drvcmd[3]=control0;
- drvcmd[4]=value0;
- drvcmd[5]=control1;
- drvcmd[6]=value1;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- control0=channel0+1;
- control1=channel1+1;
- value0=(volume0>volume1)?volume0:volume1;
- value1=value0;
- if (volume0==0) control0=0;
- if (volume1==0) control1=0;
- drvcmd[0]=CMD2_SETMODE;
- drvcmd[1]=0x0E;
- drvcmd[3]=control0;
- drvcmd[4]=value0;
- drvcmd[5]=control1;
- drvcmd[6]=value1;
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (famL_drive)
- {
- if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
- if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
- if (volume0|volume1) value0=0x80;
- drvcmd[0]=CMDL_SETMODE;
- drvcmd[1]=0x03;
- drvcmd[4]=control0;
- drvcmd[5]=value0;
- flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
- }
- else if (fam0_drive) /* different firmware levels */
- {
- if (current_drive->drv_type>=drv_300)
- {
- control0=volume0&0xFC;
- value0=volume1&0xFC;
- if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
- if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
- if (channel0!=0) control0 |= 0x01;
- if (channel1==1) value0 |= 0x01;
- }
- else
- {
- value0=(volume0>volume1)?volume0:volume1;
- if (current_drive->drv_type<drv_211)
- {
- if (channel0!=0)
- {
- i=channel1;
- channel1=channel0;
- channel0=i;
- i=volume1;
- volume1=volume0;
- volume0=i;
- }
- if (channel0==channel1)
- {
- if (channel0==0)
- {
- channel1=1;
- volume1=0;
- volume0=value0;
- }
- else
- {
- channel0=0;
- volume0=0;
- volume1=value0;
- }
- }
- }
-
- if ((volume0!=0)&&(volume1!=0))
- {
- if (volume0==0xFF) volume1=0xFF;
- else if (volume1==0xFF) volume0=0xFF;
- }
- else if (current_drive->drv_type<drv_201) volume0=volume1=value0;
-
- if (current_drive->drv_type>=drv_201)
- {
- if (volume0==0) control0 |= 0x80;
- if (volume1==0) control0 |= 0x40;
- }
- if (current_drive->drv_type>=drv_211)
- {
- if (channel0!=0) control0 |= 0x20;
- if (channel1!=1) control0 |= 0x10;
- }
- }
- drvcmd[0]=CMD0_SETMODE;
- drvcmd[1]=0x83;
- drvcmd[4]=control0;
- drvcmd[5]=value0;
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- current_drive->volume_control=0;
- if (!volume0) current_drive->volume_control|=0x10;
- if (!volume1) current_drive->volume_control|=0x20;
- i=cc_prep_mode_T();
- if (i<0) return (i);
- }
- if (!famT_drive)
- {
- response_count=0;
- i=cmd_out();
- if (i<0) return (i);
- }
- current_drive->diskstate_flags |= volume_bit;
- return (0);
-}
-/*==========================================================================*/
-static int GetStatus(void)
-{
- int i;
-
- if (famT_drive) return (0);
- flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
- response_count=0;
- cmd_type=0;
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int cc_DriveReset(void)
-{
- int i;
-
- msg(DBG_RES,"cc_DriveReset called.\n");
- clr_cmdbuf();
- response_count=0;
- if (fam0LV_drive) OUT(CDo_reset,0x00);
- else if (fam1_drive)
- {
- drvcmd[0]=CMD1_RESET;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_RESET;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- OUT(CDo_reset,0x00);
- }
- else if (famT_drive)
- {
- OUT(CDo_sel_i_d,0);
- OUT(CDo_enable,current_drive->drv_sel);
- OUT(CDo_command,CMDT_RESET);
- for (i=1;i<10;i++) OUT(CDo_command,0);
- }
- if (fam0LV_drive) sbp_sleep(5*HZ); /* wait 5 seconds */
- else sbp_sleep(1*HZ); /* wait a second */
-#if 1
- if (famT_drive)
- {
- msg(DBG_TEA, "================CMDT_RESET given=================.\n");
- sbp_sleep(3*HZ);
- }
-#endif /* 1 */
- flush_status();
- i=GetStatus();
- if (i<0) return i;
- if (!famT_drive)
- if (current_drive->error_byte!=aud_12) return -501;
- return (0);
-}
-
-/*==========================================================================*/
-static int SetSpeed(void)
-{
- int i, speed;
-
- if (!(current_drive->drv_options&(speed_auto|speed_300|speed_150))) return (0);
- speed=speed_auto;
- if (!(current_drive->drv_options&speed_auto))
- {
- speed |= speed_300;
- if (!(current_drive->drv_options&speed_300)) speed=0;
- }
- i=cc_SetSpeed(speed,0,0);
- return (i);
-}
-
-static void switch_drive(struct sbpcd_drive *);
-
-static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed)
-{
- struct sbpcd_drive *p = cdi->handle;
- if (p != current_drive)
- switch_drive(p);
-
- return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
-}
-
-/*==========================================================================*/
-static int DriveReset(void)
-{
- int i;
-
- i=cc_DriveReset();
- if (i<0) return (-22);
- do
- {
- i=GetStatus();
- if ((i<0)&&(i!=-ERR_DISKCHANGE)) {
- return (-2); /* from sta2err */
- }
- if (!st_caddy_in) break;
- sbp_sleep(1);
- }
- while (!st_diskok);
-#if 000
- current_drive->CD_changed=1;
-#endif
- if ((st_door_closed) && (st_caddy_in))
- {
- i=DiskInfo();
- if (i<0) return (-23);
- }
- return (0);
-}
-
-static int sbpcd_reset(struct cdrom_device_info *cdi)
-{
- struct sbpcd_drive *p = cdi->handle;
- if (p != current_drive)
- switch_drive(p);
- return DriveReset();
-}
-
-/*==========================================================================*/
-static int cc_PlayAudio(int pos_audio_start,int pos_audio_end)
-{
- int i, j, n;
-
- if (current_drive->audio_state==audio_playing) return (-EINVAL);
- clr_cmdbuf();
- response_count=0;
- if (famLV_drive)
- {
- drvcmd[0]=CMDL_PLAY;
- i=msf2blk(pos_audio_start);
- n=msf2blk(pos_audio_end)+1-i;
- drvcmd[1]=(i>>16)&0x00FF;
- drvcmd[2]=(i>>8)&0x00FF;
- drvcmd[3]=i&0x00FF;
- drvcmd[4]=(n>>16)&0x00FF;
- drvcmd[5]=(n>>8)&0x00FF;
- drvcmd[6]=n&0x00FF;
- if (famL_drive)
- flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
- f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
- else
- flags_cmd_out = f_putcmd;
- }
- else
- {
- j=1;
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_PLAY_MSF;
- flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
- f_obey_p_check | f_wait_if_busy;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_PLAY_MSF;
- flags_cmd_out = f_putcmd | f_ResponseStatus | f_obey_p_check;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_PLAY_MSF;
- j=3;
- response_count=1;
- }
- else if (fam0_drive)
- {
- drvcmd[0]=CMD0_PLAY_MSF;
- flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
- f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
- }
- drvcmd[j]=(pos_audio_start>>16)&0x00FF;
- drvcmd[j+1]=(pos_audio_start>>8)&0x00FF;
- drvcmd[j+2]=pos_audio_start&0x00FF;
- drvcmd[j+3]=(pos_audio_end>>16)&0x00FF;
- drvcmd[j+4]=(pos_audio_end>>8)&0x00FF;
- drvcmd[j+5]=pos_audio_end&0x00FF;
- }
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int cc_Pause_Resume(int pau_res)
-{
- int i;
-
- clr_cmdbuf();
- response_count=0;
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_PAU_RES;
- if (pau_res!=1) drvcmd[1]=0x80;
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_PAU_RES;
- if (pau_res!=1) drvcmd[2]=0x01;
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (fam0LV_drive)
- {
- drvcmd[0]=CMD0_PAU_RES;
- if (pau_res!=1) drvcmd[1]=0x80;
- if (famL_drive)
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
- f_obey_p_check|f_bit1;
- else if (famV_drive)
- flags_cmd_out=f_putcmd;
- else
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
- f_obey_p_check;
- }
- else if (famT_drive)
- {
- if (pau_res==3) return (cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end));
- else if (pau_res==1) drvcmd[0]=CMDT_PAUSE;
- else return (-56);
- }
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int cc_LockDoor(char lock)
-{
- int i;
-
- if (fam0_drive) return (0);
- msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, current_drive - D_S);
- msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked);
- clr_cmdbuf();
- response_count=0;
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_LOCK_CTL;
- if (lock==1) drvcmd[1]=0x01;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_LOCK_CTL;
- if (lock==1) drvcmd[4]=0x01;
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (famLV_drive)
- {
- drvcmd[0]=CMDL_LOCK_CTL;
- if (lock==1) drvcmd[1]=0x01;
- if (famL_drive)
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
- else
- flags_cmd_out=f_putcmd;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_LOCK_CTL;
- if (lock==1) drvcmd[4]=0x01;
- }
- i=cmd_out();
- msg(DBG_LCS,"p_door_locked bit %d after\n", st_door_locked);
- return (i);
-}
-/*==========================================================================*/
-/*==========================================================================*/
-static int UnLockDoor(void)
-{
- int i,j;
-
- j=20;
- do
- {
- i=cc_LockDoor(0);
- --j;
- sbp_sleep(1);
- }
- while ((i<0)&&(j));
- if (i<0)
- {
- cc_DriveReset();
- return -84;
- }
- return (0);
-}
-/*==========================================================================*/
-static int LockDoor(void)
-{
- int i,j;
-
- j=20;
- do
- {
- i=cc_LockDoor(1);
- --j;
- sbp_sleep(1);
- }
- while ((i<0)&&(j));
- if (j==0)
- {
- cc_DriveReset();
- j=20;
- do
- {
- i=cc_LockDoor(1);
- --j;
- sbp_sleep(1);
- }
- while ((i<0)&&(j));
- }
- return (i);
-}
-
-static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock)
-{
- return lock ? LockDoor() : UnLockDoor();
-}
-
-/*==========================================================================*/
-static int cc_CloseTray(void)
-{
- int i;
-
- if (fam0_drive) return (0);
- msg(DBG_LCK,"cc_CloseTray (drive %d)\n", current_drive - D_S);
- msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed);
-
- clr_cmdbuf();
- response_count=0;
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_TRAY_CTL;
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_TRAY_CTL;
- drvcmd[1]=0x01;
- drvcmd[4]=0x03; /* "insert" */
- flags_cmd_out=f_putcmd|f_ResponseStatus;
- }
- else if (famLV_drive)
- {
- drvcmd[0]=CMDL_TRAY_CTL;
- if (famLV_drive)
- flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
- f_ResponseStatus|f_obey_p_check|f_bit1;
- else
- flags_cmd_out=f_putcmd;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_TRAY_CTL;
- drvcmd[4]=0x03; /* "insert" */
- }
- i=cmd_out();
- msg(DBG_LCS,"p_door_closed bit %d after\n", st_door_closed);
-
- i=cc_ReadError();
- flags_cmd_out |= f_respo2;
- cc_ReadStatus(); /* command: give 1-byte status */
- i=ResponseStatus();
- if (famT_drive&&(i<0))
- {
- cc_DriveReset();
- i=ResponseStatus();
-#if 0
- sbp_sleep(HZ);
-#endif /* 0 */
- i=ResponseStatus();
- }
- if (i<0)
- {
- msg(DBG_INF,"sbpcd cc_CloseTray: ResponseStatus timed out (%d).\n",i);
- }
- if (!(famT_drive))
- {
- if (!st_spinning)
- {
- cc_SpinUp();
- if (st_check) i=cc_ReadError();
- flags_cmd_out |= f_respo2;
- cc_ReadStatus();
- i=ResponseStatus();
- } else {
- }
- }
- i=DiskInfo();
- return (i);
-}
-
-static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position)
-{
- int retval=0;
- switch_drive(cdi->handle);
- /* DUH! --AJK */
- if(current_drive->CD_changed != 0xFF) {
- current_drive->CD_changed=0xFF;
- current_drive->diskstate_flags &= ~cd_size_bit;
- }
- if (position == 1) {
- cc_SpinDown();
- } else {
- retval=cc_CloseTray();
- }
- return retval;
-}
-
-/*==========================================================================*/
-static int cc_ReadSubQ(void)
-{
- int i,j;
-
- current_drive->diskstate_flags &= ~subq_bit;
- for (j=255;j>0;j--)
- {
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_READSUBQ;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- response_count=11;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_READSUBQ;
- drvcmd[1]=0x02;
- drvcmd[3]=0x01;
- flags_cmd_out=f_putcmd;
- response_count=10;
- }
- else if (fam0LV_drive)
- {
- drvcmd[0]=CMD0_READSUBQ;
- drvcmd[1]=0x02;
- if (famLV_drive)
- flags_cmd_out=f_putcmd;
- else
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- response_count=13;
- }
- else if (famT_drive)
- {
- response_count=12;
- drvcmd[0]=CMDT_READSUBQ;
- drvcmd[1]=0x02;
- drvcmd[2]=0x40;
- drvcmd[3]=0x01;
- drvcmd[8]=response_count;
- }
- i=cmd_out();
- if (i<0) return (i);
- for (i=0;i<response_count;i++)
- {
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_SQ1,"cc_ReadSubQ:%s\n", msgbuf);
- }
- if (famT_drive) break;
- if (infobuf[0]!=0) break;
- if ((!st_spinning) || (j==1))
- {
- current_drive->SubQ_ctl_adr=current_drive->SubQ_trk=current_drive->SubQ_pnt_idx=current_drive->SubQ_whatisthis=0;
- current_drive->SubQ_run_tot=current_drive->SubQ_run_trk=0;
- return (0);
- }
- }
- if (famT_drive) current_drive->SubQ_ctl_adr=infobuf[1];
- else current_drive->SubQ_ctl_adr=swap_nibbles(infobuf[1]);
- current_drive->SubQ_trk=byt2bcd(infobuf[2]);
- current_drive->SubQ_pnt_idx=byt2bcd(infobuf[3]);
- if (fam0LV_drive) i=5;
- else if (fam12_drive) i=4;
- else if (famT_drive) i=8;
- current_drive->SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
- i=7;
- if (fam0LV_drive) i=9;
- else if (fam12_drive) i=7;
- else if (famT_drive) i=4;
- current_drive->SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
- current_drive->SubQ_whatisthis=infobuf[i+3];
- current_drive->diskstate_flags |= subq_bit;
- return (0);
-}
-/*==========================================================================*/
-static int cc_ModeSense(void)
-{
- int i;
-
- if (fam2_drive) return (0);
- if (famV_drive) return (0);
- current_drive->diskstate_flags &= ~frame_size_bit;
- clr_cmdbuf();
- if (fam1_drive)
- {
- response_count=5;
- drvcmd[0]=CMD1_GETMODE;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam0L_drive)
- {
- response_count=2;
- drvcmd[0]=CMD0_GETMODE;
- if (famL_drive) flags_cmd_out=f_putcmd;
- else flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- response_count=10;
- drvcmd[0]=CMDT_GETMODE;
- drvcmd[4]=response_count;
- }
- i=cmd_out();
- if (i<0) return (i);
- i=0;
- current_drive->sense_byte=0;
- if (fam1_drive) current_drive->sense_byte=infobuf[i++];
- else if (famT_drive)
- {
- if (infobuf[4]==0x01) current_drive->xa_byte=0x20;
- else current_drive->xa_byte=0;
- i=2;
- }
- current_drive->frame_size=make16(infobuf[i],infobuf[i+1]);
- for (i=0;i<response_count;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_XA1,"cc_ModeSense:%s\n", msgbuf);
-
- current_drive->diskstate_flags |= frame_size_bit;
- return (0);
-}
-/*==========================================================================*/
-/*==========================================================================*/
-static int cc_ModeSelect(int framesize)
-{
- int i;
-
- if (fam2_drive) return (0);
- if (famV_drive) return (0);
- current_drive->diskstate_flags &= ~frame_size_bit;
- clr_cmdbuf();
- current_drive->frame_size=framesize;
- if (framesize==CD_FRAMESIZE_RAW) current_drive->sense_byte=0x82;
- else current_drive->sense_byte=0x00;
-
- msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n",
- current_drive->sense_byte, current_drive->frame_size);
-
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_SETMODE;
- drvcmd[1]=0x00;
- drvcmd[2]=current_drive->sense_byte;
- drvcmd[3]=(current_drive->frame_size>>8)&0xFF;
- drvcmd[4]=current_drive->frame_size&0xFF;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam0L_drive)
- {
- drvcmd[0]=CMD0_SETMODE;
- drvcmd[1]=0x00;
- drvcmd[2]=(current_drive->frame_size>>8)&0xFF;
- drvcmd[3]=current_drive->frame_size&0xFF;
- drvcmd[4]=0x00;
- if(famL_drive)
- flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
- else
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- return (-1);
- }
- response_count=0;
- i=cmd_out();
- if (i<0) return (i);
- current_drive->diskstate_flags |= frame_size_bit;
- return (0);
-}
-/*==========================================================================*/
-static int cc_GetVolume(void)
-{
- int i;
- u_char switches;
- u_char chan0=0;
- u_char vol0=0;
- u_char chan1=1;
- u_char vol1=0;
-
- if (famV_drive) return (0);
- current_drive->diskstate_flags &= ~volume_bit;
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_GETMODE;
- drvcmd[1]=0x05;
- response_count=5;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_GETMODE;
- drvcmd[1]=0x0E;
- response_count=5;
- flags_cmd_out=f_putcmd;
- }
- else if (fam0L_drive)
- {
- drvcmd[0]=CMD0_GETMODE;
- drvcmd[1]=0x03;
- response_count=2;
- if(famL_drive)
- flags_cmd_out=f_putcmd;
- else
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- i=cc_get_mode_T();
- if (i<0) return (i);
- }
- if (!famT_drive)
- {
- i=cmd_out();
- if (i<0) return (i);
- }
- if (fam1_drive)
- {
- chan0=infobuf[1]&0x0F;
- vol0=infobuf[2];
- chan1=infobuf[3]&0x0F;
- vol1=infobuf[4];
- if (chan0==0)
- {
- chan0=1;
- vol0=0;
- }
- if (chan1==0)
- {
- chan1=2;
- vol1=0;
- }
- chan0 >>= 1;
- chan1 >>= 1;
- }
- else if (fam2_drive)
- {
- chan0=infobuf[1];
- vol0=infobuf[2];
- chan1=infobuf[3];
- vol1=infobuf[4];
- }
- else if (famL_drive)
- {
- chan0=0;
- chan1=1;
- vol0=vol1=infobuf[1];
- switches=infobuf[0];
- if ((switches&0x80)!=0) chan0=1;
- if ((switches&0x40)!=0) chan1=0;
- }
- else if (fam0_drive) /* different firmware levels */
- {
- chan0=0;
- chan1=1;
- vol0=vol1=infobuf[1];
- if (current_drive->drv_type>=drv_201)
- {
- if (current_drive->drv_type<drv_300)
- {
- switches=infobuf[0];
- if ((switches&0x80)!=0) vol0=0;
- if ((switches&0x40)!=0) vol1=0;
- if (current_drive->drv_type>=drv_211)
- {
- if ((switches&0x20)!=0) chan0=1;
- if ((switches&0x10)!=0) chan1=0;
- }
- }
- else
- {
- vol0=infobuf[0];
- if ((vol0&0x01)!=0) chan0=1;
- if ((vol1&0x01)==0) chan1=0;
- vol0 &= 0xFC;
- vol1 &= 0xFC;
- if (vol0!=0) vol0 += 3;
- if (vol1!=0) vol1 += 3;
- }
- }
- }
- else if (famT_drive)
- {
- current_drive->volume_control=infobuf[7];
- chan0=0;
- chan1=1;
- if (current_drive->volume_control&0x10) vol0=0;
- else vol0=0xff;
- if (current_drive->volume_control&0x20) vol1=0;
- else vol1=0xff;
- }
- current_drive->vol_chan0=chan0;
- current_drive->vol_ctrl0=vol0;
- current_drive->vol_chan1=chan1;
- current_drive->vol_ctrl1=vol1;
-#if 000
- current_drive->vol_chan2=2;
- current_drive->vol_ctrl2=0xFF;
- current_drive->vol_chan3=3;
- current_drive->vol_ctrl3=0xFF;
-#endif /* 000 */
- current_drive->diskstate_flags |= volume_bit;
- return (0);
-}
-/*==========================================================================*/
-static int cc_ReadCapacity(void)
-{
- int i, j;
-
- if (fam2_drive) return (0); /* some firmware lacks this command */
- if (famLV_drive) return (0); /* some firmware lacks this command */
- if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
- current_drive->diskstate_flags &= ~cd_size_bit;
- for (j=3;j>0;j--)
- {
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_CAPACITY;
- response_count=5;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
-#if 00
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_CAPACITY;
- response_count=8;
- flags_cmd_out=f_putcmd;
- }
-#endif
- else if (fam0_drive)
- {
- drvcmd[0]=CMD0_CAPACITY;
- response_count=5;
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- i=cmd_out();
- if (i>=0) break;
- msg(DBG_000,"cc_ReadCapacity: cmd_out: err %d\n", i);
- cc_ReadError();
- }
- if (j==0) return (i);
- if (fam1_drive) current_drive->CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
- else if (fam0_drive) current_drive->CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
-#if 00
- else if (fam2_drive) current_drive->CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
-#endif
- current_drive->diskstate_flags |= cd_size_bit;
- msg(DBG_000,"cc_ReadCapacity: %d frames.\n", current_drive->CDsize_frm);
- return (0);
-}
-/*==========================================================================*/
-static int cc_ReadTocDescr(void)
-{
- int i;
-
- current_drive->diskstate_flags &= ~toc_bit;
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_DISKINFO;
- response_count=6;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam0LV_drive)
- {
- drvcmd[0]=CMD0_DISKINFO;
- response_count=6;
- if(famLV_drive)
- flags_cmd_out=f_putcmd;
- else
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- /* possibly longer timeout periods necessary */
- current_drive->f_multisession=0;
- drvcmd[0]=CMD2_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[2]=0xAB;
- drvcmd[3]=0xFF; /* session */
- response_count=8;
- flags_cmd_out=f_putcmd;
- }
- else if (famT_drive)
- {
- current_drive->f_multisession=0;
- response_count=12;
- drvcmd[0]=CMDT_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[6]=CDROM_LEADOUT;
- drvcmd[8]=response_count;
- drvcmd[9]=0x00;
- }
- i=cmd_out();
- if (i<0) return (i);
- if ((famT_drive)&&(i<response_count)) return (-100-i);
- if ((fam1_drive)||(fam2_drive)||(fam0LV_drive))
- current_drive->xa_byte=infobuf[0];
- if (fam2_drive)
- {
- current_drive->first_session=infobuf[1];
- current_drive->last_session=infobuf[2];
- current_drive->n_first_track=infobuf[3];
- current_drive->n_last_track=infobuf[4];
- if (current_drive->first_session!=current_drive->last_session)
- {
- current_drive->f_multisession=1;
- current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
- }
-#if 0
- if (current_drive->first_session!=current_drive->last_session)
- {
- if (current_drive->last_session<=20)
- zwanzig=current_drive->last_session+1;
- else zwanzig=20;
- for (count=current_drive->first_session;count<zwanzig;count++)
- {
- drvcmd[0]=CMD2_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[2]=0xAB;
- drvcmd[3]=count;
- response_count=8;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<0) return (i);
- current_drive->msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
- }
- current_drive->diskstate_flags |= multisession_bit;
- }
-#endif
- drvcmd[0]=CMD2_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[2]=0xAA;
- drvcmd[3]=0xFF;
- response_count=5;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<0) return (i);
- current_drive->size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
- current_drive->size_blk=msf2blk(current_drive->size_msf);
- current_drive->CDsize_frm=current_drive->size_blk+1;
- }
- else if (famT_drive)
- {
- current_drive->size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
- current_drive->size_blk=msf2blk(current_drive->size_msf);
- current_drive->CDsize_frm=current_drive->size_blk+1;
- current_drive->n_first_track=infobuf[2];
- current_drive->n_last_track=infobuf[3];
- }
- else
- {
- current_drive->n_first_track=infobuf[1];
- current_drive->n_last_track=infobuf[2];
- current_drive->size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
- current_drive->size_blk=msf2blk(current_drive->size_msf);
- if (famLV_drive) current_drive->CDsize_frm=current_drive->size_blk+1;
- }
- current_drive->diskstate_flags |= toc_bit;
- msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n",
- current_drive->xa_byte,
- current_drive->n_first_track,
- current_drive->n_last_track,
- current_drive->size_msf,
- current_drive->first_session,
- current_drive->last_session);
- return (0);
-}
-/*==========================================================================*/
-static int cc_ReadTocEntry(int num)
-{
- int i;
-
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_READTOC;
- drvcmd[2]=num;
- response_count=8;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam2_drive)
- {
- /* possibly longer timeout periods necessary */
- drvcmd[0]=CMD2_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[2]=num;
- response_count=5;
- flags_cmd_out=f_putcmd;
- }
- else if (fam0LV_drive)
- {
- drvcmd[0]=CMD0_READTOC;
- drvcmd[1]=0x02;
- drvcmd[2]=num;
- response_count=8;
- if (famLV_drive)
- flags_cmd_out=f_putcmd;
- else
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- }
- else if (famT_drive)
- {
- response_count=12;
- drvcmd[0]=CMDT_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[6]=num;
- drvcmd[8]=response_count;
- drvcmd[9]=0x00;
- }
- i=cmd_out();
- if (i<0) return (i);
- if ((famT_drive)&&(i<response_count)) return (-100-i);
- if ((fam1_drive)||(fam0LV_drive))
- {
- current_drive->TocEnt_nixbyte=infobuf[0];
- i=1;
- }
- else if (fam2_drive) i=0;
- else if (famT_drive) i=5;
- current_drive->TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
- if ((fam1_drive)||(fam0L_drive))
- {
- current_drive->TocEnt_number=infobuf[i++];
- current_drive->TocEnt_format=infobuf[i];
- }
- else
- {
- current_drive->TocEnt_number=num;
- current_drive->TocEnt_format=0;
- }
- if (fam1_drive) i=4;
- else if (fam0LV_drive) i=5;
- else if (fam2_drive) i=2;
- else if (famT_drive) i=9;
- current_drive->TocEnt_address=make32(make16(0,infobuf[i]),
- make16(infobuf[i+1],infobuf[i+2]));
- for (i=0;i<response_count;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_ECS,"TocEntry:%s\n", msgbuf);
- msg(DBG_TOC,"TocEntry: %02X %02X %02X %02X %08X\n",
- current_drive->TocEnt_nixbyte, current_drive->TocEnt_ctl_adr,
- current_drive->TocEnt_number, current_drive->TocEnt_format,
- current_drive->TocEnt_address);
- return (0);
-}
-/*==========================================================================*/
-static int cc_ReadPacket(void)
-{
- int i;
-
- clr_cmdbuf();
- drvcmd[0]=CMD0_PACKET;
- drvcmd[1]=response_count;
- if(famL_drive) flags_cmd_out=f_putcmd;
- else if (fam01_drive)
- flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
- else if (fam2_drive) return (-1); /* not implemented yet */
- else if (famT_drive)
- {
- return (-1);
- }
- i=cmd_out();
- return (i);
-}
-/*==========================================================================*/
-static int convert_UPC(u_char *p)
-{
- int i;
-
- p++;
- if (fam0L_drive) p[13]=0;
- for (i=0;i<7;i++)
- {
- if (fam1_drive) current_drive->UPC_buf[i]=swap_nibbles(*p++);
- else if (fam0L_drive)
- {
- current_drive->UPC_buf[i]=((*p++)<<4)&0xFF;
- current_drive->UPC_buf[i] |= *p++;
- }
- else if (famT_drive)
- {
- return (-1);
- }
- else /* CD200 */
- {
- return (-1);
- }
- }
- current_drive->UPC_buf[6] &= 0xF0;
- return (0);
-}
-/*==========================================================================*/
-static int cc_ReadUPC(void)
-{
- int i;
-#if TEST_UPC
- int block, checksum;
-#endif /* TEST_UPC */
-
- if (fam2_drive) return (0); /* not implemented yet */
- if (famT_drive) return (0); /* not implemented yet */
- if (famV_drive) return (0); /* not implemented yet */
-#if 1
- if (fam0_drive) return (0); /* but it should work */
-#endif
-
- current_drive->diskstate_flags &= ~upc_bit;
-#if TEST_UPC
- for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
- {
-#endif /* TEST_UPC */
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_READ_UPC;
-#if TEST_UPC
- drvcmd[1]=(block>>16)&0xFF;
- drvcmd[2]=(block>>8)&0xFF;
- drvcmd[3]=block&0xFF;
-#endif /* TEST_UPC */
- response_count=8;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam0L_drive)
- {
- drvcmd[0]=CMD0_READ_UPC;
-#if TEST_UPC
- drvcmd[2]=(block>>16)&0xFF;
- drvcmd[3]=(block>>8)&0xFF;
- drvcmd[4]=block&0xFF;
-#endif /* TEST_UPC */
- response_count=0;
- flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
- }
- else if (fam2_drive)
- {
- return (-1);
- }
- else if (famT_drive)
- {
- return (-1);
- }
- i=cmd_out();
- if (i<0)
- {
- msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
- return (i);
- }
- if (fam0L_drive)
- {
- response_count=16;
- if (famL_drive) flags_cmd_out=f_putcmd;
- i=cc_ReadPacket();
- if (i<0)
- {
- msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
- return (i);
- }
- }
-#if TEST_UPC
- checksum=0;
-#endif /* TEST_UPC */
- for (i=0;i<(fam1_drive?8:16);i++)
- {
-#if TEST_UPC
- checksum |= infobuf[i];
-#endif /* TEST_UPC */
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- }
- msgbuf[i*3]=0;
- msg(DBG_UPC,"UPC info:%s\n", msgbuf);
-#if TEST_UPC
- if ((checksum&0x7F)!=0) break;
- }
-#endif /* TEST_UPC */
- current_drive->UPC_ctl_adr=0;
- if (fam1_drive) i=0;
- else i=2;
- if ((infobuf[i]&0x80)!=0)
- {
- convert_UPC(&infobuf[i]);
- current_drive->UPC_ctl_adr = (current_drive->TocEnt_ctl_adr & 0xF0) | 0x02;
- }
- for (i=0;i<7;i++)
- sprintf(&msgbuf[i*3], " %02X", current_drive->UPC_buf[i]);
- sprintf(&msgbuf[i*3], " (%02X)", current_drive->UPC_ctl_adr);
- msgbuf[i*3+5]=0;
- msg(DBG_UPC,"UPC code:%s\n", msgbuf);
- current_drive->diskstate_flags |= upc_bit;
- return (0);
-}
-
-static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
- int i;
- unsigned char *mcnp = mcn->medium_catalog_number;
- unsigned char *resp;
-
- current_drive->diskstate_flags &= ~upc_bit;
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_READ_UPC;
- response_count=8;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- }
- else if (fam0L_drive)
- {
- drvcmd[0]=CMD0_READ_UPC;
- response_count=0;
- flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
- }
- else if (fam2_drive)
- {
- return (-1);
- }
- else if (famT_drive)
- {
- return (-1);
- }
- i=cmd_out();
- if (i<0)
- {
- msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
- return (i);
- }
- if (fam0L_drive)
- {
- response_count=16;
- if (famL_drive) flags_cmd_out=f_putcmd;
- i=cc_ReadPacket();
- if (i<0)
- {
- msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
- return (i);
- }
- }
- current_drive->UPC_ctl_adr=0;
- if (fam1_drive) i=0;
- else i=2;
-
- resp = infobuf + i;
- if (*resp++ == 0x80) {
- /* packed bcd to single ASCII digits */
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- }
- *mcnp = '\0';
-
- current_drive->diskstate_flags |= upc_bit;
- return (0);
-}
-
-/*==========================================================================*/
-static int cc_CheckMultiSession(void)
-{
- int i;
-
- if (fam2_drive) return (0);
- current_drive->f_multisession=0;
- current_drive->lba_multi=0;
- if (fam0_drive) return (0);
- clr_cmdbuf();
- if (fam1_drive)
- {
- drvcmd[0]=CMD1_MULTISESS;
- response_count=6;
- flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
- i=cmd_out();
- if (i<0) return (i);
- if ((infobuf[0]&0x80)!=0)
- {
- current_drive->f_multisession=1;
- current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[1]),
- make16(infobuf[2],infobuf[3])));
- }
- }
- else if (famLV_drive)
- {
- drvcmd[0]=CMDL_MULTISESS;
- drvcmd[1]=3;
- drvcmd[2]=1;
- response_count=8;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<0) return (i);
- current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),
- make16(infobuf[6],infobuf[7])));
- }
- else if (famT_drive)
- {
- response_count=12;
- drvcmd[0]=CMDT_DISKINFO;
- drvcmd[1]=0x02;
- drvcmd[6]=0;
- drvcmd[8]=response_count;
- drvcmd[9]=0x40;
- i=cmd_out();
- if (i<0) return (i);
- if (i<response_count) return (-100-i);
- current_drive->first_session=infobuf[2];
- current_drive->last_session=infobuf[3];
- current_drive->track_of_last_session=infobuf[6];
- if (current_drive->first_session!=current_drive->last_session)
- {
- current_drive->f_multisession=1;
- current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
- }
- }
- for (i=0;i<response_count;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, current_drive->lba_multi);
- if (current_drive->lba_multi>200)
- {
- current_drive->f_multisession=1;
- msg(DBG_MUL,"MultiSession base: %06X\n", current_drive->lba_multi);
- }
- return (0);
-}
-/*==========================================================================*/
-#ifdef FUTURE
-static int cc_SubChanInfo(int frame, int count, u_char *buffer)
- /* "frame" is a RED BOOK (msf-bin) address */
-{
- int i;
-
- if (fam0LV_drive) return (-ENOSYS); /* drive firmware lacks it */
- if (famT_drive)
- {
- return (-1);
- }
-#if 0
- if (current_drive->audio_state!=audio_playing) return (-ENODATA);
-#endif
- clr_cmdbuf();
- drvcmd[0]=CMD1_SUBCHANINF;
- drvcmd[1]=(frame>>16)&0xFF;
- drvcmd[2]=(frame>>8)&0xFF;
- drvcmd[3]=frame&0xFF;
- drvcmd[5]=(count>>8)&0xFF;
- drvcmd[6]=count&0xFF;
- flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
- cmd_type=READ_SC;
- current_drive->frame_size=CD_FRAMESIZE_SUB;
- i=cmd_out(); /* which buffer to use? */
- return (i);
-}
-#endif /* FUTURE */
-/*==========================================================================*/
-static void __init check_datarate(void)
-{
- int i=0;
-
- msg(DBG_IOX,"check_datarate entered.\n");
- datarate=0;
-#if TEST_STI
- for (i=0;i<=1000;i++) printk(".");
-#endif
- /* set a timer to make (timed_out_delay!=0) after 1.1 seconds */
-#if 1
- del_timer(&delay_timer);
-#endif
- delay_timer.expires=jiffies+11*HZ/10;
- timed_out_delay=0;
- add_timer(&delay_timer);
-#if 0
- msg(DBG_TIM,"delay timer started (11*HZ/10).\n");
-#endif
- do
- {
- i=inb(CDi_status);
- datarate++;
-#if 1
- if (datarate>0x6FFFFFFF) break;
-#endif
- }
- while (!timed_out_delay);
- del_timer(&delay_timer);
-#if 0
- msg(DBG_TIM,"datarate: %04X\n", datarate);
-#endif
- if (datarate<65536) datarate=65536;
- maxtim16=datarate*16;
- maxtim04=datarate*4;
- maxtim02=datarate*2;
- maxtim_8=datarate/32;
-#if LONG_TIMING
- maxtim_data=datarate/100;
-#else
- maxtim_data=datarate/300;
-#endif /* LONG_TIMING */
-#if 0
- msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data);
-#endif
-}
-/*==========================================================================*/
-#if 0
-static int c2_ReadError(int fam)
-{
- int i;
-
- clr_cmdbuf();
- response_count=9;
- clr_respo_buf(9);
- if (fam==1)
- {
- drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
- i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
- }
- else if (fam==2)
- {
- drvcmd[0]=CMD2_READ_ERR;
- i=do_cmd(f_putcmd);
- }
- else return (-1);
- return (i);
-}
-#endif
-/*==========================================================================*/
-static void __init ask_mail(void)
-{
- int i;
-
- msg(DBG_INF, "please mail the following lines to emoenke@gwdg.de\n");
- msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n");
- msg(DBG_INF, "%s\n", VERSION);
- msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n",
- CDo_command, type, current_drive->drive_model, current_drive->drv_id);
- for (i=0;i<12;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_INF,"infobuf =%s\n", msgbuf);
- for (i=0;i<12;i++)
- sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_INF,"infobuf =%s\n", msgbuf);
-}
-/*==========================================================================*/
-static int __init check_version(void)
-{
- int i, j, l;
- int teac_possible=0;
-
- msg(DBG_INI,"check_version: id=%d, d=%d.\n", current_drive->drv_id, current_drive - D_S);
- current_drive->drv_type=0;
-
- /* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */
- /* clear any pending error state */
- clr_cmdbuf();
- drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
- response_count=9;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
- /* read drive version */
- clr_cmdbuf();
- for (i=0;i<12;i++) infobuf[i]=0;
- drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
- response_count=12; /* fam1: only 11 */
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<-1) msg(DBG_INI,"CMD0_READ_VER returns %d\n",i);
- if (i==-11) teac_possible++;
- j=0;
- for (i=0;i<12;i++) j+=infobuf[i];
- if (j)
- {
- for (i=0;i<12;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_ECS,"infobuf =%s\n", msgbuf);
- for (i=0;i<12;i++)
- sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_ECS,"infobuf =%s\n", msgbuf);
- }
- for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
- if (i==4)
- {
- current_drive->drive_model[0]='C';
- current_drive->drive_model[1]='R';
- current_drive->drive_model[2]='-';
- current_drive->drive_model[3]='5';
- current_drive->drive_model[4]=infobuf[i++];
- current_drive->drive_model[5]=infobuf[i++];
- current_drive->drive_model[6]=0;
- current_drive->drv_type=drv_fam1;
- }
- if (!current_drive->drv_type)
- {
- for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
- if (i==8)
- {
- current_drive->drive_model[0]='C';
- current_drive->drive_model[1]='R';
- current_drive->drive_model[2]='-';
- current_drive->drive_model[3]='5';
- current_drive->drive_model[4]='2';
- current_drive->drive_model[5]='x';
- current_drive->drive_model[6]=0;
- current_drive->drv_type=drv_fam0;
- }
- }
- if (!current_drive->drv_type)
- {
- for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
- if (i==8)
- {
- for (j=0;j<8;j++)
- current_drive->drive_model[j]=infobuf[j];
- current_drive->drive_model[8]=0;
- current_drive->drv_type=drv_famL;
- }
- }
- if (!current_drive->drv_type)
- {
- for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break;
- if (i==6)
- {
- for (j=0;j<6;j++)
- current_drive->drive_model[j]=infobuf[j];
- current_drive->drive_model[6]=0;
- current_drive->drv_type=drv_famV;
- i+=2; /* 2 blanks before version */
- }
- }
- if (!current_drive->drv_type)
- {
- /* check for CD200 */
- clr_cmdbuf();
- drvcmd[0]=CMD2_READ_ERR;
- response_count=9;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<0) msg(DBG_INI,"CMD2_READERR returns %d (ok anyway).\n",i);
- if (i<0) msg(DBG_000,"CMD2_READERR returns %d (ok anyway).\n",i);
- /* read drive version */
- clr_cmdbuf();
- for (i=0;i<12;i++) infobuf[i]=0;
- if (sbpro_type==1) OUT(CDo_sel_i_d,0);
-#if 0
- OUT(CDo_reset,0);
- sbp_sleep(6*HZ);
- OUT(CDo_enable,current_drive->drv_sel);
-#endif
- drvcmd[0]=CMD2_READ_VER;
- response_count=12;
- flags_cmd_out=f_putcmd;
- i=cmd_out();
- if (i<0) msg(DBG_INI,"CMD2_READ_VER returns %d\n",i);
- if (i==-7) teac_possible++;
- j=0;
- for (i=0;i<12;i++) j+=infobuf[i];
- if (j)
- {
- for (i=0;i<12;i++)
- sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_IDX,"infobuf =%s\n", msgbuf);
- for (i=0;i<12;i++)
- sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
- msgbuf[i*3]=0;
- msg(DBG_IDX,"infobuf =%s\n", msgbuf);
- }
- if (i>=0)
- {
- for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
- if (i==5)
- {
- current_drive->drive_model[0]='C';
- current_drive->drive_model[1]='D';
- current_drive->drive_model[2]='2';
- current_drive->drive_model[3]='0';
- current_drive->drive_model[4]='0';
- current_drive->drive_model[5]=infobuf[i++];
- current_drive->drive_model[6]=infobuf[i++];
- current_drive->drive_model[7]=0;
- current_drive->drv_type=drv_fam2;
- }
- }
- }
- if (!current_drive->drv_type)
- {
- /* check for TEAC CD-55A */
- msg(DBG_TEA,"teac_possible: %d\n",teac_possible);
- for (j=1;j<=((current_drive->drv_id==0)?3:1);j++)
- {
- for (l=1;l<=((current_drive->drv_id==0)?10:1);l++)
- {
- msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l);
- if (sbpro_type==1) OUT(CDo_reset,0);
- else
- {
- OUT(CDo_enable,current_drive->drv_sel);
- OUT(CDo_sel_i_d,0);
- OUT(CDo_command,CMDT_RESET);
- for (i=0;i<9;i++) OUT(CDo_command,0);
- }
- sbp_sleep(5*HZ/10);
- OUT(CDo_enable,current_drive->drv_sel);
- OUT(CDo_sel_i_d,0);
- i=inb(CDi_status);
- msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i);
-#if 0
- if (i&s_not_result_ready) continue; /* drive not present or ready */
-#endif
- i=inb(CDi_info);
- msg(DBG_TEA,"TEAC CDi_info: %02X.\n",i);
- if (i==0x55) break; /* drive found */
- }
- if (i==0x55) break; /* drive found */
- }
- if (i==0x55) /* drive found */
- {
- msg(DBG_TEA,"TEAC drive found.\n");
- clr_cmdbuf();
- flags_cmd_out=f_putcmd;
- response_count=12;
- drvcmd[0]=CMDT_READ_VER;
- drvcmd[4]=response_count;
- for (i=0;i<12;i++) infobuf[i]=0;
- i=cmd_out_T();
- if (i!=0) msg(DBG_TEA,"cmd_out_T(CMDT_READ_VER) returns %d.\n",i);
- for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break;
- if (i==6)
- {
- current_drive->drive_model[0]='C';
- current_drive->drive_model[1]='D';
- current_drive->drive_model[2]='-';
- current_drive->drive_model[3]='5';
- current_drive->drive_model[4]='5';
- current_drive->drive_model[5]=0;
- current_drive->drv_type=drv_famT;
- }
- }
- }
- if (!current_drive->drv_type)
- {
- msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,current_drive->drv_id);
- return (-522);
- }
- for (j=0;j<4;j++) current_drive->firmware_version[j]=infobuf[i+j];
- if (famL_drive)
- {
- u_char lcs_firm_e1[]="A E1";
- u_char lcs_firm_f4[]="A4F4";
-
- for (j=0;j<4;j++)
- if (current_drive->firmware_version[j]!=lcs_firm_e1[j]) break;
- if (j==4) current_drive->drv_type=drv_e1;
-
- for (j=0;j<4;j++)
- if (current_drive->firmware_version[j]!=lcs_firm_f4[j]) break;
- if (j==4) current_drive->drv_type=drv_f4;
-
- if (current_drive->drv_type==drv_famL) ask_mail();
- }
- else if (famT_drive)
- {
- j=infobuf[4]; /* one-byte version??? - here: 0x15 */
- if (j=='5')
- {
- current_drive->firmware_version[0]=infobuf[7];
- current_drive->firmware_version[1]=infobuf[8];
- current_drive->firmware_version[2]=infobuf[10];
- current_drive->firmware_version[3]=infobuf[11];
- }
- else
- {
- if (j!=0x15) ask_mail();
- current_drive->firmware_version[0]='0';
- current_drive->firmware_version[1]='.';
- current_drive->firmware_version[2]='0'+(j>>4);
- current_drive->firmware_version[3]='0'+(j&0x0f);
- }
- }
- else /* CR-52x, CR-56x, CD200, ECS-AT */
- {
- j = (current_drive->firmware_version[0] & 0x0F) * 100 +
- (current_drive->firmware_version[2] & 0x0F) *10 +
- (current_drive->firmware_version[3] & 0x0F);
- if (fam0_drive)
- {
- if (j<200) current_drive->drv_type=drv_199;
- else if (j<201) current_drive->drv_type=drv_200;
- else if (j<210) current_drive->drv_type=drv_201;
- else if (j<211) current_drive->drv_type=drv_210;
- else if (j<300) current_drive->drv_type=drv_211;
- else if (j>=300) current_drive->drv_type=drv_300;
- }
- else if (fam1_drive)
- {
- if (j<100) current_drive->drv_type=drv_099;
- else
- {
- current_drive->drv_type=drv_100;
- if ((j!=500)&&(j!=102)) ask_mail();
- }
- }
- else if (fam2_drive)
- {
- if (current_drive->drive_model[5]=='F')
- {
- if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210))
- ask_mail(); /* unknown version at time */
- }
- else
- {
- msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
- if ((j!=101)&&(j!=35))
- ask_mail(); /* unknown version at time */
- }
- }
- else if (famV_drive)
- {
- if ((j==100)||(j==150)) current_drive->drv_type=drv_at;
- ask_mail(); /* hopefully we get some feedback by this */
- }
- }
- msg(DBG_LCS,"drive type %02X\n",current_drive->drv_type);
- msg(DBG_INI,"check_version done.\n");
- return (0);
-}
-/*==========================================================================*/
-static void switch_drive(struct sbpcd_drive *p)
-{
- current_drive = p;
- OUT(CDo_enable,current_drive->drv_sel);
- msg(DBG_DID,"drive %d (ID=%d) activated.\n",
- current_drive - D_S, current_drive->drv_id);
- return;
-}
-/*==========================================================================*/
-#ifdef PATH_CHECK
-/*
- * probe for the presence of an interface card
- */
-static int __init check_card(int port)
-{
-#undef N_RESPO
-#define N_RESPO 20
- int i, j, k;
- u_char response[N_RESPO];
- u_char save_port0;
- u_char save_port3;
-
- msg(DBG_INI,"check_card entered.\n");
- save_port0=inb(port+0);
- save_port3=inb(port+3);
-
- for (j=0;j<NR_SBPCD;j++)
- {
- OUT(port+3,j) ; /* enable drive #j */
- OUT(port+0,CMD0_PATH_CHECK);
- for (i=10;i>0;i--) OUT(port+0,0);
- for (k=0;k<N_RESPO;k++) response[k]=0;
- for (k=0;k<N_RESPO;k++)
- {
- for (i=10000;i>0;i--)
- {
- if (inb(port+1)&s_not_result_ready) continue;
- response[k]=inb(port+0);
- break;
- }
- }
- for (i=0;i<N_RESPO;i++)
- sprintf(&msgbuf[i*3], " %02X", response[i]);
- msgbuf[i*3]=0;
- msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
- OUT(port+0,CMD0_PATH_CHECK);
- for (i=10;i>0;i--) OUT(port+0,0);
- for (k=0;k<N_RESPO;k++) response[k]=0xFF;
- for (k=0;k<N_RESPO;k++)
- {
- for (i=10000;i>0;i--)
- {
- if (inb(port+1)&s_not_result_ready) continue;
- response[k]=inb(port+0);
- break;
- }
- }
- for (i=0;i<N_RESPO;i++)
- sprintf(&msgbuf[i*3], " %02X", response[i]);
- msgbuf[i*3]=0;
- msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
-
- if (response[0]==0xAA)
- if (response[1]==0x55)
- return (0);
- }
- for (j=0;j<NR_SBPCD;j++)
- {
- OUT(port+3,j) ; /* enable drive #j */
- OUT(port+0,CMD2_READ_VER);
- for (i=10;i>0;i--) OUT(port+0,0);
- for (k=0;k<N_RESPO;k++) response[k]=0;
- for (k=0;k<N_RESPO;k++)
- {
- for (i=1000000;i>0;i--)
- {
- if (inb(port+1)&s_not_result_ready) continue;
- response[k]=inb(port+0);
- break;
- }
- }
- for (i=0;i<N_RESPO;i++)
- sprintf(&msgbuf[i*3], " %02X", response[i]);
- msgbuf[i*3]=0;
- msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
-
- OUT(port+0,CMD2_READ_VER);
- for (i=10;i>0;i--) OUT(port+0,0);
- for (k=0;k<N_RESPO;k++) response[k]=0xFF;
- for (k=0;k<N_RESPO;k++)
- {
- for (i=1000000;i>0;i--)
- {
- if (inb(port+1)&s_not_result_ready) continue;
- response[k]=inb(port+0);
- break;
- }
- }
- for (i=0;i<N_RESPO;i++)
- sprintf(&msgbuf[i*3], " %02X", response[i]);
- msgbuf[i*3]=0;
- msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
-
- if (response[0]==0xAA)
- if (response[1]==0x55)
- return (0);
- }
- OUT(port+0,save_port0);
- OUT(port+3,save_port3);
- return (0); /* in any case - no real "function" at time */
-}
-#endif /* PATH_CHECK */
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * probe for the presence of drives on the selected controller
- */
-static int __init check_drives(void)
-{
- int i, j;
-
- msg(DBG_INI,"check_drives entered.\n");
- ndrives=0;
- for (j=0;j<max_drives;j++)
- {
- struct sbpcd_drive *p = D_S + ndrives;
- p->drv_id=j;
- if (sbpro_type==1) p->drv_sel=(j&0x01)<<1|(j&0x02)>>1;
- else p->drv_sel=j;
- switch_drive(p);
- msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
- msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
- i=check_version();
- if (i<0) msg(DBG_INI,"check_version returns %d.\n",i);
- else
- {
- current_drive->drv_options=drv_pattern[j];
- if (fam0L_drive) current_drive->drv_options&=~(speed_auto|speed_300|speed_150);
- msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n",
- current_drive - D_S,
- current_drive->drv_id,
- current_drive->drive_model,
- current_drive->firmware_version,
- CDo_command,
- sbpro_type);
- ndrives++;
- }
- }
- for (j=ndrives;j<NR_SBPCD;j++) D_S[j].drv_id=-1;
- if (ndrives==0) return (-1);
- return (0);
-}
-/*==========================================================================*/
-#ifdef FUTURE
-/*
- * obtain if requested service disturbs current audio state
- */
-static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
-{
- switch (audio_state) /* audio status from controller */
- {
- case aud_11: /* "audio play in progress" */
- case audx11:
- switch (func) /* DOS command code */
- {
- case cmd_07: /* input flush */
- case cmd_0d: /* open device */
- case cmd_0e: /* close device */
- case cmd_0c: /* ioctl output */
- return (1);
- case cmd_03: /* ioctl input */
- switch (subfunc)
- /* DOS ioctl input subfunction */
- {
- case cxi_00:
- case cxi_06:
- case cxi_09:
- return (1);
- default:
- return (ERROR15);
- }
- return (1);
- default:
- return (ERROR15);
- }
- return (1);
- case aud_12: /* "audio play paused" */
- case audx12:
- return (1);
- default:
- return (2);
- }
-}
-/*==========================================================================*/
-/* allowed is only
- * ioctl_o, flush_input, open_device, close_device,
- * tell_address, tell_volume, tell_capabiliti,
- * tell_framesize, tell_CD_changed, tell_audio_posi
- */
-static int check_allowed1(u_char func1, u_char func2)
-{
-#if 000
- if (func1==ioctl_o) return (0);
- if (func1==read_long) return (-1);
- if (func1==read_long_prefetch) return (-1);
- if (func1==seek) return (-1);
- if (func1==audio_play) return (-1);
- if (func1==audio_pause) return (-1);
- if (func1==audio_resume) return (-1);
- if (func1!=ioctl_i) return (0);
- if (func2==tell_SubQ_run_tot) return (-1);
- if (func2==tell_cdsize) return (-1);
- if (func2==tell_TocDescrip) return (-1);
- if (func2==tell_TocEntry) return (-1);
- if (func2==tell_subQ_info) return (-1);
- if (fam1_drive) if (func2==tell_SubChanInfo) return (-1);
- if (func2==tell_UPC) return (-1);
-#else
- return (0);
-#endif
-}
-/*==========================================================================*/
-static int check_allowed2(u_char func1, u_char func2)
-{
-#if 000
- if (func1==read_long) return (-1);
- if (func1==read_long_prefetch) return (-1);
- if (func1==seek) return (-1);
- if (func1==audio_play) return (-1);
- if (func1!=ioctl_o) return (0);
- if (fam1_drive)
- {
- if (func2==EjectDisk) return (-1);
- if (func2==CloseTray) return (-1);
- }
-#else
- return (0);
-#endif
-}
-/*==========================================================================*/
-static int check_allowed3(u_char func1, u_char func2)
-{
-#if 000
- if (func1==ioctl_i)
- {
- if (func2==tell_address) return (0);
- if (func2==tell_capabiliti) return (0);
- if (func2==tell_CD_changed) return (0);
- if (fam0L_drive) if (func2==tell_SubChanInfo) return (0);
- return (-1);
- }
- if (func1==ioctl_o)
- {
- if (func2==DriveReset) return (0);
- if (fam0L_drive)
- {
- if (func2==EjectDisk) return (0);
- if (func2==LockDoor) return (0);
- if (func2==CloseTray) return (0);
- }
- return (-1);
- }
- if (func1==flush_input) return (-1);
- if (func1==read_long) return (-1);
- if (func1==read_long_prefetch) return (-1);
- if (func1==seek) return (-1);
- if (func1==audio_play) return (-1);
- if (func1==audio_pause) return (-1);
- if (func1==audio_resume) return (-1);
-#else
- return (0);
-#endif
-}
-/*==========================================================================*/
-static int seek_pos_audio_end(void)
-{
- int i;
-
- i=msf2blk(current_drive->pos_audio_end)-1;
- if (i<0) return (-1);
- i=cc_Seek(i,0);
- return (i);
-}
-#endif /* FUTURE */
-/*==========================================================================*/
-static int ReadToC(void)
-{
- int i, j;
- current_drive->diskstate_flags &= ~toc_bit;
- current_drive->ored_ctl_adr=0;
- /* special handling of CD-I HE */
- if ((current_drive->n_first_track == 2 && current_drive->n_last_track == 2) ||
- current_drive->xa_byte == 0x10)
- {
- current_drive->TocBuffer[1].nixbyte=0;
- current_drive->TocBuffer[1].ctl_adr=0x40;
- current_drive->TocBuffer[1].number=1;
- current_drive->TocBuffer[1].format=0;
- current_drive->TocBuffer[1].address=blk2msf(0);
- current_drive->ored_ctl_adr |= 0x40;
- current_drive->n_first_track = 1;
- current_drive->n_last_track = 1;
- current_drive->xa_byte = 0x10;
- j = 2;
- } else
- for (j=current_drive->n_first_track;j<=current_drive->n_last_track;j++)
- {
- i=cc_ReadTocEntry(j);
- if (i<0)
- {
- msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i);
- return (i);
- }
- current_drive->TocBuffer[j].nixbyte=current_drive->TocEnt_nixbyte;
- current_drive->TocBuffer[j].ctl_adr=current_drive->TocEnt_ctl_adr;
- current_drive->TocBuffer[j].number=current_drive->TocEnt_number;
- current_drive->TocBuffer[j].format=current_drive->TocEnt_format;
- current_drive->TocBuffer[j].address=current_drive->TocEnt_address;
- current_drive->ored_ctl_adr |= current_drive->TocEnt_ctl_adr;
- }
- /* fake entry for LeadOut Track */
- current_drive->TocBuffer[j].nixbyte=0;
- current_drive->TocBuffer[j].ctl_adr=0;
- current_drive->TocBuffer[j].number=CDROM_LEADOUT;
- current_drive->TocBuffer[j].format=0;
- current_drive->TocBuffer[j].address=current_drive->size_msf;
-
- current_drive->diskstate_flags |= toc_bit;
- return (0);
-}
-/*==========================================================================*/
-static int DiskInfo(void)
-{
- int i, j;
-
- current_drive->mode=READ_M1;
-
-#undef LOOP_COUNT
-#define LOOP_COUNT 10 /* needed for some "old" drives */
-
- msg(DBG_000,"DiskInfo entered.\n");
- for (j=1;j<LOOP_COUNT;j++)
- {
-#if 0
- i=SetSpeed();
- if (i<0)
- {
- msg(DBG_INF,"DiskInfo: SetSpeed returns %d\n", i);
- continue;
- }
- i=cc_ModeSense();
- if (i<0)
- {
- msg(DBG_INF,"DiskInfo: cc_ModeSense returns %d\n", i);
- continue;
- }
-#endif
- i=cc_ReadCapacity();
- if (i>=0) break;
- msg(DBG_INF,"DiskInfo: ReadCapacity #%d returns %d\n", j, i);
-#if 0
- i=cc_DriveReset();
-#endif
- if (!fam0_drive && j == 2) break;
- }
- if (j==LOOP_COUNT) return (-33); /* give up */
-
- i=cc_ReadTocDescr();
- if (i<0)
- {
- msg(DBG_INF,"DiskInfo: ReadTocDescr returns %d\n", i);
- return (i);
- }
- i=ReadToC();
- if (i<0)
- {
- msg(DBG_INF,"DiskInfo: ReadToC returns %d\n", i);
- return (i);
- }
- i=cc_CheckMultiSession();
- if (i<0)
- {
- msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i);
- return (i);
- }
- if (current_drive->f_multisession) current_drive->sbp_bufsiz=1; /* possibly a weird PhotoCD */
- else current_drive->sbp_bufsiz=buffers;
- i=cc_ReadTocEntry(current_drive->n_first_track);
- if (i<0)
- {
- msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i);
- return (i);
- }
- i=cc_ReadUPC();
- if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i);
- if ((fam0L_drive) && (current_drive->xa_byte==0x20 || current_drive->xa_byte == 0x10))
- {
- /* XA disk with old drive */
- cc_ModeSelect(CD_FRAMESIZE_RAW1);
- cc_ModeSense();
- }
- if (famT_drive) cc_prep_mode_T();
- msg(DBG_000,"DiskInfo done.\n");
- return (0);
-}
-
-static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
- struct sbpcd_drive *p = cdi->handle;
- int st;
-
- if (CDSL_CURRENT != slot_nr) {
- /* we have no changer support */
- return -EINVAL;
- }
-
- cc_ReadStatus();
- st=ResponseStatus();
- if (st<0)
- {
- msg(DBG_INF,"sbpcd_drive_status: timeout.\n");
- return (0);
- }
- msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
- msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
- msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
- msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
- msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
- msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
-
-#if 0
- if (!(p->status_bits & p_door_closed)) return CDS_TRAY_OPEN;
- if (p->status_bits & p_disk_ok) return CDS_DISC_OK;
- if (p->status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
-
- return CDS_NO_DISC;
-#else
- if (p->status_bits & p_spinning) return CDS_DISC_OK;
-/* return CDS_TRAY_OPEN; */
- return CDS_NO_DISC;
-
-#endif
-
-}
-
-
-/*==========================================================================*/
-#ifdef FUTURE
-/*
- * called always if driver gets entered
- * returns 0 or ERROR2 or ERROR15
- */
-static int prepare(u_char func, u_char subfunc)
-{
- int i;
-
- if (fam0L_drive)
- {
- i=inb(CDi_status);
- if (i&s_attention) GetStatus();
- }
- else if (fam1_drive) GetStatus();
- else if (fam2_drive) GetStatus();
- else if (famT_drive) GetStatus();
- if (current_drive->CD_changed==0xFF)
- {
- current_drive->diskstate_flags=0;
- current_drive->audio_state=0;
- if (!st_diskok)
- {
- i=check_allowed1(func,subfunc);
- if (i<0) return (-2);
- }
- else
- {
- i=check_allowed3(func,subfunc);
- if (i<0)
- {
- current_drive->CD_changed=1;
- return (-15);
- }
- }
- }
- else
- {
- if (!st_diskok)
- {
- current_drive->diskstate_flags=0;
- current_drive->audio_state=0;
- i=check_allowed1(func,subfunc);
- if (i<0) return (-2);
- }
- else
- {
- if (st_busy)
- {
- if (current_drive->audio_state!=audio_pausing)
- {
- i=check_allowed2(func,subfunc);
- if (i<0) return (-2);
- }
- }
- else
- {
- if (current_drive->audio_state==audio_playing) seek_pos_audio_end();
- current_drive->audio_state=0;
- }
- if (!frame_size_valid)
- {
- i=DiskInfo();
- if (i<0)
- {
- current_drive->diskstate_flags=0;
- current_drive->audio_state=0;
- i=check_allowed1(func,subfunc);
- if (i<0) return (-2);
- }
- }
- }
- }
- return (0);
-}
-#endif /* FUTURE */
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * Check the results of the "get status" command.
- */
-static int sbp_status(void)
-{
- int st;
-
- st=ResponseStatus();
- if (st<0)
- {
- msg(DBG_INF,"sbp_status: timeout.\n");
- return (0);
- }
-
- if (!st_spinning) msg(DBG_SPI,"motor got off - ignoring.\n");
-
- if (st_check)
- {
- msg(DBG_INF,"st_check detected - retrying.\n");
- return (0);
- }
- if (!st_door_closed)
- {
- msg(DBG_INF,"door is open - retrying.\n");
- return (0);
- }
- if (!st_caddy_in)
- {
- msg(DBG_INF,"disk removed - retrying.\n");
- return (0);
- }
- if (!st_diskok)
- {
- msg(DBG_INF,"!st_diskok detected - retrying.\n");
- return (0);
- }
- if (st_busy)
- {
- msg(DBG_INF,"st_busy detected - retrying.\n");
- return (0);
- }
- return (1);
-}
-/*==========================================================================*/
-
-static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp)
-{
- struct sbpcd_drive *p = cdi->handle;
- ms_infp->addr_format = CDROM_LBA;
- ms_infp->addr.lba = p->lba_multi;
- if (p->f_multisession)
- ms_infp->xa_flag=1; /* valid redirection address */
- else
- ms_infp->xa_flag=0; /* invalid redirection address */
-
- return 0;
-}
-
-static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
- void * arg)
-{
- struct sbpcd_drive *p = cdi->handle;
- int i, st, j;
-
- msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08p)\n", cdi->name, cmd, arg);
- if (p->drv_id==-1) {
- msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
- return (-ENXIO); /* no such drive */
- }
- down(&ioctl_read_sem);
- if (p != current_drive)
- switch_drive(p);
-
- msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
- switch (cmd) /* Sun-compatible */
- {
-
- case CDROMPAUSE: /* Pause the drive */
- msg(DBG_IOC,"ioctl: CDROMPAUSE entered.\n");
- /* pause the drive unit when it is currently in PLAY mode, */
- /* or reset the starting and ending locations when in PAUSED mode. */
- /* If applicable, at the next stopping point it reaches */
- /* the drive will discontinue playing. */
- switch (current_drive->audio_state)
- {
- case audio_playing:
- if (famL_drive) i=cc_ReadSubQ();
- else i=cc_Pause_Resume(1);
- if (i<0) RETURN_UP(-EIO);
- if (famL_drive) i=cc_Pause_Resume(1);
- else i=cc_ReadSubQ();
- if (i<0) RETURN_UP(-EIO);
- current_drive->pos_audio_start=current_drive->SubQ_run_tot;
- current_drive->audio_state=audio_pausing;
- RETURN_UP(0);
- case audio_pausing:
- i=cc_Seek(current_drive->pos_audio_start,1);
- if (i<0) RETURN_UP(-EIO);
- RETURN_UP(0);
- default:
- RETURN_UP(-EINVAL);
- }
-
- case CDROMRESUME: /* resume paused audio play */
- msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
- /* resume playing audio tracks when a previous PLAY AUDIO call has */
- /* been paused with a PAUSE command. */
- /* It will resume playing from the location saved in SubQ_run_tot. */
- if (current_drive->audio_state!=audio_pausing) RETURN_UP(-EINVAL);
- if (famL_drive)
- i=cc_PlayAudio(current_drive->pos_audio_start,
- current_drive->pos_audio_end);
- else i=cc_Pause_Resume(3);
- if (i<0) RETURN_UP(-EIO);
- current_drive->audio_state=audio_playing;
- RETURN_UP(0);
-
- case CDROMPLAYMSF:
- msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- if (current_drive->audio_state==audio_playing)
- {
- i=cc_Pause_Resume(1);
- if (i<0) RETURN_UP(-EIO);
- i=cc_ReadSubQ();
- if (i<0) RETURN_UP(-EIO);
- current_drive->pos_audio_start=current_drive->SubQ_run_tot;
- i=cc_Seek(current_drive->pos_audio_start,1);
- }
- memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf));
- /* values come as msf-bin */
- current_drive->pos_audio_start = (msf.cdmsf_min0<<16) |
- (msf.cdmsf_sec0<<8) |
- msf.cdmsf_frame0;
- current_drive->pos_audio_end = (msf.cdmsf_min1<<16) |
- (msf.cdmsf_sec1<<8) |
- msf.cdmsf_frame1;
- msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n",
- current_drive->pos_audio_start,current_drive->pos_audio_end);
- i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
- if (i<0)
- {
- msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
- DriveReset();
- current_drive->audio_state=0;
- RETURN_UP(-EIO);
- }
- current_drive->audio_state=audio_playing;
- RETURN_UP(0);
-
- case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- if (current_drive->audio_state==audio_playing)
- {
- msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
-#if 1
- RETURN_UP(0); /* just let us play on */
-#else
- RETURN_UP(-EINVAL); /* play on, but say "error" */
-#endif
- }
- memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti));
- msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
- ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1);
- if (ti.cdti_trk0<current_drive->n_first_track) RETURN_UP(-EINVAL);
- if (ti.cdti_trk0>current_drive->n_last_track) RETURN_UP(-EINVAL);
- if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
- if (ti.cdti_trk1>current_drive->n_last_track) ti.cdti_trk1=current_drive->n_last_track;
- current_drive->pos_audio_start=current_drive->TocBuffer[ti.cdti_trk0].address;
- current_drive->pos_audio_end=current_drive->TocBuffer[ti.cdti_trk1+1].address;
- i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
- if (i<0)
- {
- msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
- DriveReset();
- current_drive->audio_state=0;
- RETURN_UP(-EIO);
- }
- current_drive->audio_state=audio_playing;
- RETURN_UP(0);
-
- case CDROMREADTOCHDR: /* Read the table of contents header */
- msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n");
- tochdr.cdth_trk0=current_drive->n_first_track;
- tochdr.cdth_trk1=current_drive->n_last_track;
- memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
- RETURN_UP(0);
-
- case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
- msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n");
- memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
- i=tocentry.cdte_track;
- if (i==CDROM_LEADOUT) i=current_drive->n_last_track+1;
- else if (i<current_drive->n_first_track||i>current_drive->n_last_track)
- RETURN_UP(-EINVAL);
- tocentry.cdte_adr=current_drive->TocBuffer[i].ctl_adr&0x0F;
- tocentry.cdte_ctrl=(current_drive->TocBuffer[i].ctl_adr>>4)&0x0F;
- tocentry.cdte_datamode=current_drive->TocBuffer[i].format;
- if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
- {
- tocentry.cdte_addr.msf.minute=(current_drive->TocBuffer[i].address>>16)&0x00FF;
- tocentry.cdte_addr.msf.second=(current_drive->TocBuffer[i].address>>8)&0x00FF;
- tocentry.cdte_addr.msf.frame=current_drive->TocBuffer[i].address&0x00FF;
- }
- else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
- tocentry.cdte_addr.lba=msf2blk(current_drive->TocBuffer[i].address);
- else RETURN_UP(-EINVAL);
- memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
- RETURN_UP(0);
-
- case CDROMSTOP: /* Spin down the drive */
- msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- i=cc_Pause_Resume(1);
- current_drive->audio_state=0;
-#if 0
- cc_DriveReset();
-#endif
- RETURN_UP(i);
-
- case CDROMSTART: /* Spin up the drive */
- msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
- cc_SpinUp();
- current_drive->audio_state=0;
- RETURN_UP(0);
-
- case CDROMVOLCTRL: /* Volume control */
- msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
- memcpy(&volctrl,(char *) arg,sizeof(volctrl));
- current_drive->vol_chan0=0;
- current_drive->vol_ctrl0=volctrl.channel0;
- current_drive->vol_chan1=1;
- current_drive->vol_ctrl1=volctrl.channel1;
- i=cc_SetVolume();
- RETURN_UP(0);
-
- case CDROMVOLREAD: /* read Volume settings from drive */
- msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
- st=cc_GetVolume();
- if (st<0) RETURN_UP(st);
- volctrl.channel0=current_drive->vol_ctrl0;
- volctrl.channel1=current_drive->vol_ctrl1;
- volctrl.channel2=0;
- volctrl.channel2=0;
- memcpy((void *)arg,&volctrl,sizeof(volctrl));
- RETURN_UP(0);
-
- case CDROMSUBCHNL: /* Get subchannel info */
- msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n");
- /* Bogus, I can do better than this! --AJK
- if ((st_spinning)||(!subq_valid)) {
- i=cc_ReadSubQ();
- if (i<0) RETURN_UP(-EIO);
- }
- */
- i=cc_ReadSubQ();
- if (i<0) {
- j=cc_ReadError(); /* clear out error status from drive */
- current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
- /* get and set the disk state here,
- probably not the right place, but who cares!
- It makes it work properly! --AJK */
- if (current_drive->CD_changed==0xFF) {
- msg(DBG_000,"Disk changed detect\n");
- current_drive->diskstate_flags &= ~cd_size_bit;
- }
- RETURN_UP(-EIO);
- }
- if (current_drive->CD_changed==0xFF) {
- /* reread the TOC because the disk has changed! --AJK */
- msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n");
- i=DiskInfo();
- if(i==0) {
- current_drive->CD_changed=0x00; /* cd has changed, procede, */
- RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */
- } else {
- RETURN_UP(-EIO); /* we weren't ready yet! --AJK */
- }
- }
- memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
- /*
- This virtual crap is very bogus!
- It doesn't detect when the cd is done playing audio!
- Lets do this right with proper hardware register reading!
- */
- cc_ReadStatus();
- i=ResponseStatus();
- msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
- msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
- msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
- msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
- msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
- msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
- /* st_busy indicates if it's _ACTUALLY_ playing audio */
- switch (current_drive->audio_state)
- {
- case audio_playing:
- if(st_busy==0) {
- /* CD has stopped playing audio --AJK */
- current_drive->audio_state=audio_completed;
- SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
- } else {
- SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
- }
- break;
- case audio_pausing:
- SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
- break;
- case audio_completed:
- SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
- break;
- default:
- SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
- break;
- }
- SC.cdsc_adr=current_drive->SubQ_ctl_adr;
- SC.cdsc_ctrl=current_drive->SubQ_ctl_adr>>4;
- SC.cdsc_trk=bcd2bin(current_drive->SubQ_trk);
- SC.cdsc_ind=bcd2bin(current_drive->SubQ_pnt_idx);
- if (SC.cdsc_format==CDROM_LBA)
- {
- SC.cdsc_absaddr.lba=msf2blk(current_drive->SubQ_run_tot);
- SC.cdsc_reladdr.lba=msf2blk(current_drive->SubQ_run_trk);
- }
- else /* not only if (SC.cdsc_format==CDROM_MSF) */
- {
- SC.cdsc_absaddr.msf.minute=(current_drive->SubQ_run_tot>>16)&0x00FF;
- SC.cdsc_absaddr.msf.second=(current_drive->SubQ_run_tot>>8)&0x00FF;
- SC.cdsc_absaddr.msf.frame=current_drive->SubQ_run_tot&0x00FF;
- SC.cdsc_reladdr.msf.minute=(current_drive->SubQ_run_trk>>16)&0x00FF;
- SC.cdsc_reladdr.msf.second=(current_drive->SubQ_run_trk>>8)&0x00FF;
- SC.cdsc_reladdr.msf.frame=current_drive->SubQ_run_trk&0x00FF;
- }
- memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl));
- msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
- SC.cdsc_format,SC.cdsc_audiostatus,
- SC.cdsc_adr,SC.cdsc_ctrl,
- SC.cdsc_trk,SC.cdsc_ind,
- SC.cdsc_absaddr,SC.cdsc_reladdr);
- RETURN_UP(0);
-
- default:
- msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
- RETURN_UP(-EINVAL);
- } /* end switch(cmd) */
-}
-/*==========================================================================*/
-/*
- * Take care of the different block sizes between cdrom and Linux.
- */
-static void sbp_transfer(struct request *req)
-{
- long offs;
-
- while ( (req->nr_sectors > 0) &&
- (req->sector/4 >= current_drive->sbp_first_frame) &&
- (req->sector/4 <= current_drive->sbp_last_frame) )
- {
- offs = (req->sector - current_drive->sbp_first_frame * 4) * 512;
- memcpy(req->buffer, current_drive->sbp_buf + offs, 512);
- req->nr_sectors--;
- req->sector++;
- req->buffer += 512;
- }
-}
-/*==========================================================================*/
-/*
- * special end_request for sbpcd to solve CURRENT==NULL bug. (GTL)
- * GTL = Gonzalo Tornaria <tornaria@cmat.edu.uy>
- *
- * This is a kludge so we don't need to modify end_request.
- * We put the req we take out after INIT_REQUEST in the requests list,
- * so that end_request will discard it.
- *
- * The bug could be present in other block devices, perhaps we
- * should modify INIT_REQUEST and end_request instead, and
- * change every block device..
- *
- * Could be a race here?? Could e.g. a timer interrupt schedule() us?
- * If so, we should copy end_request here, and do it right.. (or
- * modify end_request and the block devices).
- *
- * In any case, the race here would be much small than it was, and
- * I couldn't reproduce..
- *
- * The race could be: suppose CURRENT==NULL. We put our req in the list,
- * and we are scheduled. Other process takes over, and gets into
- * do_sbpcd_request. It sees CURRENT!=NULL (it is == to our req), so
- * proceeds. It ends, so CURRENT is now NULL.. Now we awake somewhere in
- * end_request, but now CURRENT==NULL... oops!
- *
- */
-#undef DEBUG_GTL
-
-/*==========================================================================*/
-/*
- * I/O request routine, called from Linux kernel.
- */
-static void do_sbpcd_request(request_queue_t * q)
-{
- u_int block;
- u_int nsect;
- int status_tries, data_tries;
- struct request *req;
- struct sbpcd_drive *p;
-#ifdef DEBUG_GTL
- static int xx_nr=0;
- int xnr;
-#endif
-
- request_loop:
-#ifdef DEBUG_GTL
- xnr=++xx_nr;
-
- req = elv_next_request(q);
-
- if (!req)
- {
- printk( "do_sbpcd_request[%di](NULL), Pid:%d, Time:%li\n",
- xnr, current->pid, jiffies);
- printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n",
- xnr, jiffies);
- return;
- }
-
- printk(" do_sbpcd_request[%di](%p:%ld+%ld), Pid:%d, Time:%li\n",
- xnr, req, req->sector, req->nr_sectors, current->pid, jiffies);
-#endif
-
- req = elv_next_request(q); /* take out our request so no other */
- if (!req)
- return;
-
- if (req -> sector == -1)
- end_request(req, 0);
- spin_unlock_irq(q->queue_lock);
-
- down(&ioctl_read_sem);
- if (rq_data_dir(elv_next_request(q)) != READ)
- {
- msg(DBG_INF, "bad cmd %d\n", req->cmd[0]);
- goto err_done;
- }
- p = req->rq_disk->private_data;
-#if OLD_BUSY
- while (busy_audio) sbp_sleep(HZ); /* wait a bit */
- busy_data=1;
-#endif /* OLD_BUSY */
-
- if (p->audio_state==audio_playing) goto err_done;
- if (p != current_drive)
- switch_drive(p);
-
- block = req->sector; /* always numbered as 512-byte-pieces */
- nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
-
- msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
-#if 0
- msg(DBG_MUL,"read LBA %d\n", block/4);
-#endif
-
- sbp_transfer(req);
- /* if we satisfied the request from the buffer, we're done. */
- if (req->nr_sectors == 0)
- {
-#ifdef DEBUG_GTL
- printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 2, Time:%li\n",
- xnr, req, req->sector, req->nr_sectors, jiffies);
-#endif
- up(&ioctl_read_sem);
- spin_lock_irq(q->queue_lock);
- end_request(req, 1);
- goto request_loop;
- }
-
-#ifdef FUTURE
- i=prepare(0,0); /* at moment not really a hassle check, but ... */
- if (i!=0)
- msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
-#endif /* FUTURE */
-
- if (!st_spinning) cc_SpinUp();
-
- for (data_tries=n_retries; data_tries > 0; data_tries--)
- {
- for (status_tries=3; status_tries > 0; status_tries--)
- {
- flags_cmd_out |= f_respo3;
- cc_ReadStatus();
- if (sbp_status() != 0) break;
- if (st_check) cc_ReadError();
- sbp_sleep(1); /* wait a bit, try again */
- }
- if (status_tries == 0)
- {
- msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__);
- break;
- }
-
- sbp_read_cmd(req);
- sbp_sleep(0);
- if (sbp_data(req) != 0)
- {
-#ifdef SAFE_MIXED
- current_drive->has_data=2; /* is really a data disk */
-#endif /* SAFE_MIXED */
-#ifdef DEBUG_GTL
- printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
- xnr, req, req->sector, req->nr_sectors, jiffies);
-#endif
- up(&ioctl_read_sem);
- spin_lock_irq(q->queue_lock);
- end_request(req, 1);
- goto request_loop;
- }
- }
-
- err_done:
-#if OLD_BUSY
- busy_data=0;
-#endif /* OLD_BUSY */
-#ifdef DEBUG_GTL
- printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n",
- xnr, req, req->sector, req->nr_sectors, jiffies);
-#endif
- up(&ioctl_read_sem);
- sbp_sleep(0); /* wait a bit, try again */
- spin_lock_irq(q->queue_lock);
- end_request(req, 0);
- goto request_loop;
-}
-/*==========================================================================*/
-/*
- * build and send the READ command.
- */
-static void sbp_read_cmd(struct request *req)
-{
-#undef OLD
-
- int i;
- int block;
-
- current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
- current_drive->sbp_current = 0;
- block=req->sector/4;
- if (block+current_drive->sbp_bufsiz <= current_drive->CDsize_frm)
- current_drive->sbp_read_frames = current_drive->sbp_bufsiz;
- else
- {
- current_drive->sbp_read_frames=current_drive->CDsize_frm-block;
- /* avoid reading past end of data */
- if (current_drive->sbp_read_frames < 1)
- {
- msg(DBG_INF,"requested frame %d, CD size %d ???\n",
- block, current_drive->CDsize_frm);
- current_drive->sbp_read_frames=1;
- }
- }
-
- flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
- clr_cmdbuf();
- if (famV_drive)
- {
- drvcmd[0]=CMDV_READ;
- lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
- bin2bcdx(&drvcmd[1]);
- bin2bcdx(&drvcmd[2]);
- bin2bcdx(&drvcmd[3]);
- drvcmd[4]=current_drive->sbp_read_frames>>8;
- drvcmd[5]=current_drive->sbp_read_frames&0xff;
- drvcmd[6]=0x02; /* flag "msf-bcd" */
- }
- else if (fam0L_drive)
- {
- flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
- if (current_drive->xa_byte==0x20)
- {
- cmd_type=READ_M2;
- drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
- drvcmd[1]=(block>>16)&0x0ff;
- drvcmd[2]=(block>>8)&0x0ff;
- drvcmd[3]=block&0x0ff;
- drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
- drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
- }
- else
- {
- drvcmd[0]=CMD0_READ; /* "read frames", old drives */
- if (current_drive->drv_type>=drv_201)
- {
- lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
- bin2bcdx(&drvcmd[1]);
- bin2bcdx(&drvcmd[2]);
- bin2bcdx(&drvcmd[3]);
- }
- else
- {
- drvcmd[1]=(block>>16)&0x0ff;
- drvcmd[2]=(block>>8)&0x0ff;
- drvcmd[3]=block&0x0ff;
- }
- drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
- drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
- drvcmd[6]=(current_drive->drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
- }
- }
- else if (fam1_drive)
- {
- drvcmd[0]=CMD1_READ;
- lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[5]=(current_drive->sbp_read_frames>>8)&0x0ff;
- drvcmd[6]=current_drive->sbp_read_frames&0x0ff;
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_READ;
- lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
- drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
- drvcmd[6]=0x02;
- }
- else if (famT_drive)
- {
- drvcmd[0]=CMDT_READ;
- drvcmd[2]=(block>>24)&0x0ff;
- drvcmd[3]=(block>>16)&0x0ff;
- drvcmd[4]=(block>>8)&0x0ff;
- drvcmd[5]=block&0x0ff;
- drvcmd[7]=(current_drive->sbp_read_frames>>8)&0x0ff;
- drvcmd[8]=current_drive->sbp_read_frames&0x0ff;
- }
- flags_cmd_out=f_putcmd;
- response_count=0;
- i=cmd_out();
- if (i<0) msg(DBG_INF,"error giving READ command: %0d\n", i);
- return;
-}
-/*==========================================================================*/
-/*
- * Check the completion of the read-data command. On success, read
- * the current_drive->sbp_bufsiz * 2048 bytes of data from the disk into buffer.
- */
-static int sbp_data(struct request *req)
-{
- int i=0, j=0, l, frame;
- u_int try=0;
- u_long timeout;
- u_char *p;
- u_int data_tries = 0;
- u_int data_waits = 0;
- u_int data_retrying = 0;
- int error_flag;
- int xa_count;
- int max_latency;
- int success;
- int wait;
- int duration;
-
- error_flag=0;
- success=0;
-#if LONG_TIMING
- max_latency=9*HZ;
-#else
- if (current_drive->f_multisession) max_latency=15*HZ;
- else max_latency=5*HZ;
-#endif
- duration=jiffies;
- for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
- {
- SBPCD_CLI;
-
- del_timer(&data_timer);
- data_timer.expires=jiffies+max_latency;
- timed_out_data=0;
- add_timer(&data_timer);
- while (!timed_out_data)
- {
- if (current_drive->f_multisession) try=maxtim_data*4;
- else try=maxtim_data;
- msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try);
- for ( ; try!=0;try--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) break;
- if (!(j&s_not_result_ready)) break;
- if (fam0LV_drive) if (j&s_attention) break;
- }
- if (!(j&s_not_data_ready)) goto data_ready;
- if (try==0)
- {
- if (data_retrying == 0) data_waits++;
- data_retrying = 1;
- msg(DBG_000,"sbp_data: CDi_status loop: sleeping.\n");
- sbp_sleep(1);
- try = 1;
- }
- }
- msg(DBG_INF,"sbp_data: CDi_status loop expired.\n");
- data_ready:
- del_timer(&data_timer);
-
- if (timed_out_data)
- {
- msg(DBG_INF,"sbp_data: CDi_status timeout (timed_out_data) (%02X).\n", j);
- error_flag++;
- }
- if (try==0)
- {
- msg(DBG_INF,"sbp_data: CDi_status timeout (try=0) (%02X).\n", j);
- error_flag++;
- }
- if (!(j&s_not_result_ready))
- {
- msg(DBG_INF, "sbp_data: RESULT_READY where DATA_READY awaited (%02X).\n", j);
- response_count=20;
- j=ResponseInfo();
- j=inb(CDi_status);
- }
- if (j&s_not_data_ready)
- {
- if ((current_drive->ored_ctl_adr&0x40)==0)
- msg(DBG_INF, "CD contains no data tracks.\n");
- else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j);
- error_flag++;
- }
- SBPCD_STI;
- if (error_flag) break;
-
- msg(DBG_000, "sbp_data: beginning to read.\n");
- p = current_drive->sbp_buf + frame * CD_FRAMESIZE;
- if (sbpro_type==1) OUT(CDo_sel_i_d,1);
- if (cmd_type==READ_M2) {
- if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
- else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
- }
- if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
- else insb(CDi_data, p, CD_FRAMESIZE);
- if (cmd_type==READ_M2) {
- if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
- else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
- }
- current_drive->sbp_current++;
- if (sbpro_type==1) OUT(CDo_sel_i_d,0);
- if (cmd_type==READ_M2)
- {
- for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
- sprintf(&msgbuf[xa_count*3], " %02X", xa_head_buf[xa_count]);
- msgbuf[xa_count*3]=0;
- msg(DBG_XA1,"xa head:%s\n", msgbuf);
- }
- data_retrying = 0;
- data_tries++;
- if (data_tries >= 1000)
- {
- msg(DBG_INF,"sbp_data() statistics: %d waits in %d frames.\n", data_waits, data_tries);
- data_waits = data_tries = 0;
- }
- }
- duration=jiffies-duration;
- msg(DBG_TEA,"time to read %d frames: %d jiffies .\n",frame,duration);
- if (famT_drive)
- {
- wait=8;
- do
- {
- if (teac==2)
- {
- if ((i=CDi_stat_loop_T()) == -1) break;
- }
- else
- {
- sbp_sleep(1);
- OUT(CDo_sel_i_d,0);
- i=inb(CDi_status);
- }
- if (!(i&s_not_data_ready))
- {
- OUT(CDo_sel_i_d,1);
- j=0;
- do
- {
- if (do_16bit) i=inw(CDi_data);
- else i=inb(CDi_data);
- j++;
- i=inb(CDi_status);
- }
- while (!(i&s_not_data_ready));
- msg(DBG_TEA, "==========too much data (%d bytes/words)==============.\n", j);
- }
- if (!(i&s_not_result_ready))
- {
- OUT(CDo_sel_i_d,0);
- l=0;
- do
- {
- infobuf[l++]=inb(CDi_info);
- i=inb(CDi_status);
- }
- while (!(i&s_not_result_ready));
- if (infobuf[0]==0x00) success=1;
-#if 1
- for (j=0;j<l;j++) sprintf(&msgbuf[j*3], " %02X", infobuf[j]);
- msgbuf[j*3]=0;
- msg(DBG_TEA,"sbp_data info response:%s\n", msgbuf);
-#endif
- if (infobuf[0]==0x02)
- {
- error_flag++;
- do
- {
- ++recursion;
- if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (sbp_data): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",recursion);
- else msg(DBG_TEA,"sbp_data: CMDT_READ_ERR necessary.\n");
- clr_cmdbuf();
- drvcmd[0]=CMDT_READ_ERR;
- j=cmd_out_T(); /* !!! recursive here !!! */
- --recursion;
- sbp_sleep(1);
- }
- while (j<0);
- current_drive->error_state=infobuf[2];
- current_drive->b3=infobuf[3];
- current_drive->b4=infobuf[4];
- }
- break;
- }
- else
- {
-#if 0
- msg(DBG_TEA, "============= waiting for result=================.\n");
- sbp_sleep(1);
-#endif
- }
- }
- while (wait--);
- }
-
- if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
- {
- msg(DBG_TEA, "================error flag: %d=================.\n", error_flag);
- msg(DBG_INF,"sbp_data: read aborted by drive.\n");
-#if 1
- i=cc_DriveReset(); /* ugly fix to prevent a hang */
-#else
- i=cc_ReadError();
-#endif
- return (0);
- }
-
- if (fam0LV_drive)
- {
- SBPCD_CLI;
- i=maxtim_data;
- for (timeout=jiffies+HZ; time_before(jiffies, timeout); timeout--)
- {
- for ( ;i!=0;i--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) break;
- if (!(j&s_not_result_ready)) break;
- if (j&s_attention) break;
- }
- if (i != 0 || time_after_eq(jiffies, timeout)) break;
- sbp_sleep(0);
- i = 1;
- }
- if (i==0) msg(DBG_INF,"status timeout after READ.\n");
- if (!(j&s_attention))
- {
- msg(DBG_INF,"sbp_data: timeout waiting DRV_ATTN - retrying.\n");
- i=cc_DriveReset(); /* ugly fix to prevent a hang */
- SBPCD_STI;
- return (0);
- }
- SBPCD_STI;
- }
-
-#if 0
- if (!success)
-#endif
- do
- {
- if (fam0LV_drive) cc_ReadStatus();
-#if 1
- if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i);
-#endif
- i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
-#if 1
- if (famT_drive) msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i);
-#endif
- if (i<0)
- {
- msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", current_drive->status_bits);
- return (0);
- }
- }
- while ((fam0LV_drive)&&(!st_check)&&(!(i&p_success)));
- if (st_check)
- {
- i=cc_ReadError();
- msg(DBG_INF,"cc_ReadError was necessary after read: %d\n",i);
- return (0);
- }
- if (fatal_err)
- {
- fatal_err=0;
- current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
- current_drive->sbp_current = 0;
- msg(DBG_INF,"sbp_data: fatal_err - retrying.\n");
- return (0);
- }
-
- current_drive->sbp_first_frame = req -> sector / 4;
- current_drive->sbp_last_frame = current_drive->sbp_first_frame + current_drive->sbp_read_frames - 1;
- sbp_transfer(req);
- return (1);
-}
-/*==========================================================================*/
-
-static int sbpcd_block_open(struct inode *inode, struct file *file)
-{
- struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_open(p->sbpcd_infop, inode, file);
-}
-
-static int sbpcd_block_release(struct inode *inode, struct file *file)
-{
- struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_release(p->sbpcd_infop, file);
-}
-
-static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
- unsigned cmd, unsigned long arg)
-{
- struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
- struct cdrom_device_info *cdi = p->sbpcd_infop;
- int ret, i;
-
- ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
- if (ret != -ENOSYS)
- return ret;
-
- msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
- if (p->drv_id==-1) {
- msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
- return (-ENXIO); /* no such drive */
- }
- down(&ioctl_read_sem);
- if (p != current_drive)
- switch_drive(p);
-
- msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
- switch (cmd) /* Sun-compatible */
- {
- case DDIOCSDBG: /* DDI Debug */
- if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
- i=sbpcd_dbg_ioctl(arg,1);
- RETURN_UP(i);
- case CDROMRESET: /* hard reset the drive */
- msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
- i=DriveReset();
- current_drive->audio_state=0;
- RETURN_UP(i);
-
- case CDROMREADMODE1:
- msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- cc_ModeSelect(CD_FRAMESIZE);
- cc_ModeSense();
- current_drive->mode=READ_M1;
- RETURN_UP(0);
-
- case CDROMREADMODE2: /* not usable at the moment */
- msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- cc_ModeSelect(CD_FRAMESIZE_RAW1);
- cc_ModeSense();
- current_drive->mode=READ_M2;
- RETURN_UP(0);
-
- case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
- msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
- if (current_drive->sbp_audsiz>0)
- vfree(current_drive->aud_buf);
- current_drive->aud_buf=NULL;
- current_drive->sbp_audsiz=arg;
-
- if (current_drive->sbp_audsiz>16)
- {
- current_drive->sbp_audsiz = 0;
- RETURN_UP(current_drive->sbp_audsiz);
- }
-
- if (current_drive->sbp_audsiz>0)
- {
- current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
- if (current_drive->aud_buf==NULL)
- {
- msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
- current_drive->sbp_audsiz=0;
- }
- else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
- }
- RETURN_UP(current_drive->sbp_audsiz);
-
- case CDROMREADAUDIO:
- { /* start of CDROMREADAUDIO */
- int i=0, j=0, frame, block=0;
- u_int try=0;
- u_long timeout;
- u_char *p;
- u_int data_tries = 0;
- u_int data_waits = 0;
- u_int data_retrying = 0;
- int status_tries;
- int error_flag;
-
- msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
- if (fam0_drive) RETURN_UP(-EINVAL);
- if (famL_drive) RETURN_UP(-EINVAL);
- if (famV_drive) RETURN_UP(-EINVAL);
- if (famT_drive) RETURN_UP(-EINVAL);
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
- if (copy_from_user(&read_audio, (void __user *)arg,
- sizeof(struct cdrom_read_audio)))
- RETURN_UP(-EFAULT);
- if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
- if (!access_ok(VERIFY_WRITE, read_audio.buf,
- read_audio.nframes*CD_FRAMESIZE_RAW))
- RETURN_UP(-EFAULT);
-
- if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
- block=msf2lba(&read_audio.addr.msf.minute);
- else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
- block=read_audio.addr.lba;
- else RETURN_UP(-EINVAL);
-#if 000
- i=cc_SetSpeed(speed_150,0,0);
- if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
-#endif
- msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
- block, blk2msf(block));
- msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
-#if OLD_BUSY
- while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
- busy_audio=1;
-#endif /* OLD_BUSY */
- error_flag=0;
- for (data_tries=5; data_tries>0; data_tries--)
- {
- msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
- current_drive->mode=READ_AU;
- cc_ModeSelect(CD_FRAMESIZE_RAW);
- cc_ModeSense();
- for (status_tries=3; status_tries > 0; status_tries--)
- {
- flags_cmd_out |= f_respo3;
- cc_ReadStatus();
- if (sbp_status() != 0) break;
- if (st_check) cc_ReadError();
- sbp_sleep(1); /* wait a bit, try again */
- }
- if (status_tries == 0)
- {
- msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
- continue;
- }
- msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
-
- flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
- if (fam0L_drive)
- {
- flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
- cmd_type=READ_M2;
- drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
- drvcmd[1]=(block>>16)&0x000000ff;
- drvcmd[2]=(block>>8)&0x000000ff;
- drvcmd[3]=block&0x000000ff;
- drvcmd[4]=0;
- drvcmd[5]=read_audio.nframes; /* # of frames */
- drvcmd[6]=0;
- }
- else if (fam1_drive)
- {
- drvcmd[0]=CMD1_READ; /* "read frames", new drives */
- lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[4]=0;
- drvcmd[5]=0;
- drvcmd[6]=read_audio.nframes; /* # of frames */
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_READ_XA2;
- lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[4]=0;
- drvcmd[5]=read_audio.nframes; /* # of frames */
- drvcmd[6]=0x11; /* raw mode */
- }
- else if (famT_drive) /* CD-55A: not tested yet */
- {
- }
- msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
- flags_cmd_out=f_putcmd;
- response_count=0;
- i=cmd_out();
- if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
- sbp_sleep(0);
- msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
- for (frame=1;frame<2 && !error_flag; frame++)
- {
- try=maxtim_data;
- for (timeout=jiffies+9*HZ; ; )
- {
- for ( ; try!=0;try--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) break;
- if (!(j&s_not_result_ready)) break;
- if (fam0L_drive) if (j&s_attention) break;
- }
- if (try != 0 || time_after_eq(jiffies, timeout)) break;
- if (data_retrying == 0) data_waits++;
- data_retrying = 1;
- sbp_sleep(1);
- try = 1;
- }
- if (try==0)
- {
- msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
- error_flag++;
- break;
- }
- msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
- if (j&s_not_data_ready)
- {
- msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
- error_flag++;
- break;
- }
- msg(DBG_AUD,"read_audio: before reading data.\n");
- error_flag=0;
- p = current_drive->aud_buf;
- if (sbpro_type==1) OUT(CDo_sel_i_d,1);
- if (do_16bit)
- {
- u_short *p2 = (u_short *) p;
-
- for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
- {
- if ((inb_p(CDi_status)&s_not_data_ready)) continue;
-
- /* get one sample */
- *p2++ = inw_p(CDi_data);
- *p2++ = inw_p(CDi_data);
- }
- } else {
- for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
- {
- if ((inb_p(CDi_status)&s_not_data_ready)) continue;
-
- /* get one sample */
- *p++ = inb_p(CDi_data);
- *p++ = inb_p(CDi_data);
- *p++ = inb_p(CDi_data);
- *p++ = inb_p(CDi_data);
- }
- }
- if (sbpro_type==1) OUT(CDo_sel_i_d,0);
- data_retrying = 0;
- }
- msg(DBG_AUD,"read_audio: after reading data.\n");
- if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
- {
- msg(DBG_AUD,"read_audio: read aborted by drive\n");
-#if 0000
- i=cc_DriveReset(); /* ugly fix to prevent a hang */
-#else
- i=cc_ReadError();
-#endif
- continue;
- }
- if (fam0L_drive)
- {
- i=maxtim_data;
- for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
- {
- for ( ;i!=0;i--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) break;
- if (!(j&s_not_result_ready)) break;
- if (j&s_attention) break;
- }
- if (i != 0 || time_after_eq(jiffies, timeout)) break;
- sbp_sleep(0);
- i = 1;
- }
- if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
- if (!(j&s_attention))
- {
- msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
- i=cc_DriveReset(); /* ugly fix to prevent a hang */
- continue;
- }
- }
- do
- {
- if (fam0L_drive) cc_ReadStatus();
- i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
- if (i<0) { msg(DBG_AUD,
- "read_audio: cc_ReadStatus error after read: %02X\n",
- current_drive->status_bits);
- continue; /* FIXME */
- }
- }
- while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
- if (st_check)
- {
- i=cc_ReadError();
- msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
- continue;
- }
- if (copy_to_user(read_audio.buf,
- current_drive->aud_buf,
- read_audio.nframes * CD_FRAMESIZE_RAW))
- RETURN_UP(-EFAULT);
- msg(DBG_AUD,"read_audio: copy_to_user done.\n");
- break;
- }
- cc_ModeSelect(CD_FRAMESIZE);
- cc_ModeSense();
- current_drive->mode=READ_M1;
-#if OLD_BUSY
- busy_audio=0;
-#endif /* OLD_BUSY */
- if (data_tries == 0)
- {
- msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
- RETURN_UP(-EIO);
- }
- msg(DBG_AUD,"read_audio: successful return.\n");
- RETURN_UP(0);
- } /* end of CDROMREADAUDIO */
-
- default:
- msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
- RETURN_UP(-EINVAL);
- } /* end switch(cmd) */
-}
-
-static int sbpcd_block_media_changed(struct gendisk *disk)
-{
- struct sbpcd_drive *p = disk->private_data;
- return cdrom_media_changed(p->sbpcd_infop);
-}
-
-static struct block_device_operations sbpcd_bdops =
-{
- .owner = THIS_MODULE,
- .open = sbpcd_block_open,
- .release = sbpcd_block_release,
- .ioctl = sbpcd_block_ioctl,
- .media_changed = sbpcd_block_media_changed,
-};
-/*==========================================================================*/
-/*
- * Open the device special file. Check that a disk is in. Read TOC.
- */
-static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
-{
- struct sbpcd_drive *p = cdi->handle;
-
- down(&ioctl_read_sem);
- switch_drive(p);
-
- /*
- * try to keep an "open" counter here and lock the door if 0->1.
- */
- msg(DBG_LCK,"open_count: %d -> %d\n",
- current_drive->open_count,current_drive->open_count+1);
- if (++current_drive->open_count<=1)
- {
- int i;
- i=LockDoor();
- current_drive->open_count=1;
- if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n");
- i=DiskInfo();
- if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n");
- if ((current_drive->ored_ctl_adr&0x40)==0)
- {
- msg(DBG_INF,"CD contains no data tracks.\n");
-#ifdef SAFE_MIXED
- current_drive->has_data=0;
-#endif /* SAFE_MIXED */
- }
-#ifdef SAFE_MIXED
- else if (current_drive->has_data<1) current_drive->has_data=1;
-#endif /* SAFE_MIXED */
- }
- if (!st_spinning) cc_SpinUp();
- RETURN_UP(0);
-}
-/*==========================================================================*/
-/*
- * On close, we flush all sbp blocks from the buffer cache.
- */
-static void sbpcd_release(struct cdrom_device_info * cdi)
-{
- struct sbpcd_drive *p = cdi->handle;
-
- if (p->drv_id==-1) {
- msg(DBG_INF, "release: bad device: %s\n", cdi->name);
- return;
- }
- down(&ioctl_read_sem);
- switch_drive(p);
- /*
- * try to keep an "open" counter here and unlock the door if 1->0.
- */
- msg(DBG_LCK,"open_count: %d -> %d\n",
- p->open_count,p->open_count-1);
- if (p->open_count>-2) /* CDROMEJECT may have been done */
- {
- if (--p->open_count<=0)
- {
- p->sbp_first_frame=p->sbp_last_frame=-1;
- if (p->audio_state!=audio_playing)
- if (p->f_eject) cc_SpinDown();
- p->diskstate_flags &= ~cd_size_bit;
- p->open_count=0;
-#ifdef SAFE_MIXED
- p->has_data=0;
-#endif /* SAFE_MIXED */
- }
- }
- up(&ioctl_read_sem);
- return ;
-}
-/*==========================================================================*/
-/*
- *
- */
-static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr);
-static struct cdrom_device_ops sbpcd_dops = {
- .open = sbpcd_open,
- .release = sbpcd_release,
- .drive_status = sbpcd_drive_status,
- .media_changed = sbpcd_media_changed,
- .tray_move = sbpcd_tray_move,
- .lock_door = sbpcd_lock_door,
- .select_speed = sbpcd_select_speed,
- .get_last_session = sbpcd_get_last_session,
- .get_mcn = sbpcd_get_mcn,
- .reset = sbpcd_reset,
- .audio_ioctl = sbpcd_audio_ioctl,
- .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
- CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
- CDC_MCN | CDC_PLAY_AUDIO,
- .n_minors = 1,
-};
-
-/*==========================================================================*/
-/*
- * accept "kernel command line" parameters
- * (suggested by Peter MacDonald with SLS 1.03)
- *
- * This is only implemented for the first controller. Should be enough to
- * allow installing with a "strange" distribution kernel.
- *
- * use: tell LILO:
- * sbpcd=0x230,SoundBlaster
- * or
- * sbpcd=0x300,LaserMate
- * or
- * sbpcd=0x338,SoundScape
- * or
- * sbpcd=0x2C0,Teac16bit
- *
- * (upper/lower case sensitive here - but all-lowercase is ok!!!).
- *
- * the address value has to be the CDROM PORT ADDRESS -
- * not the soundcard base address.
- * For the SPEA/SoundScape setup, DO NOT specify the "configuration port"
- * address, but the address which is really used for the CDROM (usually 8
- * bytes above).
- *
- */
-
-int sbpcd_setup(char *s)
-{
-#ifndef MODULE
- int p[4];
- (void)get_options(s, ARRAY_SIZE(p), p);
- setup_done++;
- msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s);
- sbpro_type=0; /* default: "LaserMate" */
- if (p[0]>1) sbpro_type=p[2];
- else if (!strcmp(s,str_sb)) sbpro_type=1;
- else if (!strcmp(s,str_sb_l)) sbpro_type=1;
- else if (!strcmp(s,str_sp)) sbpro_type=2;
- else if (!strcmp(s,str_sp_l)) sbpro_type=2;
- else if (!strcmp(s,str_ss)) sbpro_type=2;
- else if (!strcmp(s,str_ss_l)) sbpro_type=2;
- else if (!strcmp(s,str_t16)) sbpro_type=3;
- else if (!strcmp(s,str_t16_l)) sbpro_type=3;
- if (p[0]>0) sbpcd_ioaddr=p[1];
- if (p[0]>2) max_drives=p[3];
-#else
- sbpcd_ioaddr = sbpcd[0];
- sbpro_type = sbpcd[1];
-#endif
-
- CDo_command=sbpcd_ioaddr;
- CDi_info=sbpcd_ioaddr;
- CDi_status=sbpcd_ioaddr+1;
- CDo_sel_i_d=sbpcd_ioaddr+1;
- CDo_reset=sbpcd_ioaddr+2;
- CDo_enable=sbpcd_ioaddr+3;
- f_16bit=0;
- if ((sbpro_type==1)||(sbpro_type==3))
- {
- CDi_data=sbpcd_ioaddr;
- if (sbpro_type==3)
- {
- f_16bit=1;
- sbpro_type=1;
- }
- }
- else CDi_data=sbpcd_ioaddr+2;
-
- return 1;
-}
-
-__setup("sbpcd=", sbpcd_setup);
-
-
-/*==========================================================================*/
-/*
- * Sequoia S-1000 CD-ROM Interface Configuration
- * as used within SPEA Media FX, Ensonic SoundScape and some Reveal cards
- * The soundcard has to get jumpered for the interface type "Panasonic"
- * (not Sony or Mitsumi) and to get soft-configured for
- * -> configuration port address
- * -> CDROM port offset (num_ports): has to be 8 here. Possibly this
- * offset value determines the interface type (none, Panasonic,
- * Mitsumi, Sony).
- * The interface uses a configuration port (0x320, 0x330, 0x340, 0x350)
- * some bytes below the real CDROM address.
- *
- * For the Panasonic style (LaserMate) interface and the configuration
- * port 0x330, we have to use an offset of 8; so, the real CDROM port
- * address is 0x338.
- */
-static int __init config_spea(void)
-{
- /*
- * base address offset between configuration port and CDROM port,
- * this probably defines the interface type
- * 2 (type=??): 0x00
- * 8 (type=LaserMate):0x10
- * 16 (type=??):0x20
- * 32 (type=??):0x30
- */
- int n_ports=0x10;
-
- int irq_number=0; /* off:0x00, 2/9:0x01, 7:0x03, 12:0x05, 15:0x07 */
- int dma_channel=0; /* off: 0x00, 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68 */
- int dack_polarity=0; /* L:0x00, H:0x80 */
- int drq_polarity=0x40; /* L:0x00, H:0x40 */
- int i;
-
-#define SPEA_REG_1 sbpcd_ioaddr-0x08+4
-#define SPEA_REG_2 sbpcd_ioaddr-0x08+5
-
- OUT(SPEA_REG_1,0xFF);
- i=inb(SPEA_REG_1);
- if (i!=0x0F)
- {
- msg(DBG_SEQ,"no SPEA interface at %04X present.\n", sbpcd_ioaddr);
- return (-1); /* no interface found */
- }
- OUT(SPEA_REG_1,0x04);
- OUT(SPEA_REG_2,0xC0);
-
- OUT(SPEA_REG_1,0x05);
- OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
-
-#if 1
-#define SPEA_PATTERN 0x80
-#else
-#define SPEA_PATTERN 0x00
-#endif
- OUT(SPEA_REG_1,0x06);
- OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
- OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
-
- OUT(SPEA_REG_1,0x09);
- i=(inb(SPEA_REG_2)&0xCF)|n_ports;
- OUT(SPEA_REG_2,i);
-
- sbpro_type = 0; /* acts like a LaserMate interface now */
- msg(DBG_SEQ,"found SoundScape interface at %04X.\n", sbpcd_ioaddr);
- return (0);
-}
-
-/*==========================================================================*/
-/*
- * Test for presence of drive and initialize it.
- * Called once at boot or load time.
- */
-
-/* FIXME: cleanups after failed allocations are too ugly for words */
-#ifdef MODULE
-int __init __sbpcd_init(void)
-#else
-int __init sbpcd_init(void)
-#endif
-{
- int i=0, j=0;
- int addr[2]={1, CDROM_PORT};
- int port_index;
-
- sti();
-
- msg(DBG_INF,"sbpcd.c %s\n", VERSION);
-#ifndef MODULE
-#if DISTRIBUTION
- if (!setup_done)
- {
- msg(DBG_INF,"Looking for Matsushita/Panasonic, CreativeLabs, Longshine, TEAC CD-ROM drives\n");
- msg(DBG_INF,"= = = = = = = = = = W A R N I N G = = = = = = = = = =\n");
- msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an NE2000 card).\n");
- msg(DBG_INF,"If that happens, you have to reboot and use the\n");
- msg(DBG_INF,"LILO (kernel) command line feature like:\n");
- msg(DBG_INF," LILO boot: ... sbpcd=0x230,SoundBlaster\n");
- msg(DBG_INF,"or like:\n");
- msg(DBG_INF," LILO boot: ... sbpcd=0x300,LaserMate\n");
- msg(DBG_INF,"or like:\n");
- msg(DBG_INF," LILO boot: ... sbpcd=0x338,SoundScape\n");
- msg(DBG_INF,"with your REAL address.\n");
- msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n");
- }
-#endif /* DISTRIBUTION */
- sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
- sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */
-#endif /* MODULE */
-
- for (port_index=0;port_index<NUM_PROBE;port_index+=2)
- {
- addr[1]=sbpcd[port_index];
- if (addr[1]==0) break;
- if (check_region(addr[1],4))
- {
- msg(DBG_INF,"check_region: %03X is not free.\n",addr[1]);
- continue;
- }
- if (sbpcd[port_index+1]==2) type=str_sp;
- else if (sbpcd[port_index+1]==1) type=str_sb;
- else if (sbpcd[port_index+1]==3) type=str_t16;
- else type=str_lm;
- sbpcd_setup((char *)type);
-#if DISTRIBUTION
- msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type);
-#endif /* DISTRIBUTION */
- if (sbpcd[port_index+1]==2)
- {
- i=config_spea();
- if (i<0) continue;
- }
-#ifdef PATH_CHECK
- if (check_card(addr[1])) continue;
-#endif /* PATH_CHECK */
- i=check_drives();
- msg(DBG_INI,"check_drives done.\n");
- if (i>=0) break; /* drive found */
- } /* end of cycling through the set of possible I/O port addresses */
-
- if (ndrives==0)
- {
- msg(DBG_INF, "No drive found.\n");
-#ifdef MODULE
- return -EIO;
-#else
- goto init_done;
-#endif /* MODULE */
- }
-
- if (port_index>0)
- {
- msg(DBG_INF, "You should read Documentation/cdrom/sbpcd\n");
- msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n");
- }
- check_datarate();
- msg(DBG_INI,"check_datarate done.\n");
-
- for (j=0;j<NR_SBPCD;j++)
- {
- struct sbpcd_drive *p = D_S + j;
- if (p->drv_id==-1)
- continue;
- switch_drive(p);
-#if 1
- if (!famL_drive) cc_DriveReset();
-#endif
- if (!st_spinning) cc_SpinUp();
- p->sbp_first_frame = -1; /* First frame in buffer */
- p->sbp_last_frame = -1; /* Last frame in buffer */
- p->sbp_read_frames = 0; /* Number of frames being read to buffer */
- p->sbp_current = 0; /* Frame being currently read */
- p->CD_changed=1;
- p->frame_size=CD_FRAMESIZE;
- p->f_eject=0;
-#if EJECT
- if (!fam0_drive) p->f_eject=1;
-#endif /* EJECT */
- cc_ReadStatus();
- i=ResponseStatus(); /* returns orig. status or p_busy_new */
- if (famT_drive) i=ResponseStatus(); /* returns orig. status or p_busy_new */
- if (i<0)
- {
- if (i!=-402)
- msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
- }
- else
- {
- if (st_check)
- {
- i=cc_ReadError();
- msg(DBG_INI,"init: cc_ReadError returns %d\n",i);
- }
- }
- msg(DBG_INI,"init: first GetStatus: %d\n",i);
- msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n",
- p->error_byte);
- if (p->error_byte==aud_12)
- {
- timeout=jiffies+2*HZ;
- do
- {
- i=GetStatus();
- msg(DBG_INI,"init: second GetStatus: %02X\n",i);
- msg(DBG_LCS,
- "init: second GetStatus: error_byte=%d\n",
- p->error_byte);
- if (i<0) break;
- if (!st_caddy_in) break;
- }
- while ((!st_diskok)||time_after(jiffies, timeout));
- }
- i=SetSpeed();
- if (i>=0) p->CD_changed=1;
- }
-
- if (!request_region(CDo_command,4,major_name))
- {
- printk(KERN_WARNING "sbpcd: Unable to request region 0x%x\n", CDo_command);
- return -EIO;
- }
-
- /*
- * Turn on the CD audio channels.
- * The addresses are obtained from SOUND_BASE (see sbpcd.h).
- */
-#if SOUND_BASE
- OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
- OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
-#endif /* SOUND_BASE */
-
- if (register_blkdev(MAJOR_NR, major_name)) {
-#ifdef MODULE
- return -EIO;
-#else
- goto init_done;
-#endif /* MODULE */
- }
-
- /*
- * init error handling is broken beyond belief in this driver...
- */
- sbpcd_queue = blk_init_queue(do_sbpcd_request, &sbpcd_lock);
- if (!sbpcd_queue) {
- release_region(CDo_command,4);
- unregister_blkdev(MAJOR_NR, major_name);
- return -ENOMEM;
- }
-
- for (j=0;j<NR_SBPCD;j++)
- {
- struct cdrom_device_info * sbpcd_infop;
- struct gendisk *disk;
- struct sbpcd_drive *p = D_S + j;
-
- if (p->drv_id==-1) continue;
- switch_drive(p);
-#ifdef SAFE_MIXED
- p->has_data=0;
-#endif /* SAFE_MIXED */
- /*
- * allocate memory for the frame buffers
- */
- p->aud_buf=NULL;
- p->sbp_audsiz=0;
- p->sbp_bufsiz=buffers;
- if (p->drv_type&drv_fam1)
- if (READ_AUDIO>0)
- p->sbp_audsiz = READ_AUDIO;
- p->sbp_buf=(u_char *) vmalloc(buffers*CD_FRAMESIZE);
- if (!p->sbp_buf) {
- msg(DBG_INF,"data buffer (%d frames) not available.\n",
- buffers);
- if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
- {
- printk("Can't unregister %s\n", major_name);
- }
- release_region(CDo_command,4);
- blk_cleanup_queue(sbpcd_queue);
- return -EIO;
- }
-#ifdef MODULE
- msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
-#endif /* MODULE */
- if (p->sbp_audsiz>0)
- {
- p->aud_buf=(u_char *) vmalloc(p->sbp_audsiz*CD_FRAMESIZE_RAW);
- if (p->aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",p->sbp_audsiz);
- else msg(DBG_INF,"audio buffer size: %d frames.\n",p->sbp_audsiz);
- }
- sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info));
- if (sbpcd_infop == NULL)
- {
- release_region(CDo_command,4);
- blk_cleanup_queue(sbpcd_queue);
- return -ENOMEM;
- }
- memset(sbpcd_infop, 0, sizeof(struct cdrom_device_info));
- sbpcd_infop->ops = &sbpcd_dops;
- sbpcd_infop->speed = 2;
- sbpcd_infop->capacity = 1;
- sprintf(sbpcd_infop->name, "sbpcd%d", j);
- sbpcd_infop->handle = p;
- p->sbpcd_infop = sbpcd_infop;
- disk = alloc_disk(1);
- disk->major = MAJOR_NR;
- disk->first_minor = j;
- disk->fops = &sbpcd_bdops;
- strcpy(disk->disk_name, sbpcd_infop->name);
- disk->flags = GENHD_FL_CD;
- p->disk = disk;
- if (register_cdrom(sbpcd_infop))
- {
- printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n");
- }
- disk->private_data = p;
- disk->queue = sbpcd_queue;
- add_disk(disk);
- }
- blk_queue_hardsect_size(sbpcd_queue, CD_FRAMESIZE);
-
-#ifndef MODULE
- init_done:
-#endif
- return 0;
-}
-/*==========================================================================*/
-#ifdef MODULE
-static void sbpcd_exit(void)
-{
- int j;
-
- if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
- {
- msg(DBG_INF, "What's that: can't unregister %s.\n", major_name);
- return;
- }
- release_region(CDo_command,4);
- blk_cleanup_queue(sbpcd_queue);
- for (j=0;j<NR_SBPCD;j++)
- {
- if (D_S[j].drv_id==-1) continue;
- del_gendisk(D_S[j].disk);
- put_disk(D_S[j].disk);
- vfree(D_S[j].sbp_buf);
- if (D_S[j].sbp_audsiz>0)
- vfree(D_S[j].aud_buf);
- if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
- {
- msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
- return;
- }
- vfree(D_S[j].sbpcd_infop);
- }
- msg(DBG_INF, "%s module released.\n", major_name);
-}
-
-
-module_init(__sbpcd_init) /*HACK!*/;
-module_exit(sbpcd_exit);
-
-
-#endif /* MODULE */
-static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
- struct sbpcd_drive *p = cdi->handle;
- msg(DBG_CHK,"media_check (%s) called\n", cdi->name);
-
- if (p->CD_changed==0xFF)
- {
- p->CD_changed=0;
- msg(DBG_CHK,"medium changed (drive %s)\n", cdi->name);
- current_drive->diskstate_flags &= ~toc_bit;
- /* we *don't* need invalidate here, it's done by caller */
- current_drive->diskstate_flags &= ~cd_size_bit;
-#ifdef SAFE_MIXED
- current_drive->has_data=0;
-#endif /* SAFE_MIXED */
-
- return (1);
- }
- else
- return (0);
-}
-
-MODULE_LICENSE("GPL");
-/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but
- AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */
-MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR);
-
-/*==========================================================================*/
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
-
diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h
deleted file mode 100644
index 2f2225f13c6f..000000000000
--- a/drivers/cdrom/sbpcd.h
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * sbpcd.h Specify interface address and interface type here.
- */
-
-/*
- * Attention! This file contains user-serviceable parts!
- * I recommend to make use of it...
- * If you feel helpless, look into Documentation/cdrom/sbpcd
- * (good idea anyway, at least before mailing me).
- *
- * The definitions for the first controller can get overridden by
- * the kernel command line ("lilo boot option").
- * Examples:
- * sbpcd=0x300,LaserMate
- * or
- * sbpcd=0x230,SoundBlaster
- * or
- * sbpcd=0x338,SoundScape
- * or
- * sbpcd=0x2C0,Teac16bit
- *
- * If sbpcd gets used as a module, you can load it with
- * insmod sbpcd.o sbpcd=0x300,0
- * or
- * insmod sbpcd.o sbpcd=0x230,1
- * or
- * insmod sbpcd.o sbpcd=0x338,2
- * or
- * insmod sbpcd.o sbpcd=0x2C0,3
- * respective to override the configured address and type.
- */
-
-/*
- * define your CDROM port base address as CDROM_PORT
- * and specify the type of your interface card as SBPRO.
- *
- * address:
- * ========
- * SBPRO type addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
- * LASERMATE type (CI-101P, WDH-7001C) addresses typically are 0x0300, ...
- * SOUNDSCAPE addresses are from the LASERMATE type and range. You have to
- * specify the REAL address here, not the configuration port address. Look
- * at the CDROM driver's invoking line within your DOS CONFIG.SYS, or let
- * sbpcd auto-probe, if you are not firm with the address.
- * There are some soundcards on the market with 0x0630, 0x0650, ...; their
- * type is not obvious (both types are possible).
- *
- * example: if your SBPRO audio address is 0x220, specify 0x230 and SBPRO 1.
- * if your soundcard has its CDROM port above 0x300, specify
- * that address and try SBPRO 0 first.
- * if your SoundScape configuration port is at 0x330, specify
- * 0x338 and SBPRO 2.
- *
- * interface type:
- * ===============
- * set SBPRO to 1 for "true" SoundBlaster card
- * set SBPRO to 0 for "compatible" soundcards and
- * for "poor" (no sound) interface cards.
- * set SBPRO to 2 for Ensonic SoundScape or SPEA Media FX cards
- * set SBPRO to 3 for Teac 16bit interface cards
- *
- * Almost all "compatible" sound boards need to set SBPRO to 0.
- * If SBPRO is set wrong, the drives will get found - but any
- * data access will give errors (audio access will work).
- * The "OmniCD" no-sound interface card from CreativeLabs and most Teac
- * interface cards need SBPRO 1.
- *
- * sound base:
- * ===========
- * The SOUND_BASE definition tells if we should try to turn the CD sound
- * channels on. It will only be of use regarding soundcards with a SbPro
- * compatible mixer.
- *
- * Example: #define SOUND_BASE 0x220 enables the sound card's CD channels
- * #define SOUND_BASE 0 leaves the soundcard untouched
- */
-#define CDROM_PORT 0x340 /* <-----------<< port address */
-#define SBPRO 0 /* <-----------<< interface type */
-#define MAX_DRIVES 4 /* set to 1 if the card does not use "drive select" */
-#define SOUND_BASE 0x220 /* <-----------<< sound address of this card or 0 */
-
-/*
- * some more or less user dependent definitions - service them!
- */
-
-/* Set this to 0 once you have configured your interface definitions right. */
-#define DISTRIBUTION 1
-
-/*
- * Time to wait after giving a message.
- * This gets important if you enable non-standard DBG_xxx flags.
- * You will see what happens if you omit the pause or make it
- * too short. Be warned!
- */
-#define KLOGD_PAUSE 1
-
-/* tray control: eject tray if no disk is in */
-#if DISTRIBUTION
-#define JUKEBOX 0
-#else
-#define JUKEBOX 1
-#endif /* DISTRIBUTION */
-
-/* tray control: eject tray after last use */
-#if DISTRIBUTION
-#define EJECT 0
-#else
-#define EJECT 1
-#endif /* DISTRIBUTION */
-
-/* max. number of audio frames to read with one */
-/* request (allocates n* 2352 bytes kernel memory!) */
-/* may be freely adjusted, f.e. 75 (= 1 sec.), at */
-/* runtime by use of the CDROMAUDIOBUFSIZ ioctl. */
-#define READ_AUDIO 0
-
-/* Optimizations for the Teac CD-55A drive read performance.
- * SBP_TEAC_SPEED can be changed here, or one can set the
- * variable "teac" when loading as a module.
- * Valid settings are:
- * 0 - very slow - the recommended "DISTRIBUTION 1" setup.
- * 1 - 2x performance with little overhead. No busy waiting.
- * 2 - 4x performance with 5ms overhead per read. Busy wait.
- *
- * Setting SBP_TEAC_SPEED or the variable 'teac' to anything
- * other than 0 may cause problems. If you run into them, first
- * change SBP_TEAC_SPEED back to 0 and see if your drive responds
- * normally. If yes, you are "allowed" to report your case - to help
- * me with the driver, not to solve your hassle. Don´t mail if you
- * simply are stuck into your own "tuning" experiments, you know?
- */
-#define SBP_TEAC_SPEED 1
-
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * nothing to change below here if you are not fully aware what you're doing
- */
-#ifndef _LINUX_SBPCD_H
-
-#define _LINUX_SBPCD_H
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * driver's own read_ahead, data mode
- */
-#define SBP_BUFFER_FRAMES 8
-
-#define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */
-#undef FUTURE
-#undef SAFE_MIXED
-
-#define TEST_UPC 0
-#define SPEA_TEST 0
-#define TEST_STI 0
-#define OLD_BUSY 0
-#undef PATH_CHECK
-#ifndef SOUND_BASE
-#define SOUND_BASE 0
-#endif
-#if DISTRIBUTION
-#undef SBP_TEAC_SPEED
-#define SBP_TEAC_SPEED 0
-#endif
-/*==========================================================================*/
-/*
- * DDI interface definitions
- * "invented" by Fred N. van Kempen..
- */
-#define DDIOCSDBG 0x9000
-
-/*==========================================================================*/
-/*
- * "private" IOCTL functions
- */
-#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
-
-/*==========================================================================*/
-/*
- * Debug output levels
- */
-#define DBG_INF 1 /* necessary information */
-#define DBG_BSZ 2 /* BLOCK_SIZE trace */
-#define DBG_REA 3 /* READ status trace */
-#define DBG_CHK 4 /* MEDIA CHECK trace */
-#define DBG_TIM 5 /* datarate timer test */
-#define DBG_INI 6 /* initialization trace */
-#define DBG_TOC 7 /* tell TocEntry values */
-#define DBG_IOC 8 /* ioctl trace */
-#define DBG_STA 9 /* ResponseStatus() trace */
-#define DBG_ERR 10 /* cc_ReadError() trace */
-#define DBG_CMD 11 /* cmd_out() trace */
-#define DBG_WRN 12 /* give explanation before auto-probing */
-#define DBG_MUL 13 /* multi session code test */
-#define DBG_IDX 14 /* test code for drive_id !=0 */
-#define DBG_IOX 15 /* some special information */
-#define DBG_DID 16 /* drive ID test */
-#define DBG_RES 17 /* drive reset info */
-#define DBG_SPI 18 /* SpinUp test */
-#define DBG_IOS 19 /* ioctl trace: subchannel functions */
-#define DBG_IO2 20 /* ioctl trace: general */
-#define DBG_UPC 21 /* show UPC information */
-#define DBG_XA1 22 /* XA mode debugging */
-#define DBG_LCK 23 /* door (un)lock info */
-#define DBG_SQ1 24 /* dump SubQ frame */
-#define DBG_AUD 25 /* READ AUDIO debugging */
-#define DBG_SEQ 26 /* Sequoia interface configuration trace */
-#define DBG_LCS 27 /* Longshine LCS-7260 debugging trace */
-#define DBG_CD2 28 /* MKE/Funai CD200 debugging trace */
-#define DBG_TEA 29 /* TEAC CD-55A debugging trace */
-#define DBG_ECS 30 /* ECS-AT (Vertos 100) debugging trace */
-#define DBG_000 31 /* unnecessary information */
-
-/*==========================================================================*/
-/*==========================================================================*/
-
-/*
- * bits of flags_cmd_out:
- */
-#define f_respo3 0x100
-#define f_putcmd 0x80
-#define f_respo2 0x40
-#define f_lopsta 0x20
-#define f_getsta 0x10
-#define f_ResponseStatus 0x08
-#define f_obey_p_check 0x04
-#define f_bit1 0x02
-#define f_wait_if_busy 0x01
-
-/*
- * diskstate_flags:
- */
-#define x80_bit 0x80
-#define upc_bit 0x40
-#define volume_bit 0x20
-#define toc_bit 0x10
-#define multisession_bit 0x08
-#define cd_size_bit 0x04
-#define subq_bit 0x02
-#define frame_size_bit 0x01
-
-/*
- * disk states (bits of diskstate_flags):
- */
-#define upc_valid (current_drive->diskstate_flags&upc_bit)
-#define volume_valid (current_drive->diskstate_flags&volume_bit)
-#define toc_valid (current_drive->diskstate_flags&toc_bit)
-#define cd_size_valid (current_drive->diskstate_flags&cd_size_bit)
-#define subq_valid (current_drive->diskstate_flags&subq_bit)
-#define frame_size_valid (current_drive->diskstate_flags&frame_size_bit)
-
-/*
- * the status_bits variable
- */
-#define p_success 0x100
-#define p_door_closed 0x80
-#define p_caddy_in 0x40
-#define p_spinning 0x20
-#define p_check 0x10
-#define p_busy_new 0x08
-#define p_door_locked 0x04
-#define p_disk_ok 0x01
-
-/*
- * LCS-7260 special status result bits:
- */
-#define p_lcs_door_locked 0x02
-#define p_lcs_door_closed 0x01 /* probably disk_in */
-
-/*
- * CR-52x special status result bits:
- */
-#define p_caddin_old 0x40
-#define p_success_old 0x08
-#define p_busy_old 0x04
-#define p_bit_1 0x02 /* hopefully unused now */
-
-/*
- * "generation specific" defs of the status result bits:
- */
-#define p0_door_closed 0x80
-#define p0_caddy_in 0x40
-#define p0_spinning 0x20
-#define p0_check 0x10
-#define p0_success 0x08 /* unused */
-#define p0_busy 0x04
-#define p0_bit_1 0x02 /* unused */
-#define p0_disk_ok 0x01
-
-#define pL_disk_in 0x40
-#define pL_spinning 0x20
-#define pL_check 0x10
-#define pL_success 0x08 /* unused ?? */
-#define pL_busy 0x04
-#define pL_door_locked 0x02
-#define pL_door_closed 0x01
-
-#define pV_door_closed 0x40
-#define pV_spinning 0x20
-#define pV_check 0x10
-#define pV_success 0x08
-#define pV_busy 0x04
-#define pV_door_locked 0x02
-#define pV_disk_ok 0x01
-
-#define p1_door_closed 0x80
-#define p1_disk_in 0x40
-#define p1_spinning 0x20
-#define p1_check 0x10
-#define p1_busy 0x08
-#define p1_door_locked 0x04
-#define p1_bit_1 0x02 /* unused */
-#define p1_disk_ok 0x01
-
-#define p2_disk_ok 0x80
-#define p2_door_locked 0x40
-#define p2_spinning 0x20
-#define p2_busy2 0x10
-#define p2_busy1 0x08
-#define p2_door_closed 0x04
-#define p2_disk_in 0x02
-#define p2_check 0x01
-
-/*
- * used drive states:
- */
-#define st_door_closed (current_drive->status_bits&p_door_closed)
-#define st_caddy_in (current_drive->status_bits&p_caddy_in)
-#define st_spinning (current_drive->status_bits&p_spinning)
-#define st_check (current_drive->status_bits&p_check)
-#define st_busy (current_drive->status_bits&p_busy_new)
-#define st_door_locked (current_drive->status_bits&p_door_locked)
-#define st_diskok (current_drive->status_bits&p_disk_ok)
-
-/*
- * bits of the CDi_status register:
- */
-#define s_not_result_ready 0x04 /* 0: "result ready" */
-#define s_not_data_ready 0x02 /* 0: "data ready" */
-#define s_attention 0x01 /* 1: "attention required" */
-/*
- * usable as:
- */
-#define DRV_ATTN ((inb(CDi_status)&s_attention)!=0)
-#define DATA_READY ((inb(CDi_status)&s_not_data_ready)==0)
-#define RESULT_READY ((inb(CDi_status)&s_not_result_ready)==0)
-
-/*
- * drive families and types (firmware versions):
- */
-#define drv_fam0 0x0100 /* CR-52x family */
-#define drv_199 (drv_fam0+0x01) /* <200 */
-#define drv_200 (drv_fam0+0x02) /* <201 */
-#define drv_201 (drv_fam0+0x03) /* <210 */
-#define drv_210 (drv_fam0+0x04) /* <211 */
-#define drv_211 (drv_fam0+0x05) /* <300 */
-#define drv_300 (drv_fam0+0x06) /* >=300 */
-
-#define drv_fam1 0x0200 /* CR-56x family */
-#define drv_099 (drv_fam1+0x01) /* <100 */
-#define drv_100 (drv_fam1+0x02) /* >=100, only 1.02 and 5.00 known */
-
-#define drv_fam2 0x0400 /* CD200 family */
-
-#define drv_famT 0x0800 /* TEAC CD-55A */
-
-#define drv_famL 0x1000 /* Longshine family */
-#define drv_260 (drv_famL+0x01) /* LCS-7260 */
-#define drv_e1 (drv_famL+0x01) /* LCS-7260, firmware "A E1" */
-#define drv_f4 (drv_famL+0x02) /* LCS-7260, firmware "A4F4" */
-
-#define drv_famV 0x2000 /* ECS-AT (vertos-100) family */
-#define drv_at (drv_famV+0x01) /* ECS-AT, firmware "1.00" */
-
-#define fam0_drive (current_drive->drv_type&drv_fam0)
-#define famL_drive (current_drive->drv_type&drv_famL)
-#define famV_drive (current_drive->drv_type&drv_famV)
-#define fam1_drive (current_drive->drv_type&drv_fam1)
-#define fam2_drive (current_drive->drv_type&drv_fam2)
-#define famT_drive (current_drive->drv_type&drv_famT)
-#define fam0L_drive (current_drive->drv_type&(drv_fam0|drv_famL))
-#define fam0V_drive (current_drive->drv_type&(drv_fam0|drv_famV))
-#define famLV_drive (current_drive->drv_type&(drv_famL|drv_famV))
-#define fam0LV_drive (current_drive->drv_type&(drv_fam0|drv_famL|drv_famV))
-#define fam1L_drive (current_drive->drv_type&(drv_fam1|drv_famL))
-#define fam1V_drive (current_drive->drv_type&(drv_fam1|drv_famV))
-#define fam1LV_drive (current_drive->drv_type&(drv_fam1|drv_famL|drv_famV))
-#define fam01_drive (current_drive->drv_type&(drv_fam0|drv_fam1))
-#define fam12_drive (current_drive->drv_type&(drv_fam1|drv_fam2))
-#define fam2T_drive (current_drive->drv_type&(drv_fam2|drv_famT))
-
-/*
- * audio states:
- */
-#define audio_completed 3 /* Forgot this one! --AJK */
-#define audio_playing 2
-#define audio_pausing 1
-
-/*
- * drv_pattern, drv_options:
- */
-#define speed_auto 0x80
-#define speed_300 0x40
-#define speed_150 0x20
-#define audio_mono 0x04
-
-/*
- * values of cmd_type (0 else):
- */
-#define READ_M1 0x01 /* "data mode 1": 2048 bytes per frame */
-#define READ_M2 0x02 /* "data mode 2": 12+2048+280 bytes per frame */
-#define READ_SC 0x04 /* "subchannel info": 96 bytes per frame */
-#define READ_AU 0x08 /* "audio frame": 2352 bytes per frame */
-
-/*
- * sense_byte:
- *
- * values: 00
- * 01
- * 81
- * 82 "raw audio" mode
- * xx from infobuf[0] after 85 00 00 00 00 00 00
- */
-
-/* audio status (bin) */
-#define aud_00 0x00 /* Audio status byte not supported or not valid */
-#define audx11 0x0b /* Audio play operation in progress */
-#define audx12 0x0c /* Audio play operation paused */
-#define audx13 0x0d /* Audio play operation successfully completed */
-#define audx14 0x0e /* Audio play operation stopped due to error */
-#define audx15 0x0f /* No current audio status to return */
-/* audio status (bcd) */
-#define aud_11 0x11 /* Audio play operation in progress */
-#define aud_12 0x12 /* Audio play operation paused */
-#define aud_13 0x13 /* Audio play operation successfully completed */
-#define aud_14 0x14 /* Audio play operation stopped due to error */
-#define aud_15 0x15 /* No current audio status to return */
-
-/*
- * highest allowed drive number (MINOR+1)
- */
-#define NR_SBPCD 4
-
-/*
- * we try to never disable interrupts - seems to work
- */
-#define SBPCD_DIS_IRQ 0
-
-/*
- * "write byte to port"
- */
-#define OUT(x,y) outb(y,x)
-
-/*==========================================================================*/
-
-#define MIXER_addr SOUND_BASE+4 /* sound card's address register */
-#define MIXER_data SOUND_BASE+5 /* sound card's data register */
-#define MIXER_CD_Volume 0x28 /* internal SB Pro register address */
-
-/*==========================================================================*/
-
-#define MAX_TRACKS 99
-
-#define ERR_DISKCHANGE 615
-
-/*==========================================================================*/
-/*
- * To make conversions easier (machine dependent!)
- */
-typedef union _msf
-{
- u_int n;
- u_char c[4];
-} MSF;
-
-typedef union _blk
-{
- u_int n;
- u_char c[4];
-} BLK;
-
-/*==========================================================================*/
-
-/*============================================================================
-==============================================================================
-
-COMMAND SET of "old" drives like CR-521, CR-522
- (the CR-562 family is different):
-
-No. Command Code
---------------------------------------------
-
-Drive Commands:
- 1 Seek 01
- 2 Read Data 02
- 3 Read XA-Data 03
- 4 Read Header 04
- 5 Spin Up 05
- 6 Spin Down 06
- 7 Diagnostic 07
- 8 Read UPC 08
- 9 Read ISRC 09
-10 Play Audio 0A
-11 Play Audio MSF 0B
-12 Play Audio Track/Index 0C
-
-Status Commands:
-13 Read Status 81
-14 Read Error 82
-15 Read Drive Version 83
-16 Mode Select 84
-17 Mode Sense 85
-18 Set XA Parameter 86
-19 Read XA Parameter 87
-20 Read Capacity 88
-21 Read SUB_Q 89
-22 Read Disc Code 8A
-23 Read Disc Information 8B
-24 Read TOC 8C
-25 Pause/Resume 8D
-26 Read Packet 8E
-27 Read Path Check 00
-
-
-all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first
-
-mnemo 7-byte command #bytes response (r0...rn)
-________ ____________________ ____
-
-Read Status:
-status: 81. (1) one-byte command, gives the main
- status byte
-Read Error:
-check1: 82 00 00 00 00 00 00. (6) r1: audio status
-
-Read Packet:
-check2: 8e xx 00 00 00 00 00. (xx) gets xx bytes response, relating
- to commands 01 04 05 07 08 09
-
-Play Audio:
-play: 0a ll-bb-aa nn-nn-nn. (0) play audio, ll-bb-aa: starting block (lba),
- nn-nn-nn: #blocks
-Play Audio MSF:
- 0b mm-ss-ff mm-ss-ff (0) play audio from/to
-
-Play Audio Track/Index:
- 0c ...
-
-Pause/Resume:
-pause: 8d pr 00 00 00 00 00. (0) pause (pr=00)
- resume (pr=80) audio playing
-
-Mode Select:
- 84 00 nn-nn ??.?? 00 (0) nn-nn: 2048 or 2340
- possibly defines transfer size
-
-set_vol: 84 83 00 00 sw le 00. (0) sw(itch): lrxxxxxx (off=1)
- le(vel): min=0, max=FF, else half
- (firmware 2.11)
-
-Mode Sense:
-get_vol: 85 03 00 00 00 00 00. (2) tell current audio volume setting
-
-Read Disc Information:
-tocdesc: 8b 00 00 00 00 00 00. (6) read the toc descriptor ("msf-bin"-format)
-
-Read TOC:
-tocent: 8c fl nn 00 00 00 00. (8) read toc entry #nn
- (fl=0:"lba"-, =2:"msf-bin"-format)
-
-Read Capacity:
-capacit: 88 00 00 00 00 00 00. (5) "read CD-ROM capacity"
-
-
-Read Path Check:
-ping: 00 00 00 00 00 00 00. (2) r0=AA, r1=55
- ("ping" if the drive is connected)
-
-Read Drive Version:
-ident: 83 00 00 00 00 00 00. (12) gives "MATSHITAn.nn"
- (n.nn = 2.01, 2.11., 3.00, ...)
-
-Seek:
-seek: 01 00 ll-bb-aa 00 00. (0)
-seek: 01 02 mm-ss-ff 00 00. (0)
-
-Read Data:
-read: 02 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2048 bytes,
- starting at block xx-xx-xx
- fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
-
-Read XA-Data:
-read: 03 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2340 bytes,
- starting at block xx-xx-xx
- fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
-
-Read SUB_Q:
- 89 fl 00 00 00 00 00. (13) r0: audio status, r4-r7: lba/msf,
- fl=0: "lba", fl=2: "msf"
-
-Read Disc Code:
- 8a 00 00 00 00 00 00. (14) possibly extended "check condition"-info
-
-Read Header:
- 04 00 ll-bb-aa 00 00. (0) 4 bytes response with "check2"
- 04 02 mm-ss-ff 00 00. (0) 4 bytes response with "check2"
-
-Spin Up:
- 05 00 ll-bb-aa 00 00. (0) possibly implies a "seek"
-
-Spin Down:
- 06 ...
-
-Diagnostic:
- 07 00 ll-bb-aa 00 00. (2) 2 bytes response with "check2"
- 07 02 mm-ss-ff 00 00. (2) 2 bytes response with "check2"
-
-Read UPC:
- 08 00 ll-bb-aa 00 00. (16)
- 08 02 mm-ss-ff 00 00. (16)
-
-Read ISRC:
- 09 00 ll-bb-aa 00 00. (15) 15 bytes response with "check2"
- 09 02 mm-ss-ff 00 00. (15) 15 bytes response with "check2"
-
-Set XA Parameter:
- 86 ...
-
-Read XA Parameter:
- 87 ...
-
-==============================================================================
-============================================================================*/
-
-/*
- * commands
- *
- * CR-52x: CMD0_
- * CR-56x: CMD1_
- * CD200: CMD2_
- * LCS-7260: CMDL_
- * TEAC CD-55A: CMDT_
- * ECS-AT: CMDV_
- */
-#define CMD1_RESET 0x0a
-#define CMD2_RESET 0x01
-#define CMDT_RESET 0xc0
-
-#define CMD1_LOCK_CTL 0x0c
-#define CMD2_LOCK_CTL 0x1e
-#define CMDT_LOCK_CTL CMD2_LOCK_CTL
-#define CMDL_LOCK_CTL 0x0e
-#define CMDV_LOCK_CTL CMDL_LOCK_CTL
-
-#define CMD1_TRAY_CTL 0x07
-#define CMD2_TRAY_CTL 0x1b
-#define CMDT_TRAY_CTL CMD2_TRAY_CTL
-#define CMDL_TRAY_CTL 0x0d
-#define CMDV_TRAY_CTL CMDL_TRAY_CTL
-
-#define CMD1_MULTISESS 0x8d
-#define CMDL_MULTISESS 0x8c
-#define CMDV_MULTISESS CMDL_MULTISESS
-
-#define CMD1_SUBCHANINF 0x11
-#define CMD2_SUBCHANINF 0x??
-
-#define CMD1_ABORT 0x08
-#define CMD2_ABORT 0x08
-#define CMDT_ABORT 0x08
-
-#define CMD2_x02 0x02
-
-#define CMD2_SETSPEED 0xda
-
-#define CMD0_PATH_CHECK 0x00
-#define CMD1_PATH_CHECK 0x???
-#define CMD2_PATH_CHECK 0x???
-#define CMDT_PATH_CHECK 0x???
-#define CMDL_PATH_CHECK CMD0_PATH_CHECK
-#define CMDV_PATH_CHECK CMD0_PATH_CHECK
-
-#define CMD0_SEEK 0x01
-#define CMD1_SEEK CMD0_SEEK
-#define CMD2_SEEK 0x2b
-#define CMDT_SEEK CMD2_SEEK
-#define CMDL_SEEK CMD0_SEEK
-#define CMDV_SEEK CMD0_SEEK
-
-#define CMD0_READ 0x02
-#define CMD1_READ 0x10
-#define CMD2_READ 0x28
-#define CMDT_READ CMD2_READ
-#define CMDL_READ CMD0_READ
-#define CMDV_READ CMD0_READ
-
-#define CMD0_READ_XA 0x03
-#define CMD2_READ_XA 0xd4
-#define CMD2_READ_XA2 0xd5
-#define CMDL_READ_XA CMD0_READ_XA /* really ?? */
-#define CMDV_READ_XA CMD0_READ_XA
-
-#define CMD0_READ_HEAD 0x04
-
-#define CMD0_SPINUP 0x05
-#define CMD1_SPINUP 0x02
-#define CMD2_SPINUP CMD2_TRAY_CTL
-#define CMDL_SPINUP CMD0_SPINUP
-#define CMDV_SPINUP CMD0_SPINUP
-
-#define CMD0_SPINDOWN 0x06 /* really??? */
-#define CMD1_SPINDOWN 0x06
-#define CMD2_SPINDOWN CMD2_TRAY_CTL
-#define CMDL_SPINDOWN 0x0d
-#define CMDV_SPINDOWN CMD0_SPINDOWN
-
-#define CMD0_DIAG 0x07
-
-#define CMD0_READ_UPC 0x08
-#define CMD1_READ_UPC 0x88
-#define CMD2_READ_UPC 0x???
-#define CMDL_READ_UPC CMD0_READ_UPC
-#define CMDV_READ_UPC 0x8f
-
-#define CMD0_READ_ISRC 0x09
-
-#define CMD0_PLAY 0x0a
-#define CMD1_PLAY 0x???
-#define CMD2_PLAY 0x???
-#define CMDL_PLAY CMD0_PLAY
-#define CMDV_PLAY CMD0_PLAY
-
-#define CMD0_PLAY_MSF 0x0b
-#define CMD1_PLAY_MSF 0x0e
-#define CMD2_PLAY_MSF 0x47
-#define CMDT_PLAY_MSF CMD2_PLAY_MSF
-#define CMDL_PLAY_MSF 0x???
-
-#define CMD0_PLAY_TI 0x0c
-#define CMD1_PLAY_TI 0x0f
-
-#define CMD0_STATUS 0x81
-#define CMD1_STATUS 0x05
-#define CMD2_STATUS 0x00
-#define CMDT_STATUS CMD2_STATUS
-#define CMDL_STATUS CMD0_STATUS
-#define CMDV_STATUS CMD0_STATUS
-#define CMD2_SEEK_LEADIN 0x00
-
-#define CMD0_READ_ERR 0x82
-#define CMD1_READ_ERR CMD0_READ_ERR
-#define CMD2_READ_ERR 0x03
-#define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */
-#define CMDL_READ_ERR CMD0_READ_ERR
-#define CMDV_READ_ERR CMD0_READ_ERR
-
-#define CMD0_READ_VER 0x83
-#define CMD1_READ_VER CMD0_READ_VER
-#define CMD2_READ_VER 0x12
-#define CMDT_READ_VER CMD2_READ_VER /* really ?? */
-#define CMDL_READ_VER CMD0_READ_VER
-#define CMDV_READ_VER CMD0_READ_VER
-
-#define CMD0_SETMODE 0x84
-#define CMD1_SETMODE 0x09
-#define CMD2_SETMODE 0x55
-#define CMDT_SETMODE CMD2_SETMODE
-#define CMDL_SETMODE CMD0_SETMODE
-
-#define CMD0_GETMODE 0x85
-#define CMD1_GETMODE 0x84
-#define CMD2_GETMODE 0x5a
-#define CMDT_GETMODE CMD2_GETMODE
-#define CMDL_GETMODE CMD0_GETMODE
-
-#define CMD0_SET_XA 0x86
-
-#define CMD0_GET_XA 0x87
-
-#define CMD0_CAPACITY 0x88
-#define CMD1_CAPACITY 0x85
-#define CMD2_CAPACITY 0x25
-#define CMDL_CAPACITY CMD0_CAPACITY /* missing in some firmware versions */
-
-#define CMD0_READSUBQ 0x89
-#define CMD1_READSUBQ 0x87
-#define CMD2_READSUBQ 0x42
-#define CMDT_READSUBQ CMD2_READSUBQ
-#define CMDL_READSUBQ CMD0_READSUBQ
-#define CMDV_READSUBQ CMD0_READSUBQ
-
-#define CMD0_DISKCODE 0x8a
-
-#define CMD0_DISKINFO 0x8b
-#define CMD1_DISKINFO CMD0_DISKINFO
-#define CMD2_DISKINFO 0x43
-#define CMDT_DISKINFO CMD2_DISKINFO
-#define CMDL_DISKINFO CMD0_DISKINFO
-#define CMDV_DISKINFO CMD0_DISKINFO
-
-#define CMD0_READTOC 0x8c
-#define CMD1_READTOC CMD0_READTOC
-#define CMD2_READTOC 0x???
-#define CMDL_READTOC CMD0_READTOC
-#define CMDV_READTOC CMD0_READTOC
-
-#define CMD0_PAU_RES 0x8d
-#define CMD1_PAU_RES 0x0d
-#define CMD2_PAU_RES 0x4b
-#define CMDT_PAUSE CMD2_PAU_RES
-#define CMDL_PAU_RES CMD0_PAU_RES
-#define CMDV_PAUSE CMD0_PAU_RES
-
-#define CMD0_PACKET 0x8e
-#define CMD1_PACKET CMD0_PACKET
-#define CMD2_PACKET 0x???
-#define CMDL_PACKET CMD0_PACKET
-#define CMDV_PACKET 0x???
-
-/*==========================================================================*/
-/*==========================================================================*/
-#endif /* _LINUX_SBPCD_H */
-/*==========================================================================*/
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
deleted file mode 100644
index 5409fca5bbfc..000000000000
--- a/drivers/cdrom/sjcd.c
+++ /dev/null
@@ -1,1815 +0,0 @@
-/* -- sjcd.c
- *
- * Sanyo CD-ROM device driver implementation, Version 1.6
- * Copyright (C) 1995 Vadim V. Model
- *
- * model@cecmow.enet.dec.com
- * vadim@rbrf.ru
- * vadim@ipsun.ras.ru
- *
- *
- * This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de);
- * it was developed under use of mcd.c from Martin Harriss, with help of
- * Eric van der Maarel (H.T.M.v.d.Maarel@marin.nl).
- *
- * It is planned to include these routines into sbpcd.c later - to make
- * a "mixed use" on one cable possible for all kinds of drives which use
- * the SoundBlaster/Panasonic style CDROM interface. But today, the
- * ability to install directly from CDROM is more important than flexibility.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * History:
- * 1.1 First public release with kernel version 1.3.7.
- * Written by Vadim Model.
- * 1.2 Added detection and configuration of cdrom interface
- * on ISP16 soundcard.
- * Allow for command line options: sjcd=<io_base>,<irq>,<dma>
- * 1.3 Some minor changes to README.sjcd.
- * 1.4 MSS Sound support!! Listen to a CD through the speakers.
- * 1.5 Module support and bugfixes.
- * Tray locking.
- * 1.6 Removed ISP16 code from this driver.
- * Allow only to set io base address on command line: sjcd=<io_base>
- * Changes to Documentation/cdrom/sjcd
- * Added cleanup after any error in the initialisation.
- * 1.7 Added code to set the sector size tables to prevent the bug present in
- * the previous version of this driver. Coded added by Anthony Barbachan
- * from bugfix tip originally suggested by Alan Cox.
- *
- * November 1999 -- Make kernel-parameter implementation work with 2.3.x
- * Removed init_module & cleanup_module in favor of
- * module_init & module_exit.
- * Torben Mathiasen <tmm@image.dk>
- */
-
-#define SJCD_VERSION_MAJOR 1
-#define SJCD_VERSION_MINOR 7
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/major.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/blkdev.h>
-#include "sjcd.h"
-
-static int sjcd_present = 0;
-static struct request_queue *sjcd_queue;
-
-#define MAJOR_NR SANYO_CDROM_MAJOR
-#define QUEUE (sjcd_queue)
-#define CURRENT elv_next_request(sjcd_queue)
-
-#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
-
-/*
- * buffer for block size conversion
- */
-static char sjcd_buf[2048 * SJCD_BUF_SIZ];
-static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
-static volatile int sjcd_buf_in, sjcd_buf_out = -1;
-
-/*
- * Status.
- */
-static unsigned short sjcd_status_valid = 0;
-static unsigned short sjcd_door_closed;
-static unsigned short sjcd_door_was_open;
-static unsigned short sjcd_media_is_available;
-static unsigned short sjcd_media_is_changed;
-static unsigned short sjcd_toc_uptodate = 0;
-static unsigned short sjcd_command_failed;
-static volatile unsigned char sjcd_completion_status = 0;
-static volatile unsigned char sjcd_completion_error = 0;
-static unsigned short sjcd_command_is_in_progress = 0;
-static unsigned short sjcd_error_reported = 0;
-static DEFINE_SPINLOCK(sjcd_lock);
-
-static int sjcd_open_count;
-
-static int sjcd_audio_status;
-static struct sjcd_play_msf sjcd_playing;
-
-static int sjcd_base = SJCD_BASE_ADDR;
-
-module_param(sjcd_base, int, 0);
-
-static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
-
-/*
- * Data transfer.
- */
-static volatile unsigned short sjcd_transfer_is_active = 0;
-
-enum sjcd_transfer_state {
- SJCD_S_IDLE = 0,
- SJCD_S_START = 1,
- SJCD_S_MODE = 2,
- SJCD_S_READ = 3,
- SJCD_S_DATA = 4,
- SJCD_S_STOP = 5,
- SJCD_S_STOPPING = 6
-};
-static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
-static long sjcd_transfer_timeout = 0;
-static int sjcd_read_count = 0;
-static unsigned char sjcd_mode = 0;
-
-#define SJCD_READ_TIMEOUT 5000
-
-#if defined( SJCD_GATHER_STAT )
-/*
- * Statistic.
- */
-static struct sjcd_stat statistic;
-#endif
-
-/*
- * Timer.
- */
-static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0);
-
-#define SJCD_SET_TIMER( func, tmout ) \
- ( sjcd_delay_timer.expires = jiffies+tmout, \
- sjcd_delay_timer.function = ( void * )func, \
- add_timer( &sjcd_delay_timer ) )
-
-#define CLEAR_TIMER del_timer( &sjcd_delay_timer )
-
-/*
- * Set up device, i.e., use command line data to set
- * base address.
- */
-#ifndef MODULE
-static int __init sjcd_setup(char *str)
-{
- int ints[2];
- (void) get_options(str, ARRAY_SIZE(ints), ints);
- if (ints[0] > 0)
- sjcd_base = ints[1];
-
- return 1;
-}
-
-__setup("sjcd=", sjcd_setup);
-
-#endif
-
-/*
- * Special converters.
- */
-static unsigned char bin2bcd(int bin)
-{
- int u, v;
-
- u = bin % 10;
- v = bin / 10;
- return (u | (v << 4));
-}
-
-static int bcd2bin(unsigned char bcd)
-{
- return ((bcd >> 4) * 10 + (bcd & 0x0F));
-}
-
-static long msf2hsg(struct msf *mp)
-{
- return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
- + bcd2bin(mp->min) * 4500 - 150);
-}
-
-static void hsg2msf(long hsg, struct msf *msf)
-{
- hsg += 150;
- msf->min = hsg / 4500;
- hsg %= 4500;
- msf->sec = hsg / 75;
- msf->frame = hsg % 75;
- msf->min = bin2bcd(msf->min); /* convert to BCD */
- msf->sec = bin2bcd(msf->sec);
- msf->frame = bin2bcd(msf->frame);
-}
-
-/*
- * Send a command to cdrom. Invalidate status.
- */
-static void sjcd_send_cmd(unsigned char cmd)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: send_cmd( 0x%x )\n", cmd);
-#endif
- outb(cmd, SJCDPORT(0));
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
-}
-
-/*
- * Send a command with one arg to cdrom. Invalidate status.
- */
-static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
-#endif
- outb(cmd, SJCDPORT(0));
- outb(a, SJCDPORT(0));
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
-}
-
-/*
- * Send a command with four args to cdrom. Invalidate status.
- */
-static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
- unsigned char b, unsigned char c,
- unsigned char d)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
-#endif
- outb(cmd, SJCDPORT(0));
- outb(a, SJCDPORT(0));
- outb(b, SJCDPORT(0));
- outb(c, SJCDPORT(0));
- outb(d, SJCDPORT(0));
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
-}
-
-/*
- * Send a play or read command to cdrom. Invalidate Status.
- */
-static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
-#endif
- outb(cmd, SJCDPORT(0));
- outb(pms->start.min, SJCDPORT(0));
- outb(pms->start.sec, SJCDPORT(0));
- outb(pms->start.frame, SJCDPORT(0));
- outb(pms->end.min, SJCDPORT(0));
- outb(pms->end.sec, SJCDPORT(0));
- outb(pms->end.frame, SJCDPORT(0));
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
-}
-
-/*
- * Get a value from the data port. Should not block, so we use a little
- * wait for a while. Returns 0 if OK.
- */
-static int sjcd_load_response(void *buf, int len)
-{
- unsigned char *resp = (unsigned char *) buf;
-
- for (; len; --len) {
- int i;
- for (i = 200;
- i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
- if (i > 0)
- *resp++ = (unsigned char) inb(SJCDPORT(0));
- else
- break;
- }
- return (len);
-}
-
-/*
- * Load and parse command completion status (drive info byte and maybe error).
- * Sorry, no error classification yet.
- */
-static void sjcd_load_status(void)
-{
- sjcd_media_is_changed = 0;
- sjcd_completion_error = 0;
- sjcd_completion_status = inb(SJCDPORT(0));
- if (sjcd_completion_status & SST_DOOR_OPENED) {
- sjcd_door_closed = sjcd_media_is_available = 0;
- } else {
- sjcd_door_closed = 1;
- if (sjcd_completion_status & SST_MEDIA_CHANGED)
- sjcd_media_is_available = sjcd_media_is_changed =
- 1;
- else if (sjcd_completion_status & 0x0F) {
- /*
- * OK, we seem to catch an error ...
- */
- while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
- sjcd_completion_error = inb(SJCDPORT(0));
- if ((sjcd_completion_status & 0x08) &&
- (sjcd_completion_error & 0x40))
- sjcd_media_is_available = 0;
- else
- sjcd_command_failed = 1;
- } else
- sjcd_media_is_available = 1;
- }
- /*
- * Ok, status loaded successfully.
- */
- sjcd_status_valid = 1, sjcd_error_reported = 0;
- sjcd_command_is_in_progress = 0;
-
- /*
- * If the disk is changed, the TOC is not valid.
- */
- if (sjcd_media_is_changed)
- sjcd_toc_uptodate = 0;
-#if defined( SJCD_TRACE )
- printk("SJCD: status %02x.%02x loaded.\n",
- (int) sjcd_completion_status, (int) sjcd_completion_error);
-#endif
-}
-
-/*
- * Read status from cdrom. Check to see if the status is available.
- */
-static int sjcd_check_status(void)
-{
- /*
- * Try to load the response from cdrom into buffer.
- */
- if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
- sjcd_load_status();
- return (1);
- } else {
- /*
- * No status is available.
- */
- return (0);
- }
-}
-
-/*
- * This is just timeout counter, and nothing more. Surprised ? :-)
- */
-static volatile long sjcd_status_timeout;
-
-/*
- * We need about 10 seconds to wait. The longest command takes about 5 seconds
- * to probe the disk (usually after tray closed or drive reset). Other values
- * should be thought of for other commands.
- */
-#define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
-
-static void sjcd_status_timer(void)
-{
- if (sjcd_check_status()) {
- /*
- * The command completed and status is loaded, stop waiting.
- */
- wake_up(&sjcd_waitq);
- } else if (--sjcd_status_timeout <= 0) {
- /*
- * We are timed out.
- */
- wake_up(&sjcd_waitq);
- } else {
- /*
- * We have still some time to wait. Try again.
- */
- SJCD_SET_TIMER(sjcd_status_timer, 1);
- }
-}
-
-/*
- * Wait for status for 10 sec approx. Returns non-positive when timed out.
- * Should not be used while reading data CDs.
- */
-static int sjcd_wait_for_status(void)
-{
- sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
- SJCD_SET_TIMER(sjcd_status_timer, 1);
- sleep_on(&sjcd_waitq);
-#if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
- if (sjcd_status_timeout <= 0)
- printk("SJCD: Error Wait For Status.\n");
-#endif
- return (sjcd_status_timeout);
-}
-
-static int sjcd_receive_status(void)
-{
- int i;
-#if defined( SJCD_TRACE )
- printk("SJCD: receive_status\n");
-#endif
- /*
- * Wait a bit for status available.
- */
- for (i = 200; i-- && (sjcd_check_status() == 0););
- if (i < 0) {
-#if defined( SJCD_TRACE )
- printk("SJCD: long wait for status\n");
-#endif
- if (sjcd_wait_for_status() <= 0)
- printk("SJCD: Timeout when read status.\n");
- else
- i = 0;
- }
- return (i);
-}
-
-/*
- * Load the status. Issue get status command and wait for status available.
- */
-static void sjcd_get_status(void)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: get_status\n");
-#endif
- sjcd_send_cmd(SCMD_GET_STATUS);
- sjcd_receive_status();
-}
-
-/*
- * Check the drive if the disk is changed. Should be revised.
- */
-static int sjcd_disk_change(struct gendisk *disk)
-{
-#if 0
- printk("SJCD: sjcd_disk_change(%s)\n", disk->disk_name);
-#endif
- if (!sjcd_command_is_in_progress)
- sjcd_get_status();
- return (sjcd_status_valid ? sjcd_media_is_changed : 0);
-}
-
-/*
- * Read the table of contents (TOC) and TOC header if necessary.
- * We assume that the drive contains no more than 99 toc entries.
- */
-static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
-static unsigned char sjcd_first_track_no, sjcd_last_track_no;
-#define sjcd_disk_length sjcd_table_of_contents[0].un.track_msf
-
-static int sjcd_update_toc(void)
-{
- struct sjcd_hw_disk_info info;
- int i;
-#if defined( SJCD_TRACE )
- printk("SJCD: update toc:\n");
-#endif
- /*
- * check to see if we need to do anything
- */
- if (sjcd_toc_uptodate)
- return (0);
-
- /*
- * Get the TOC start information.
- */
- sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
- sjcd_receive_status();
-
- if (!sjcd_status_valid) {
- printk("SJCD: cannot load status.\n");
- return (-1);
- }
-
- if (!sjcd_media_is_available) {
- printk("SJCD: no disk in drive\n");
- return (-1);
- }
-
- if (!sjcd_command_failed) {
- if (sjcd_load_response(&info, sizeof(info)) != 0) {
- printk
- ("SJCD: cannot load response about TOC start.\n");
- return (-1);
- }
- sjcd_first_track_no = bcd2bin(info.un.track_no);
- } else {
- printk("SJCD: get first failed\n");
- return (-1);
- }
-#if defined( SJCD_TRACE )
- printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
-#endif
- /*
- * Get the TOC finish information.
- */
- sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
- sjcd_receive_status();
-
- if (!sjcd_status_valid) {
- printk("SJCD: cannot load status.\n");
- return (-1);
- }
-
- if (!sjcd_media_is_available) {
- printk("SJCD: no disk in drive\n");
- return (-1);
- }
-
- if (!sjcd_command_failed) {
- if (sjcd_load_response(&info, sizeof(info)) != 0) {
- printk
- ("SJCD: cannot load response about TOC finish.\n");
- return (-1);
- }
- sjcd_last_track_no = bcd2bin(info.un.track_no);
- } else {
- printk("SJCD: get last failed\n");
- return (-1);
- }
-#if defined( SJCD_TRACE )
- printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
-#endif
- for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
- /*
- * Get the first track information.
- */
- sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
- sjcd_receive_status();
-
- if (!sjcd_status_valid) {
- printk("SJCD: cannot load status.\n");
- return (-1);
- }
-
- if (!sjcd_media_is_available) {
- printk("SJCD: no disk in drive\n");
- return (-1);
- }
-
- if (!sjcd_command_failed) {
- if (sjcd_load_response(&sjcd_table_of_contents[i],
- sizeof(struct
- sjcd_hw_disk_info))
- != 0) {
- printk
- ("SJCD: cannot load info for %d track\n",
- i);
- return (-1);
- }
- } else {
- printk("SJCD: get info %d failed\n", i);
- return (-1);
- }
- }
-
- /*
- * Get the disk length info.
- */
- sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
- sjcd_receive_status();
-
- if (!sjcd_status_valid) {
- printk("SJCD: cannot load status.\n");
- return (-1);
- }
-
- if (!sjcd_media_is_available) {
- printk("SJCD: no disk in drive\n");
- return (-1);
- }
-
- if (!sjcd_command_failed) {
- if (sjcd_load_response(&info, sizeof(info)) != 0) {
- printk
- ("SJCD: cannot load response about disk size.\n");
- return (-1);
- }
- sjcd_disk_length.min = info.un.track_msf.min;
- sjcd_disk_length.sec = info.un.track_msf.sec;
- sjcd_disk_length.frame = info.un.track_msf.frame;
- } else {
- printk("SJCD: get size failed\n");
- return (1);
- }
-#if defined( SJCD_TRACE )
- printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
- sjcd_disk_length.sec, sjcd_disk_length.frame);
-#endif
- return (0);
-}
-
-/*
- * Load subchannel information.
- */
-static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
-{
- int s;
-#if defined( SJCD_TRACE )
- printk("SJCD: load sub q\n");
-#endif
- sjcd_send_cmd(SCMD_GET_QINFO);
- s = sjcd_receive_status();
- if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
- sjcd_send_cmd(0xF2);
- s = sjcd_receive_status();
- if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
- return (-1);
- sjcd_send_cmd(SCMD_GET_QINFO);
- s = sjcd_receive_status();
- if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
- return (-1);
- }
- if (sjcd_media_is_available)
- if (sjcd_load_response(qp, sizeof(*qp)) == 0)
- return (0);
- return (-1);
-}
-
-/*
- * Start playing from the specified position.
- */
-static int sjcd_play(struct sjcd_play_msf *mp)
-{
- struct sjcd_play_msf msf;
-
- /*
- * Turn the device to play mode.
- */
- sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
- if (sjcd_receive_status() < 0)
- return (-1);
-
- /*
- * Seek to the starting point.
- */
- msf.start = mp->start;
- msf.end.min = msf.end.sec = msf.end.frame = 0x00;
- sjcd_send_6_cmd(SCMD_SEEK, &msf);
- if (sjcd_receive_status() < 0)
- return (-1);
-
- /*
- * Start playing.
- */
- sjcd_send_6_cmd(SCMD_PLAY, mp);
- return (sjcd_receive_status());
-}
-
-/*
- * Tray control functions.
- */
-static int sjcd_tray_close(void)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: tray_close\n");
-#endif
- sjcd_send_cmd(SCMD_CLOSE_TRAY);
- return (sjcd_receive_status());
-}
-
-static int sjcd_tray_lock(void)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: tray_lock\n");
-#endif
- sjcd_send_cmd(SCMD_LOCK_TRAY);
- return (sjcd_receive_status());
-}
-
-static int sjcd_tray_unlock(void)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: tray_unlock\n");
-#endif
- sjcd_send_cmd(SCMD_UNLOCK_TRAY);
- return (sjcd_receive_status());
-}
-
-static int sjcd_tray_open(void)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: tray_open\n");
-#endif
- sjcd_send_cmd(SCMD_EJECT_TRAY);
- return (sjcd_receive_status());
-}
-
-/*
- * Do some user commands.
- */
-static int sjcd_ioctl(struct inode *ip, struct file *fp,
- unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
-#if defined( SJCD_TRACE )
- printk("SJCD:ioctl\n");
-#endif
-
- sjcd_get_status();
- if (!sjcd_status_valid)
- return (-EIO);
- if (sjcd_update_toc() < 0)
- return (-EIO);
-
- switch (cmd) {
- case CDROMSTART:{
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: start\n");
-#endif
- return (0);
- }
-
- case CDROMSTOP:{
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: stop\n");
-#endif
- sjcd_send_cmd(SCMD_PAUSE);
- (void) sjcd_receive_status();
- sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
- return (0);
- }
-
- case CDROMPAUSE:{
- struct sjcd_hw_qinfo q_info;
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: pause\n");
-#endif
- if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
- sjcd_send_cmd(SCMD_PAUSE);
- (void) sjcd_receive_status();
- if (sjcd_get_q_info(&q_info) < 0) {
- sjcd_audio_status =
- CDROM_AUDIO_NO_STATUS;
- } else {
- sjcd_audio_status =
- CDROM_AUDIO_PAUSED;
- sjcd_playing.start = q_info.abs;
- }
- return (0);
- } else
- return (-EINVAL);
- }
-
- case CDROMRESUME:{
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: resume\n");
-#endif
- if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
- /*
- * continue play starting at saved location
- */
- if (sjcd_play(&sjcd_playing) < 0) {
- sjcd_audio_status =
- CDROM_AUDIO_ERROR;
- return (-EIO);
- } else {
- sjcd_audio_status =
- CDROM_AUDIO_PLAY;
- return (0);
- }
- } else
- return (-EINVAL);
- }
-
- case CDROMPLAYTRKIND:{
- struct cdrom_ti ti;
- int s = -EFAULT;
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: playtrkind\n");
-#endif
- if (!copy_from_user(&ti, argp, sizeof(ti))) {
- s = 0;
- if (ti.cdti_trk0 < sjcd_first_track_no)
- return (-EINVAL);
- if (ti.cdti_trk1 > sjcd_last_track_no)
- ti.cdti_trk1 = sjcd_last_track_no;
- if (ti.cdti_trk0 > ti.cdti_trk1)
- return (-EINVAL);
-
- sjcd_playing.start =
- sjcd_table_of_contents[ti.cdti_trk0].
- un.track_msf;
- sjcd_playing.end =
- (ti.cdti_trk1 <
- sjcd_last_track_no) ?
- sjcd_table_of_contents[ti.cdti_trk1 +
- 1].un.
- track_msf : sjcd_table_of_contents[0].
- un.track_msf;
-
- if (sjcd_play(&sjcd_playing) < 0) {
- sjcd_audio_status =
- CDROM_AUDIO_ERROR;
- return (-EIO);
- } else
- sjcd_audio_status =
- CDROM_AUDIO_PLAY;
- }
- return (s);
- }
-
- case CDROMPLAYMSF:{
- struct cdrom_msf sjcd_msf;
- int s;
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: playmsf\n");
-#endif
- if ((s =
- access_ok(VERIFY_READ, argp, sizeof(sjcd_msf))
- ? 0 : -EFAULT) == 0) {
- if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
- sjcd_send_cmd(SCMD_PAUSE);
- (void) sjcd_receive_status();
- sjcd_audio_status =
- CDROM_AUDIO_NO_STATUS;
- }
-
- if (copy_from_user(&sjcd_msf, argp,
- sizeof(sjcd_msf)))
- return (-EFAULT);
-
- sjcd_playing.start.min =
- bin2bcd(sjcd_msf.cdmsf_min0);
- sjcd_playing.start.sec =
- bin2bcd(sjcd_msf.cdmsf_sec0);
- sjcd_playing.start.frame =
- bin2bcd(sjcd_msf.cdmsf_frame0);
- sjcd_playing.end.min =
- bin2bcd(sjcd_msf.cdmsf_min1);
- sjcd_playing.end.sec =
- bin2bcd(sjcd_msf.cdmsf_sec1);
- sjcd_playing.end.frame =
- bin2bcd(sjcd_msf.cdmsf_frame1);
-
- if (sjcd_play(&sjcd_playing) < 0) {
- sjcd_audio_status =
- CDROM_AUDIO_ERROR;
- return (-EIO);
- } else
- sjcd_audio_status =
- CDROM_AUDIO_PLAY;
- }
- return (s);
- }
-
- case CDROMREADTOCHDR:{
- struct cdrom_tochdr toc_header;
-#if defined (SJCD_TRACE )
- printk("SJCD: ioctl: readtocheader\n");
-#endif
- toc_header.cdth_trk0 = sjcd_first_track_no;
- toc_header.cdth_trk1 = sjcd_last_track_no;
- if (copy_to_user(argp, &toc_header,
- sizeof(toc_header)))
- return -EFAULT;
- return 0;
- }
-
- case CDROMREADTOCENTRY:{
- struct cdrom_tocentry toc_entry;
- int s;
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: readtocentry\n");
-#endif
- if ((s =
- access_ok(VERIFY_WRITE, argp, sizeof(toc_entry))
- ? 0 : -EFAULT) == 0) {
- struct sjcd_hw_disk_info *tp;
-
- if (copy_from_user(&toc_entry, argp,
- sizeof(toc_entry)))
- return (-EFAULT);
- if (toc_entry.cdte_track == CDROM_LEADOUT)
- tp = &sjcd_table_of_contents[0];
- else if (toc_entry.cdte_track <
- sjcd_first_track_no)
- return (-EINVAL);
- else if (toc_entry.cdte_track >
- sjcd_last_track_no)
- return (-EINVAL);
- else
- tp = &sjcd_table_of_contents
- [toc_entry.cdte_track];
-
- toc_entry.cdte_adr =
- tp->track_control & 0x0F;
- toc_entry.cdte_ctrl =
- tp->track_control >> 4;
-
- switch (toc_entry.cdte_format) {
- case CDROM_LBA:
- toc_entry.cdte_addr.lba =
- msf2hsg(&(tp->un.track_msf));
- break;
- case CDROM_MSF:
- toc_entry.cdte_addr.msf.minute =
- bcd2bin(tp->un.track_msf.min);
- toc_entry.cdte_addr.msf.second =
- bcd2bin(tp->un.track_msf.sec);
- toc_entry.cdte_addr.msf.frame =
- bcd2bin(tp->un.track_msf.
- frame);
- break;
- default:
- return (-EINVAL);
- }
- if (copy_to_user(argp, &toc_entry,
- sizeof(toc_entry)))
- s = -EFAULT;
- }
- return (s);
- }
-
- case CDROMSUBCHNL:{
- struct cdrom_subchnl subchnl;
- int s;
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: subchnl\n");
-#endif
- if ((s =
- access_ok(VERIFY_WRITE, argp, sizeof(subchnl))
- ? 0 : -EFAULT) == 0) {
- struct sjcd_hw_qinfo q_info;
-
- if (copy_from_user(&subchnl, argp,
- sizeof(subchnl)))
- return (-EFAULT);
-
- if (sjcd_get_q_info(&q_info) < 0)
- return (-EIO);
-
- subchnl.cdsc_audiostatus =
- sjcd_audio_status;
- subchnl.cdsc_adr =
- q_info.track_control & 0x0F;
- subchnl.cdsc_ctrl =
- q_info.track_control >> 4;
- subchnl.cdsc_trk =
- bcd2bin(q_info.track_no);
- subchnl.cdsc_ind = bcd2bin(q_info.x);
-
- switch (subchnl.cdsc_format) {
- case CDROM_LBA:
- subchnl.cdsc_absaddr.lba =
- msf2hsg(&(q_info.abs));
- subchnl.cdsc_reladdr.lba =
- msf2hsg(&(q_info.rel));
- break;
- case CDROM_MSF:
- subchnl.cdsc_absaddr.msf.minute =
- bcd2bin(q_info.abs.min);
- subchnl.cdsc_absaddr.msf.second =
- bcd2bin(q_info.abs.sec);
- subchnl.cdsc_absaddr.msf.frame =
- bcd2bin(q_info.abs.frame);
- subchnl.cdsc_reladdr.msf.minute =
- bcd2bin(q_info.rel.min);
- subchnl.cdsc_reladdr.msf.second =
- bcd2bin(q_info.rel.sec);
- subchnl.cdsc_reladdr.msf.frame =
- bcd2bin(q_info.rel.frame);
- break;
- default:
- return (-EINVAL);
- }
- if (copy_to_user(argp, &subchnl,
- sizeof(subchnl)))
- s = -EFAULT;
- }
- return (s);
- }
-
- case CDROMVOLCTRL:{
- struct cdrom_volctrl vol_ctrl;
- int s;
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: volctrl\n");
-#endif
- if ((s =
- access_ok(VERIFY_READ, argp, sizeof(vol_ctrl))
- ? 0 : -EFAULT) == 0) {
- unsigned char dummy[4];
-
- if (copy_from_user(&vol_ctrl, argp,
- sizeof(vol_ctrl)))
- return (-EFAULT);
- sjcd_send_4_cmd(SCMD_SET_VOLUME,
- vol_ctrl.channel0, 0xFF,
- vol_ctrl.channel1, 0xFF);
- if (sjcd_receive_status() < 0)
- return (-EIO);
- (void) sjcd_load_response(dummy, 4);
- }
- return (s);
- }
-
- case CDROMEJECT:{
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: eject\n");
-#endif
- if (!sjcd_command_is_in_progress) {
- sjcd_tray_unlock();
- sjcd_send_cmd(SCMD_EJECT_TRAY);
- (void) sjcd_receive_status();
- }
- return (0);
- }
-
-#if defined( SJCD_GATHER_STAT )
- case 0xABCD:{
-#if defined( SJCD_TRACE )
- printk("SJCD: ioctl: statistic\n");
-#endif
- if (copy_to_user(argp, &statistic, sizeof(statistic)))
- return -EFAULT;
- return 0;
- }
-#endif
-
- default:
- return (-EINVAL);
- }
-}
-
-/*
- * Invalidate internal buffers of the driver.
- */
-static void sjcd_invalidate_buffers(void)
-{
- int i;
- for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
- sjcd_buf_out = -1;
-}
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-
-static int current_valid(void)
-{
- return CURRENT &&
- CURRENT->cmd == READ &&
- CURRENT->sector != -1;
-}
-
-static void sjcd_transfer(void)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: transfer:\n");
-#endif
- if (current_valid()) {
- while (CURRENT->nr_sectors) {
- int i, bn = CURRENT->sector / 4;
- for (i = 0;
- i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
- i++);
- if (i < SJCD_BUF_SIZ) {
- int offs =
- (i * 4 + (CURRENT->sector & 3)) * 512;
- int nr_sectors = 4 - (CURRENT->sector & 3);
- if (sjcd_buf_out != i) {
- sjcd_buf_out = i;
- if (sjcd_buf_bn[i] != bn) {
- sjcd_buf_out = -1;
- continue;
- }
- }
- if (nr_sectors > CURRENT->nr_sectors)
- nr_sectors = CURRENT->nr_sectors;
-#if defined( SJCD_TRACE )
- printk("SJCD: copy out\n");
-#endif
- memcpy(CURRENT->buffer, sjcd_buf + offs,
- nr_sectors * 512);
- CURRENT->nr_sectors -= nr_sectors;
- CURRENT->sector += nr_sectors;
- CURRENT->buffer += nr_sectors * 512;
- } else {
- sjcd_buf_out = -1;
- break;
- }
- }
- }
-#if defined( SJCD_TRACE )
- printk("SJCD: transfer: done\n");
-#endif
-}
-
-static void sjcd_poll(void)
-{
-#if defined( SJCD_GATHER_STAT )
- /*
- * Update total number of ticks.
- */
- statistic.ticks++;
- statistic.tticks[sjcd_transfer_state]++;
-#endif
-
- ReSwitch:switch (sjcd_transfer_state) {
-
- case SJCD_S_IDLE:{
-#if defined( SJCD_GATHER_STAT )
- statistic.idle_ticks++;
-#endif
-#if defined( SJCD_TRACE )
- printk("SJCD_S_IDLE\n");
-#endif
- return;
- }
-
- case SJCD_S_START:{
-#if defined( SJCD_GATHER_STAT )
- statistic.start_ticks++;
-#endif
- sjcd_send_cmd(SCMD_GET_STATUS);
- sjcd_transfer_state =
- sjcd_mode ==
- SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
- sjcd_transfer_timeout = 500;
-#if defined( SJCD_TRACE )
- printk("SJCD_S_START: goto SJCD_S_%s mode\n",
- sjcd_transfer_state ==
- SJCD_S_READ ? "READ" : "MODE");
-#endif
- break;
- }
-
- case SJCD_S_MODE:{
- if (sjcd_check_status()) {
- /*
- * Previous command is completed.
- */
- if (!sjcd_status_valid
- || sjcd_command_failed) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- sjcd_mode = 0; /* unknown mode; should not be valid when failed */
- sjcd_send_1_cmd(SCMD_SET_MODE,
- SCMD_MODE_COOKED);
- sjcd_transfer_state = SJCD_S_READ;
- sjcd_transfer_timeout = 1000;
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
-#endif
- }
-#if defined( SJCD_GATHER_STAT )
- else
- statistic.mode_ticks++;
-#endif
- break;
- }
-
- case SJCD_S_READ:{
- if (sjcd_status_valid ? 1 : sjcd_check_status()) {
- /*
- * Previous command is completed.
- */
- if (!sjcd_status_valid
- || sjcd_command_failed) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- if (!sjcd_media_is_available) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- if (sjcd_mode != SCMD_MODE_COOKED) {
- /*
- * We seem to come from set mode. So discard one byte of result.
- */
- if (sjcd_load_response
- (&sjcd_mode, 1) != 0) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state =
- SJCD_S_STOP;
- goto ReSwitch;
- }
- if (sjcd_mode != SCMD_MODE_COOKED) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state =
- SJCD_S_STOP;
- goto ReSwitch;
- }
- }
-
- if (current_valid()) {
- struct sjcd_play_msf msf;
-
- sjcd_next_bn = CURRENT->sector / 4;
- hsg2msf(sjcd_next_bn, &msf.start);
- msf.end.min = 0;
- msf.end.sec = 0;
- msf.end.frame = sjcd_read_count =
- SJCD_BUF_SIZ;
-#if defined( SJCD_TRACE )
- printk
- ("SJCD: ---reading msf-address %x:%x:%x %x:%x:%x\n",
- msf.start.min, msf.start.sec,
- msf.start.frame, msf.end.min,
- msf.end.sec, msf.end.frame);
- printk
- ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
- sjcd_next_bn, sjcd_buf_in,
- sjcd_buf_out,
- sjcd_buf_bn[sjcd_buf_in]);
-#endif
- sjcd_send_6_cmd(SCMD_DATA_READ,
- &msf);
- sjcd_transfer_state = SJCD_S_DATA;
- sjcd_transfer_timeout = 500;
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
-#endif
- } else {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- }
-#if defined( SJCD_GATHER_STAT )
- else
- statistic.read_ticks++;
-#endif
- break;
- }
-
- case SJCD_S_DATA:{
- unsigned char stat;
-
- sjcd_s_data:stat =
- inb(SJCDPORT
- (1));
-#if defined( SJCD_TRACE )
- printk("SJCD_S_DATA: status = 0x%02x\n", stat);
-#endif
- if (SJCD_STATUS_AVAILABLE(stat)) {
- /*
- * No data is waiting for us in the drive buffer. Status of operation
- * completion is available. Read and parse it.
- */
- sjcd_load_status();
-
- if (!sjcd_status_valid
- || sjcd_command_failed) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
- sjcd_next_bn);
-#endif
- if (current_valid())
- end_request(CURRENT, 0);
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- if (!sjcd_media_is_available) {
- printk
- ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- sjcd_transfer_state = SJCD_S_READ;
- goto ReSwitch;
- } else if (SJCD_DATA_AVAILABLE(stat)) {
- /*
- * One frame is read into device buffer. We must copy it to our memory.
- * Otherwise cdrom hangs up. Check to see if we have something to copy
- * to.
- */
- if (!current_valid()
- && sjcd_buf_in == sjcd_buf_out) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
- printk
- (" ... all the date would be discarded\n");
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- /*
- * Everything seems to be OK. Just read the frame and recalculate
- * indices.
- */
- sjcd_buf_bn[sjcd_buf_in] = -1; /* ??? */
- insb(SJCDPORT(2),
- sjcd_buf + 2048 * sjcd_buf_in, 2048);
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
- sjcd_next_bn, sjcd_buf_in,
- sjcd_buf_out,
- sjcd_buf_bn[sjcd_buf_in]);
-#endif
- sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
- if (sjcd_buf_out == -1)
- sjcd_buf_out = sjcd_buf_in;
- if (++sjcd_buf_in == SJCD_BUF_SIZ)
- sjcd_buf_in = 0;
-
- /*
- * Only one frame is ready at time. So we should turn over to wait for
- * another frame. If we need that, of course.
- */
- if (--sjcd_read_count == 0) {
- /*
- * OK, request seems to be precessed. Continue transferring...
- */
- if (!sjcd_transfer_is_active) {
- while (current_valid()) {
- /*
- * Continue transferring.
- */
- sjcd_transfer();
- if (CURRENT->
- nr_sectors ==
- 0)
- end_request
- (CURRENT, 1);
- else
- break;
- }
- }
- if (current_valid() &&
- (CURRENT->sector / 4 <
- sjcd_next_bn
- || CURRENT->sector / 4 >
- sjcd_next_bn +
- SJCD_BUF_SIZ)) {
-#if defined( SJCD_TRACE )
- printk
- ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
-#endif
- sjcd_transfer_state =
- SJCD_S_STOP;
- goto ReSwitch;
- }
- }
- /*
- * Now we should turn around rather than wait for while.
- */
- goto sjcd_s_data;
- }
-#if defined( SJCD_GATHER_STAT )
- else
- statistic.data_ticks++;
-#endif
- break;
- }
-
- case SJCD_S_STOP:{
- sjcd_read_count = 0;
- sjcd_send_cmd(SCMD_STOP);
- sjcd_transfer_state = SJCD_S_STOPPING;
- sjcd_transfer_timeout = 500;
-#if defined( SJCD_GATHER_STAT )
- statistic.stop_ticks++;
-#endif
- break;
- }
-
- case SJCD_S_STOPPING:{
- unsigned char stat;
-
- stat = inb(SJCDPORT(1));
-#if defined( SJCD_TRACE )
- printk("SJCD_S_STOP: status = 0x%02x\n", stat);
-#endif
- if (SJCD_DATA_AVAILABLE(stat)) {
- int i;
-#if defined( SJCD_TRACE )
- printk("SJCD_S_STOP: discard data\n");
-#endif
- /*
- * Discard all the data from the pipe. Foolish method.
- */
- for (i = 2048; i--;
- (void) inb(SJCDPORT(2)));
- sjcd_transfer_timeout = 500;
- } else if (SJCD_STATUS_AVAILABLE(stat)) {
- sjcd_load_status();
- if (sjcd_status_valid
- && sjcd_media_is_changed) {
- sjcd_toc_uptodate = 0;
- sjcd_invalidate_buffers();
- }
- if (current_valid()) {
- if (sjcd_status_valid)
- sjcd_transfer_state =
- SJCD_S_READ;
- else
- sjcd_transfer_state =
- SJCD_S_START;
- } else
- sjcd_transfer_state = SJCD_S_IDLE;
- goto ReSwitch;
- }
-#if defined( SJCD_GATHER_STAT )
- else
- statistic.stopping_ticks++;
-#endif
- break;
- }
-
- default:
- printk("SJCD: poll: invalid state %d\n",
- sjcd_transfer_state);
- return;
- }
-
- if (--sjcd_transfer_timeout == 0) {
- printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
- while (current_valid())
- end_request(CURRENT, 0);
- sjcd_send_cmd(SCMD_STOP);
- sjcd_transfer_state = SJCD_S_IDLE;
- goto ReSwitch;
- }
-
- /*
- * Get back in some time. 1 should be replaced with count variable to
- * avoid unnecessary testings.
- */
- SJCD_SET_TIMER(sjcd_poll, 1);
-}
-
-static void do_sjcd_request(request_queue_t * q)
-{
-#if defined( SJCD_TRACE )
- printk("SJCD: do_sjcd_request(%ld+%ld)\n",
- CURRENT->sector, CURRENT->nr_sectors);
-#endif
- sjcd_transfer_is_active = 1;
- while (current_valid()) {
- sjcd_transfer();
- if (CURRENT->nr_sectors == 0)
- end_request(CURRENT, 1);
- else {
- sjcd_buf_out = -1; /* Want to read a block not in buffer */
- if (sjcd_transfer_state == SJCD_S_IDLE) {
- if (!sjcd_toc_uptodate) {
- if (sjcd_update_toc() < 0) {
- printk
- ("SJCD: transfer: discard\n");
- while (current_valid())
- end_request(CURRENT, 0);
- break;
- }
- }
- sjcd_transfer_state = SJCD_S_START;
- SJCD_SET_TIMER(sjcd_poll, HZ / 100);
- }
- break;
- }
- }
- sjcd_transfer_is_active = 0;
-#if defined( SJCD_TRACE )
- printk
- ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
- sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
- sjcd_buf_bn[sjcd_buf_in]);
- printk("do_sjcd_request ends\n");
-#endif
-}
-
-/*
- * Open the device special file. Check disk is in.
- */
-static int sjcd_open(struct inode *ip, struct file *fp)
-{
- /*
- * Check the presence of device.
- */
- if (!sjcd_present)
- return (-ENXIO);
-
- /*
- * Only read operations are allowed. Really? (:-)
- */
- if (fp->f_mode & 2)
- return (-EROFS);
-
- if (sjcd_open_count == 0) {
- int s, sjcd_open_tries;
-/* We don't know that, do we? */
-/*
- sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-*/
- sjcd_mode = 0;
- sjcd_door_was_open = 0;
- sjcd_transfer_state = SJCD_S_IDLE;
- sjcd_invalidate_buffers();
- sjcd_status_valid = 0;
-
- /*
- * Strict status checking.
- */
- for (sjcd_open_tries = 4; --sjcd_open_tries;) {
- if (!sjcd_status_valid)
- sjcd_get_status();
- if (!sjcd_status_valid) {
-#if defined( SJCD_DIAGNOSTIC )
- printk
- ("SJCD: open: timed out when check status.\n");
-#endif
- goto err_out;
- } else if (!sjcd_media_is_available) {
-#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: open: no disk in drive\n");
-#endif
- if (!sjcd_door_closed) {
- sjcd_door_was_open = 1;
-#if defined( SJCD_TRACE )
- printk
- ("SJCD: open: close the tray\n");
-#endif
- s = sjcd_tray_close();
- if (s < 0 || !sjcd_status_valid
- || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
- printk
- ("SJCD: open: tray close attempt failed\n");
-#endif
- goto err_out;
- }
- continue;
- } else
- goto err_out;
- }
- break;
- }
- s = sjcd_tray_lock();
- if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: open: tray lock attempt failed\n");
-#endif
- goto err_out;
- }
-#if defined( SJCD_TRACE )
- printk("SJCD: open: done\n");
-#endif
- }
-
- ++sjcd_open_count;
- return (0);
-
- err_out:
- return (-EIO);
-}
-
-/*
- * On close, we flush all sjcd blocks from the buffer cache.
- */
-static int sjcd_release(struct inode *inode, struct file *file)
-{
- int s;
-
-#if defined( SJCD_TRACE )
- printk("SJCD: release\n");
-#endif
- if (--sjcd_open_count == 0) {
- sjcd_invalidate_buffers();
- s = sjcd_tray_unlock();
- if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
- printk
- ("SJCD: release: tray unlock attempt failed.\n");
-#endif
- }
- if (sjcd_door_was_open) {
- s = sjcd_tray_open();
- if (s < 0 || !sjcd_status_valid
- || sjcd_command_failed) {
-#if defined( SJCD_DIAGNOSTIC )
- printk
- ("SJCD: release: tray unload attempt failed.\n");
-#endif
- }
- }
- }
- return 0;
-}
-
-/*
- * A list of file operations allowed for this cdrom.
- */
-static struct block_device_operations sjcd_fops = {
- .owner = THIS_MODULE,
- .open = sjcd_open,
- .release = sjcd_release,
- .ioctl = sjcd_ioctl,
- .media_changed = sjcd_disk_change,
-};
-
-/*
- * Following stuff is intended for initialization of the cdrom. It
- * first looks for presence of device. If the device is present, it
- * will be reset. Then read the version of the drive and load status.
- * The version is two BCD-coded bytes.
- */
-static struct {
- unsigned char major, minor;
-} sjcd_version;
-
-static struct gendisk *sjcd_disk;
-
-/*
- * Test for presence of drive and initialize it. Called at boot time.
- * Probe cdrom, find out version and status.
- */
-static int __init sjcd_init(void)
-{
- int i;
-
- printk(KERN_INFO
- "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
- SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
-
-#if defined( SJCD_TRACE )
- printk("SJCD: sjcd=0x%x: ", sjcd_base);
-#endif
-
- if (register_blkdev(MAJOR_NR, "sjcd"))
- return -EIO;
-
- sjcd_queue = blk_init_queue(do_sjcd_request, &sjcd_lock);
- if (!sjcd_queue)
- goto out0;
-
- blk_queue_hardsect_size(sjcd_queue, 2048);
-
- sjcd_disk = alloc_disk(1);
- if (!sjcd_disk) {
- printk(KERN_ERR "SJCD: can't allocate disk");
- goto out1;
- }
- sjcd_disk->major = MAJOR_NR,
- sjcd_disk->first_minor = 0,
- sjcd_disk->fops = &sjcd_fops,
- sprintf(sjcd_disk->disk_name, "sjcd");
-
- if (!request_region(sjcd_base, 4,"sjcd")) {
- printk
- ("SJCD: Init failed, I/O port (%X) is already in use\n",
- sjcd_base);
- goto out2;
- }
-
- /*
- * Check for card. Since we are booting now, we can't use standard
- * wait algorithm.
- */
- printk(KERN_INFO "SJCD: Resetting: ");
- sjcd_send_cmd(SCMD_RESET);
- for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
- unsigned long timer;
-
- /*
- * Wait 10ms approx.
- */
- for (timer = jiffies; time_before_eq(jiffies, timer););
- if ((i % 100) == 0)
- printk(".");
- (void) sjcd_check_status();
- }
- if (i == 0 || sjcd_command_failed) {
- printk(" reset failed, no drive found.\n");
- goto out3;
- } else
- printk("\n");
-
- /*
- * Get and print out cdrom version.
- */
- printk(KERN_INFO "SJCD: Getting version: ");
- sjcd_send_cmd(SCMD_GET_VERSION);
- for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
- unsigned long timer;
-
- /*
- * Wait 10ms approx.
- */
- for (timer = jiffies; time_before_eq(jiffies, timer););
- if ((i % 100) == 0)
- printk(".");
- (void) sjcd_check_status();
- }
- if (i == 0 || sjcd_command_failed) {
- printk(" get version failed, no drive found.\n");
- goto out3;
- }
-
- if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
- printk(" %1x.%02x\n", (int) sjcd_version.major,
- (int) sjcd_version.minor);
- } else {
- printk(" read version failed, no drive found.\n");
- goto out3;
- }
-
- /*
- * Check and print out the tray state. (if it is needed?).
- */
- if (!sjcd_status_valid) {
- printk(KERN_INFO "SJCD: Getting status: ");
- sjcd_send_cmd(SCMD_GET_STATUS);
- for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
- unsigned long timer;
-
- /*
- * Wait 10ms approx.
- */
- for (timer = jiffies;
- time_before_eq(jiffies, timer););
- if ((i % 100) == 0)
- printk(".");
- (void) sjcd_check_status();
- }
- if (i == 0 || sjcd_command_failed) {
- printk(" get status failed, no drive found.\n");
- goto out3;
- } else
- printk("\n");
- }
-
- printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
- sjcd_disk->queue = sjcd_queue;
- add_disk(sjcd_disk);
-
- sjcd_present++;
- return (0);
-out3:
- release_region(sjcd_base, 4);
-out2:
- put_disk(sjcd_disk);
-out1:
- blk_cleanup_queue(sjcd_queue);
-out0:
- if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
- printk("SJCD: cannot unregister device.\n");
- return (-EIO);
-}
-
-static void __exit sjcd_exit(void)
-{
- del_gendisk(sjcd_disk);
- put_disk(sjcd_disk);
- release_region(sjcd_base, 4);
- blk_cleanup_queue(sjcd_queue);
- if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
- printk("SJCD: cannot unregister device.\n");
- printk(KERN_INFO "SJCD: module: removed.\n");
-}
-
-module_init(sjcd_init);
-module_exit(sjcd_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR);
diff --git a/drivers/cdrom/sjcd.h b/drivers/cdrom/sjcd.h
deleted file mode 100644
index 0aa5e714659d..000000000000
--- a/drivers/cdrom/sjcd.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Definitions for a Sanyo CD-ROM interface.
- *
- * Copyright (C) 1995 Vadim V. Model
- * model@cecmow.enet.dec.com
- * vadim@rbrf.msk.su
- * vadim@ipsun.ras.ru
- * Eric van der Maarel
- * H.T.M.v.d.Maarel@marin.nl
- *
- * This information is based on mcd.c from M. Harriss and sjcd102.lst from
- * E. Moenkeberg.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __SJCD_H__
-#define __SJCD_H__
-
-/*
- * Change this to set the I/O port address as default. More flexibility
- * come with setup implementation.
- */
-#define SJCD_BASE_ADDR 0x340
-
-/*
- * Change this to set the irq as default. Really SANYO do not use interrupts
- * at all.
- */
-#define SJCD_INTR_NR 0
-
-/*
- * Change this to set the dma as default value. really SANYO does not use
- * direct memory access at all.
- */
-#define SJCD_DMA_NR 0
-
-/*
- * Macros which allow us to find out the status of the drive.
- */
-#define SJCD_STATUS_AVAILABLE( x ) (((x)&0x02)==0)
-#define SJCD_DATA_AVAILABLE( x ) (((x)&0x01)==0)
-
-/*
- * Port access macro. Three ports are available: S-data port (command port),
- * status port (read only) and D-data port (read only).
- */
-#define SJCDPORT( x ) ( sjcd_base + ( x ) )
-#define SJCD_STATUS_PORT SJCDPORT( 1 )
-#define SJCD_S_DATA_PORT SJCDPORT( 0 )
-#define SJCD_COMMAND_PORT SJCDPORT( 0 )
-#define SJCD_D_DATA_PORT SJCDPORT( 2 )
-
-/*
- * Drive info bits. Drive info available as first (mandatory) byte of
- * command completion status.
- */
-#define SST_NOT_READY 0x10 /* no disk in the drive (???) */
-#define SST_MEDIA_CHANGED 0x20 /* disk is changed */
-#define SST_DOOR_OPENED 0x40 /* door is open */
-
-/* commands */
-
-#define SCMD_EJECT_TRAY 0xD0 /* eject tray if not locked */
-#define SCMD_LOCK_TRAY 0xD2 /* lock tray when in */
-#define SCMD_UNLOCK_TRAY 0xD4 /* unlock tray when in */
-#define SCMD_CLOSE_TRAY 0xD6 /* load tray in */
-
-#define SCMD_RESET 0xFA /* soft reset */
-#define SCMD_GET_STATUS 0x80
-#define SCMD_GET_VERSION 0xCC
-
-#define SCMD_DATA_READ 0xA0 /* are the same, depend on mode&args */
-#define SCMD_SEEK 0xA0
-#define SCMD_PLAY 0xA0
-
-#define SCMD_GET_QINFO 0xA8
-
-#define SCMD_SET_MODE 0xC4
-#define SCMD_MODE_PLAY 0xE0
-#define SCMD_MODE_COOKED (0xF8 & ~0x20)
-#define SCMD_MODE_RAW 0xF9
-#define SCMD_MODE_x20_BIT 0x20 /* What is it for ? */
-
-#define SCMD_SET_VOLUME 0xAE
-#define SCMD_PAUSE 0xE0
-#define SCMD_STOP 0xE0
-
-#define SCMD_GET_DISK_INFO 0xAA
-
-/*
- * Some standard arguments for SCMD_GET_DISK_INFO.
- */
-#define SCMD_GET_1_TRACK 0xA0 /* get the first track information */
-#define SCMD_GET_L_TRACK 0xA1 /* get the last track information */
-#define SCMD_GET_D_SIZE 0xA2 /* get the whole disk information */
-
-/*
- * Borrowed from hd.c. Allows to optimize multiple port read commands.
- */
-#define S_READ_DATA( port, buf, nr ) insb( port, buf, nr )
-
-/*
- * We assume that there are no audio disks with TOC length more than this
- * number (I personally have never seen disks with more than 20 fragments).
- */
-#define SJCD_MAX_TRACKS 100
-
-struct msf {
- unsigned char min;
- unsigned char sec;
- unsigned char frame;
-};
-
-struct sjcd_hw_disk_info {
- unsigned char track_control;
- unsigned char track_no;
- unsigned char x, y, z;
- union {
- unsigned char track_no;
- struct msf track_msf;
- } un;
-};
-
-struct sjcd_hw_qinfo {
- unsigned char track_control;
- unsigned char track_no;
- unsigned char x;
- struct msf rel;
- struct msf abs;
-};
-
-struct sjcd_play_msf {
- struct msf start;
- struct msf end;
-};
-
-struct sjcd_disk_info {
- unsigned char first;
- unsigned char last;
- struct msf disk_length;
- struct msf first_track;
-};
-
-struct sjcd_toc {
- unsigned char ctrl_addr;
- unsigned char track;
- unsigned char point_index;
- struct msf track_time;
- struct msf disk_time;
-};
-
-#if defined( SJCD_GATHER_STAT )
-
-struct sjcd_stat {
- int ticks;
- int tticks[ 8 ];
- int idle_ticks;
- int start_ticks;
- int mode_ticks;
- int read_ticks;
- int data_ticks;
- int stop_ticks;
- int stopping_ticks;
-};
-
-#endif
-
-#endif
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
deleted file mode 100644
index f77ada933ea0..000000000000
--- a/drivers/cdrom/sonycd535.c
+++ /dev/null
@@ -1,1689 +0,0 @@
-/*
- * Sony CDU-535 interface device driver
- *
- * This is a modified version of the CDU-31A device driver (see below).
- * Changes were made using documentation for the CDU-531 (which Sony
- * assures me is very similar to the 535) and partial disassembly of the
- * DOS driver. I used Minyard's driver and replaced the CDU-31A
- * commands with the CDU-531 commands. This was complicated by a different
- * interface protocol with the drive. The driver is still polled.
- *
- * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec.
- * I tried polling without the sony_sleep during the data transfers but
- * it did not speed things up any.
- *
- * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict
- * with CDU-31A driver. This is the also the number from the Linux
- * Device Driver Registry for the Sony Drive. Hope nobody else is using it.
- *
- * 1993-08-29 (rgj) remove the configuring of the interface board address
- * from the top level configuration, you have to modify it in this file.
- *
- * 1995-01-26 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
- *
- * 1995-05-20
- * Modified to support CDU-510/515 series
- * (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
- * Fixed to report verify_area() failures
- * (Heiko Eissfeldt <heiko@colossus.escape.de>)
- *
- * 1995-06-01
- * More changes to support CDU-510/515 series
- * (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
- *
- * November 1999 -- Make kernel-parameter implementation work with 2.3.x
- * Removed init_module & cleanup_module in favor of
- * module_init & module_exit.
- * Torben Mathiasen <tmm@image.dk>
- *
- * September 2003 - Fix SMP support by removing cli/sti calls.
- * Using spinlocks with a wait_queue instead.
- * Felipe Damasio <felipewd@terra.com.br>
- *
- * Things to do:
- * - handle errors and status better, put everything into a single word
- * - use interrupts (code mostly there, but a big hole still missing)
- * - handle multi-session CDs?
- * - use DMA?
- *
- * Known Bugs:
- * -
- *
- * Ken Pizzini (ken@halcyon.com)
- *
- * Original by:
- * Ron Jeppesen (ronj.an@site007.saic.com)
- *
- *
- *------------------------------------------------------------------------
- * Sony CDROM interface device driver.
- *
- * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to Ken above)
- *
- * Colossians 3:17
- *
- * The Sony interface device driver handles Sony interface CDROM
- * drives and provides a complete block-level interface as well as an
- * ioctl() interface compatible with the Sun (as specified in
- * include/linux/cdrom.h). With this interface, CDROMs can be
- * accessed and standard audio CDs can be played back normally.
- *
- * This interface is (unfortunately) a polled interface. This is
- * because most Sony interfaces are set up with DMA and interrupts
- * disables. Some (like mine) do not even have the capability to
- * handle interrupts or DMA. For this reason you will see a bit of
- * the following:
- *
- * snap = jiffies;
- * while (jiffies-snap < SONY_JIFFIES_TIMEOUT)
- * {
- * if (some_condition())
- * break;
- * sony_sleep();
- * }
- * if (some_condition not met)
- * {
- * return an_error;
- * }
- *
- * This ugly hack waits for something to happen, sleeping a little
- * between every try. (The conditional is written so that jiffies
- * wrap-around is handled properly.)
- *
- * One thing about these drives: They talk in MSF (Minute Second Frame) format.
- * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
- * disk. The funny thing is that these are sent to the drive in BCD, but the
- * interface wants to see them in decimal. A lot of conversion goes on.
- *
- * Copyright (C) 1993 Corey Minyard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-# include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <linux/genhd.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#define REALLY_SLOW_IO
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <linux/cdrom.h>
-
-#define MAJOR_NR CDU535_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
-#include "sonycd535.h"
-
-/*
- * this is the base address of the interface card for the Sony CDU-535
- * CDROM drive. If your jumpers are set for an address other than
- * this one (the default), change the following line to the
- * proper address.
- */
-#ifndef CDU535_ADDRESS
-# define CDU535_ADDRESS 0x340
-#endif
-#ifndef CDU535_INTERRUPT
-# define CDU535_INTERRUPT 0
-#endif
-#ifndef CDU535_HANDLE
-# define CDU535_HANDLE "cdu535"
-#endif
-#ifndef CDU535_MESSAGE_NAME
-# define CDU535_MESSAGE_NAME "Sony CDU-535"
-#endif
-
-#define CDU535_BLOCK_SIZE 2048
-
-#ifndef MAX_SPINUP_RETRY
-# define MAX_SPINUP_RETRY 3 /* 1 is sufficient for most drives... */
-#endif
-#ifndef RETRY_FOR_BAD_STATUS
-# define RETRY_FOR_BAD_STATUS 100 /* in 10th of second */
-#endif
-
-#ifndef DEBUG
-# define DEBUG 1
-#endif
-
-/*
- * SONY535_BUFFER_SIZE determines the size of internal buffer used
- * by the drive. It must be at least 2K and the larger the buffer
- * the better the transfer rate. It does however take system memory.
- * On my system I get the following transfer rates using dd to read
- * 10 Mb off /dev/cdrom.
- *
- * 8K buffer 43 Kb/sec
- * 16K buffer 66 Kb/sec
- * 32K buffer 91 Kb/sec
- * 64K buffer 111 Kb/sec
- * 128K buffer 123 Kb/sec
- * 512K buffer 123 Kb/sec
- */
-#define SONY535_BUFFER_SIZE (64*1024)
-
-/*
- * if LOCK_DOORS is defined then the eject button is disabled while
- * the device is open.
- */
-#ifndef NO_LOCK_DOORS
-# define LOCK_DOORS
-#endif
-
-static int read_subcode(void);
-static void sony_get_toc(void);
-static int cdu_open(struct inode *inode, struct file *filp);
-static inline unsigned int int_to_bcd(unsigned int val);
-static unsigned int bcd_to_int(unsigned int bcd);
-static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
- Byte * response, int n_response, int ignoreStatusBit7);
-
-/* The base I/O address of the Sony Interface. This is a variable (not a
- #define) so it can be easily changed via some future ioctl() */
-static unsigned int sony535_cd_base_io = CDU535_ADDRESS;
-module_param(sony535_cd_base_io, int, 0);
-
-/*
- * The following are I/O addresses of the various registers for the drive. The
- * comment for the base address also applies here.
- */
-static unsigned short select_unit_reg;
-static unsigned short result_reg;
-static unsigned short command_reg;
-static unsigned short read_status_reg;
-static unsigned short data_reg;
-
-static DEFINE_SPINLOCK(sonycd535_lock); /* queue lock */
-static struct request_queue *sonycd535_queue;
-
-static int initialized; /* Has the drive been initialized? */
-static int sony_disc_changed = 1; /* Has the disk been changed
- since the last check? */
-static int sony_toc_read; /* Has the table of contents been
- read? */
-static unsigned int sony_buffer_size; /* Size in bytes of the read-ahead
- buffer. */
-static unsigned int sony_buffer_sectors; /* Size (in 2048 byte records) of
- the read-ahead buffer. */
-static unsigned int sony_usage; /* How many processes have the
- drive open. */
-
-static int sony_first_block = -1; /* First OS block (512 byte) in
- the read-ahead buffer */
-static int sony_last_block = -1; /* Last OS block (512 byte) in
- the read-ahead buffer */
-
-static struct s535_sony_toc *sony_toc; /* Points to the table of
- contents. */
-
-static struct s535_sony_subcode *last_sony_subcode; /* Points to the last
- subcode address read */
-static Byte **sony_buffer; /* Points to the pointers
- to the sector buffers */
-
-static int sony_inuse; /* is the drive in use? Only one
- open at a time allowed */
-
-/*
- * The audio status uses the values from read subchannel data as specified
- * in include/linux/cdrom.h.
- */
-static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
-
-/*
- * The following are a hack for pausing and resuming audio play. The drive
- * does not work as I would expect it, if you stop it then start it again,
- * the drive seeks back to the beginning and starts over. This holds the
- * position during a pause so a resume can restart it. It uses the
- * audio status variable above to tell if it is paused.
- * I just kept the CDU-31A driver behavior rather than using the PAUSE
- * command on the CDU-535.
- */
-static Byte cur_pos_msf[3];
-static Byte final_pos_msf[3];
-
-/* What IRQ is the drive using? 0 if none. */
-static int sony535_irq_used = CDU535_INTERRUPT;
-
-/* The interrupt handler will wake this queue up when it gets an interrupt. */
-static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait);
-
-
-/*
- * This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't. Setting flag to 0 resets the changed flag.
- */
-static int
-cdu535_check_media_change(struct gendisk *disk)
-{
- /* if driver is not initialized, always return 0 */
- int retval = initialized ? sony_disc_changed : 0;
- sony_disc_changed = 0;
- return retval;
-}
-
-static inline void
-enable_interrupts(void)
-{
-#ifdef USE_IRQ
- /*
- * This code was taken from cdu31a.c; it will not
- * directly work for the cdu535 as written...
- */
- curr_control_reg |= ( SONY_ATTN_INT_EN_BIT
- | SONY_RES_RDY_INT_EN_BIT
- | SONY_DATA_RDY_INT_EN_BIT);
- outb(curr_control_reg, sony_cd_control_reg);
-#endif
-}
-
-static inline void
-disable_interrupts(void)
-{
-#ifdef USE_IRQ
- /*
- * This code was taken from cdu31a.c; it will not
- * directly work for the cdu535 as written...
- */
- curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
- | SONY_RES_RDY_INT_EN_BIT
- | SONY_DATA_RDY_INT_EN_BIT);
- outb(curr_control_reg, sony_cd_control_reg);
-#endif
-}
-
-static irqreturn_t
-cdu535_interrupt(int irq, void *dev_id)
-{
- disable_interrupts();
- if (waitqueue_active(&cdu535_irq_wait)) {
- wake_up(&cdu535_irq_wait);
- return IRQ_HANDLED;
- }
- printk(CDU535_MESSAGE_NAME
- ": Got an interrupt but nothing was waiting\n");
- return IRQ_NONE;
-}
-
-
-/*
- * Wait a little while.
- */
-static inline void
-sony_sleep(void)
-{
- if (sony535_irq_used <= 0) { /* poll */
- yield();
- } else { /* Interrupt driven */
- DEFINE_WAIT(wait);
-
- spin_lock_irq(&sonycd535_lock);
- enable_interrupts();
- prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE);
- spin_unlock_irq(&sonycd535_lock);
- schedule();
- finish_wait(&cdu535_irq_wait, &wait);
- }
-}
-
-/*------------------start of SONY CDU535 very specific ---------------------*/
-
-/****************************************************************************
- * void select_unit( int unit_no )
- *
- * Select the specified unit (0-3) so that subsequent commands reference it
- ****************************************************************************/
-static void
-select_unit(int unit_no)
-{
- unsigned int select_mask = ~(1 << unit_no);
- outb(select_mask, select_unit_reg);
-}
-
-/***************************************************************************
- * int read_result_reg( Byte *data_ptr )
- *
- * Read a result byte from the Sony CDU controller, store in location pointed
- * to by data_ptr. Return zero on success, TIME_OUT if we did not receive
- * data.
- ***************************************************************************/
-static int
-read_result_reg(Byte *data_ptr)
-{
- unsigned long snap;
- int read_status;
-
- snap = jiffies;
- while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
- read_status = inb(read_status_reg);
- if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
-#if DEBUG > 1
- printk(CDU535_MESSAGE_NAME
- ": read_result_reg(): readStatReg = 0x%x\n", read_status);
-#endif
- *data_ptr = inb(result_reg);
- return 0;
- } else {
- sony_sleep();
- }
- }
- printk(CDU535_MESSAGE_NAME " read_result_reg: TIME OUT!\n");
- return TIME_OUT;
-}
-
-/****************************************************************************
- * int read_exec_status( Byte status[2] )
- *
- * Read the execution status of the last command and put into status.
- * Handles reading second status word if available. Returns 0 on success,
- * TIME_OUT on failure.
- ****************************************************************************/
-static int
-read_exec_status(Byte status[2])
-{
- status[1] = 0;
- if (read_result_reg(&(status[0])) != 0)
- return TIME_OUT;
- if ((status[0] & 0x80) != 0) { /* byte two follows */
- if (read_result_reg(&(status[1])) != 0)
- return TIME_OUT;
- }
-#if DEBUG > 1
- printk(CDU535_MESSAGE_NAME ": read_exec_status: read 0x%x 0x%x\n",
- status[0], status[1]);
-#endif
- return 0;
-}
-
-/****************************************************************************
- * int check_drive_status( void )
- *
- * Check the current drive status. Using this before executing a command
- * takes care of the problem of unsolicited drive status-2 messages.
- * Add a check of the audio status if we think the disk is playing.
- ****************************************************************************/
-static int
-check_drive_status(void)
-{
- Byte status, e_status[2];
- int CDD, ATN;
- Byte cmd;
-
- select_unit(0);
- if (sony_audio_status == CDROM_AUDIO_PLAY) { /* check status */
- outb(SONY535_REQUEST_AUDIO_STATUS, command_reg);
- if (read_result_reg(&status) == 0) {
- switch (status) {
- case 0x0:
- break; /* play in progress */
- case 0x1:
- break; /* paused */
- case 0x3: /* audio play completed */
- case 0x5: /* play not requested */
- sony_audio_status = CDROM_AUDIO_COMPLETED;
- read_subcode();
- break;
- case 0x4: /* error during play */
- sony_audio_status = CDROM_AUDIO_ERROR;
- break;
- }
- }
- }
- /* now check drive status */
- outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg);
- if (read_result_reg(&status) != 0)
- return TIME_OUT;
-
-#if DEBUG > 1
- printk(CDU535_MESSAGE_NAME ": check_drive_status() got 0x%x\n", status);
-#endif
-
- if (status == 0)
- return 0;
-
- ATN = status & 0xf;
- CDD = (status >> 4) & 0xf;
-
- switch (ATN) {
- case 0x0:
- break; /* go on to CDD stuff */
- case SONY535_ATN_BUSY:
- if (initialized)
- printk(CDU535_MESSAGE_NAME " error: drive busy\n");
- return CD_BUSY;
- case SONY535_ATN_EJECT_IN_PROGRESS:
- printk(CDU535_MESSAGE_NAME " error: eject in progress\n");
- sony_audio_status = CDROM_AUDIO_INVALID;
- return CD_BUSY;
- case SONY535_ATN_RESET_OCCURRED:
- case SONY535_ATN_DISC_CHANGED:
- case SONY535_ATN_RESET_AND_DISC_CHANGED:
-#if DEBUG > 0
- printk(CDU535_MESSAGE_NAME " notice: reset occurred or disc changed\n");
-#endif
- sony_disc_changed = 1;
- sony_toc_read = 0;
- sony_audio_status = CDROM_AUDIO_NO_STATUS;
- sony_first_block = -1;
- sony_last_block = -1;
- if (initialized) {
- cmd = SONY535_SPIN_UP;
- do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0);
- sony_get_toc();
- }
- return 0;
- default:
- printk(CDU535_MESSAGE_NAME " error: drive busy (ATN=0x%x)\n", ATN);
- return CD_BUSY;
- }
- switch (CDD) { /* the 531 docs are not helpful in decoding this */
- case 0x0: /* just use the values from the DOS driver */
- case 0x2:
- case 0xa:
- break; /* no error */
- case 0xc:
- printk(CDU535_MESSAGE_NAME
- ": check_drive_status(): CDD = 0xc! Not properly handled!\n");
- return CD_BUSY; /* ? */
- default:
- return CD_BUSY;
- }
- return 0;
-} /* check_drive_status() */
-
-/*****************************************************************************
- * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
- * Byte *response, int n_response, int ignore_status_bit7 )
- *
- * Generic routine for executing commands. The command and its parameters
- * should be placed in the cmd[] array, number of bytes in the command is
- * stored in nCmd. The response from the command will be stored in the
- * response array. The number of bytes you expect back (excluding status)
- * should be passed in n_response. Finally, some
- * commands set bit 7 of the return status even when there is no second
- * status byte, on these commands set ignoreStatusBit7 TRUE.
- * If the command was sent and data received back, then we return 0,
- * else we return TIME_OUT. You still have to check the status yourself.
- * You should call check_drive_status() before calling this routine
- * so that you do not lose notifications of disk changes, etc.
- ****************************************************************************/
-static int
-do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
- Byte * response, int n_response, int ignore_status_bit7)
-{
- int i;
-
- /* write out the command */
- for (i = 0; i < n_cmd; i++)
- outb(cmd[i], command_reg);
-
- /* read back the status */
- if (read_result_reg(status) != 0)
- return TIME_OUT;
- if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) {
- /* get second status byte */
- if (read_result_reg(status + 1) != 0)
- return TIME_OUT;
- } else {
- status[1] = 0;
- }
-#if DEBUG > 2
- printk(CDU535_MESSAGE_NAME ": do_sony_cmd %x: %x %x\n",
- *cmd, status[0], status[1]);
-#endif
-
- /* do not know about when I should read set of data and when not to */
- if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0)
- return 0;
-
- /* else, read in rest of data */
- for (i = 0; 0 < n_response; n_response--, i++)
- if (read_result_reg(response + i) != 0)
- return TIME_OUT;
- return 0;
-} /* do_sony_cmd() */
-
-/**************************************************************************
- * int set_drive_mode( int mode, Byte status[2] )
- *
- * Set the drive mode to the specified value (mode=0 is audio, mode=e0
- * is mode-1 CDROM
- **************************************************************************/
-static int
-set_drive_mode(int mode, Byte status[2])
-{
- Byte cmd_buff[2];
- Byte ret_buff[1];
-
- cmd_buff[0] = SONY535_SET_DRIVE_MODE;
- cmd_buff[1] = mode;
- return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1);
-}
-
-/***************************************************************************
- * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
- * Byte *data_buff, int buff_size )
- *
- * Read n_blocks of data from the CDROM starting at position params[0:2],
- * number of blocks in stored in params[3:5] -- both these are already
- * int bcd format.
- * Transfer the data into the buffer pointed at by data_buff. buff_size
- * gives the number of bytes available in the buffer.
- * The routine returns number of bytes read in if successful, otherwise
- * it returns one of the standard error returns.
- ***************************************************************************/
-static int
-seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
- Byte **buff, int buf_size)
-{
- Byte cmd_buff[7];
- int i;
- int read_status;
- unsigned long snap;
- Byte *data_buff;
- int sector_count = 0;
-
- if (buf_size < CDU535_BLOCK_SIZE * n_blocks)
- return NO_ROOM;
-
- set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
-
- /* send command to read the data */
- cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
- for (i = 0; i < 6; i++)
- cmd_buff[i + 1] = params[i];
- for (i = 0; i < 7; i++)
- outb(cmd_buff[i], command_reg);
-
- /* read back the data one block at a time */
- while (0 < n_blocks--) {
- /* wait for data to be ready */
- int data_valid = 0;
- snap = jiffies;
- while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
- read_status = inb(read_status_reg);
- if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
- read_exec_status(status);
- return BAD_STATUS;
- }
- if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
- /* data is ready, read it */
- data_buff = buff[sector_count++];
- for (i = 0; i < CDU535_BLOCK_SIZE; i++)
- *data_buff++ = inb(data_reg); /* unrolling this loop does not seem to help */
- data_valid = 1;
- break; /* exit the timeout loop */
- }
- sony_sleep(); /* data not ready, sleep a while */
- }
- if (!data_valid)
- return TIME_OUT; /* if we reach this stage */
- }
-
- /* read all the data, now read the status */
- if ((i = read_exec_status(status)) != 0)
- return i;
- return CDU535_BLOCK_SIZE * sector_count;
-} /* seek_and_read_N_blocks() */
-
-/****************************************************************************
- * int request_toc_data( Byte status[2], struct s535_sony_toc *toc )
- *
- * Read in the table of contents data. Converts all the bcd data
- * into integers in the toc structure.
- ****************************************************************************/
-static int
-request_toc_data(Byte status[2], struct s535_sony_toc *toc)
-{
- int to_status;
- int i, j, n_tracks, track_no;
- int first_track_num, last_track_num;
- Byte cmd_no = 0xb2;
- Byte track_address_buffer[5];
-
- /* read the fixed portion of the table of contents */
- if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0)
- return to_status;
-
- /* convert the data into integers so we can use them */
- first_track_num = bcd_to_int(toc->first_track_num);
- last_track_num = bcd_to_int(toc->last_track_num);
- n_tracks = last_track_num - first_track_num + 1;
-
- /* read each of the track address descriptors */
- for (i = 0; i < n_tracks; i++) {
- /* read the descriptor into a temporary buffer */
- for (j = 0; j < 5; j++) {
- if (read_result_reg(track_address_buffer + j) != 0)
- return TIME_OUT;
- if (j == 1) /* need to convert from bcd */
- track_no = bcd_to_int(track_address_buffer[j]);
- }
- /* copy the descriptor to proper location - sonycd.c just fills */
- memcpy(toc->tracks + i, track_address_buffer, 5);
- }
- return 0;
-} /* request_toc_data() */
-
-/***************************************************************************
- * int spin_up_drive( Byte status[2] )
- *
- * Spin up the drive (unless it is already spinning).
- ***************************************************************************/
-static int
-spin_up_drive(Byte status[2])
-{
- Byte cmd;
-
- /* first see if the drive is already spinning */
- cmd = SONY535_REQUEST_DRIVE_STATUS_1;
- if (do_sony_cmd(&cmd, 1, status, NULL, 0, 0) != 0)
- return TIME_OUT;
- if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0)
- return 0; /* it's already spinning */
-
- /* otherwise, give the spin-up command */
- cmd = SONY535_SPIN_UP;
- return do_sony_cmd(&cmd, 1, status, NULL, 0, 0);
-}
-
-/*--------------------end of SONY CDU535 very specific ---------------------*/
-
-/* Convert from an integer 0-99 to BCD */
-static inline unsigned int
-int_to_bcd(unsigned int val)
-{
- int retval;
-
- retval = (val / 10) << 4;
- retval = retval | val % 10;
- return retval;
-}
-
-
-/* Convert from BCD to an integer from 0-99 */
-static unsigned int
-bcd_to_int(unsigned int bcd)
-{
- return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
-}
-
-
-/*
- * Convert a logical sector value (like the OS would want to use for
- * a block device) to an MSF format.
- */
-static void
-log_to_msf(unsigned int log, Byte *msf)
-{
- log = log + LOG_START_OFFSET;
- msf[0] = int_to_bcd(log / 4500);
- log = log % 4500;
- msf[1] = int_to_bcd(log / 75);
- msf[2] = int_to_bcd(log % 75);
-}
-
-
-/*
- * Convert an MSF format to a logical sector.
- */
-static unsigned int
-msf_to_log(Byte *msf)
-{
- unsigned int log;
-
-
- log = bcd_to_int(msf[2]);
- log += bcd_to_int(msf[1]) * 75;
- log += bcd_to_int(msf[0]) * 4500;
- log = log - LOG_START_OFFSET;
-
- return log;
-}
-
-
-/*
- * Take in integer size value and put it into a buffer like
- * the drive would want to see a number-of-sector value.
- */
-static void
-size_to_buf(unsigned int size, Byte *buf)
-{
- buf[0] = size / 65536;
- size = size % 65536;
- buf[1] = size / 256;
- buf[2] = size % 256;
-}
-
-
-/*
- * The OS calls this to perform a read or write operation to the drive.
- * Write obviously fail. Reads to a read ahead of sony_buffer_size
- * bytes to help speed operations. This especially helps since the OS
- * may use 1024 byte blocks and the drive uses 2048 byte blocks. Since most
- * data access on a CD is done sequentially, this saves a lot of operations.
- */
-static void
-do_cdu535_request(request_queue_t * q)
-{
- struct request *req;
- unsigned int read_size;
- int block;
- int nsect;
- int copyoff;
- int spin_up_retry;
- Byte params[10];
- Byte status[2];
- Byte cmd[2];
-
- while (1) {
- req = elv_next_request(q);
- if (!req)
- return;
-
- block = req->sector;
- nsect = req->nr_sectors;
- if (!blk_fs_request(req)) {
- end_request(req, 0);
- continue;
- }
- if (rq_data_dir(req) == WRITE) {
- end_request(req, 0);
- continue;
- }
- /*
- * If the block address is invalid or the request goes beyond
- * the end of the media, return an error.
- */
- if (sony_toc->lead_out_start_lba <= (block/4)) {
- end_request(req, 0);
- return;
- }
- if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
- end_request(req, 0);
- return;
- }
- while (0 < nsect) {
- /*
- * If the requested sector is not currently in
- * the read-ahead buffer, it must be read in.
- */
- if ((block < sony_first_block) || (sony_last_block < block)) {
- sony_first_block = (block / 4) * 4;
- log_to_msf(block / 4, params);
-
- /*
- * If the full read-ahead would go beyond the end of the media, trim
- * it back to read just till the end of the media.
- */
- if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
- sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
- read_size = sony_toc->lead_out_start_lba - (block / 4);
- } else {
- sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
- read_size = sony_buffer_sectors;
- }
- size_to_buf(read_size, &params[3]);
-
- /*
- * Read the data. If the drive was not spinning,
- * spin it up and try some more.
- */
- for (spin_up_retry=0 ;; ++spin_up_retry) {
- /* This loop has been modified to support the Sony
- * CDU-510/515 series, thanks to Claudio Porfiri
- * <C.Porfiri@nisms.tei.ericsson.se>.
- */
- /*
- * This part is to deal with very slow hardware. We
- * try at most MAX_SPINUP_RETRY times to read the same
- * block. A check for seek_and_read_N_blocks' result is
- * performed; if the result is wrong, the CDROM's engine
- * is restarted and the operation is tried again.
- */
- /*
- * 1995-06-01: The system got problems when downloading
- * from Slackware CDROM, the problem seems to be:
- * seek_and_read_N_blocks returns BAD_STATUS and we
- * should wait for a while before retrying, so a new
- * part was added to discriminate the return value from
- * seek_and_read_N_blocks for the various cases.
- */
- int readStatus = seek_and_read_N_blocks(params, read_size,
- status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
- if (0 <= readStatus) /* Good data; common case, placed first */
- break;
- if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
- /* give up */
- if (readStatus == NO_ROOM)
- printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
- else
- printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
- status[0]);
- sony_first_block = -1;
- sony_last_block = -1;
- end_request(req, 0);
- return;
- }
- if (readStatus == BAD_STATUS) {
- /* Sleep for a while, then retry */
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(&sonycd535_lock);
- schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
- spin_lock_irq(&sonycd535_lock);
- }
-#if DEBUG > 0
- printk(CDU535_MESSAGE_NAME
- " debug: calling spin up when reading data!\n");
-#endif
- cmd[0] = SONY535_SPIN_UP;
- do_sony_cmd(cmd, 1, status, NULL, 0, 0);
- }
- }
- /*
- * The data is in memory now, copy it to the buffer and advance to the
- * next block to read.
- */
- copyoff = block - sony_first_block;
- memcpy(req->buffer,
- sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
-
- block += 1;
- nsect -= 1;
- req->buffer += 512;
- }
-
- end_request(req, 1);
- }
-}
-
-/*
- * Read the table of contents from the drive and set sony_toc_read if
- * successful.
- */
-static void
-sony_get_toc(void)
-{
- Byte status[2];
- if (!sony_toc_read) {
- /* do not call check_drive_status() from here since it can call this routine */
- if (request_toc_data(status, sony_toc) < 0)
- return;
- sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
- sony_toc_read = 1;
- }
-}
-
-
-/*
- * Search for a specific track in the table of contents. track is
- * passed in bcd format
- */
-static int
-find_track(int track)
-{
- int i;
- int num_tracks;
-
-
- num_tracks = bcd_to_int(sony_toc->last_track_num) -
- bcd_to_int(sony_toc->first_track_num) + 1;
- for (i = 0; i < num_tracks; i++) {
- if (sony_toc->tracks[i].track == track) {
- return i;
- }
- }
-
- return -1;
-}
-
-/*
- * Read the subcode and put it int last_sony_subcode for future use.
- */
-static int
-read_subcode(void)
-{
- Byte cmd = SONY535_REQUEST_SUB_Q_DATA;
- Byte status[2];
- int dsc_status;
-
- if (check_drive_status() != 0)
- return -EIO;
-
- if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode,
- sizeof(struct s535_sony_subcode), 1)) != 0) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x, %d (read_subcode)\n",
- status[0], dsc_status);
- return -EIO;
- }
- return 0;
-}
-
-
-/*
- * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If
- * the drive is playing, the subchannel needs to be read (since it would be
- * changing). If the drive is paused or completed, the subcode information has
- * already been stored, just use that. The ioctl call wants things in decimal
- * (not BCD), so all the conversions are done.
- */
-static int
-sony_get_subchnl_info(void __user *arg)
-{
- struct cdrom_subchnl schi;
-
- /* Get attention stuff */
- if (check_drive_status() != 0)
- return -EIO;
-
- sony_get_toc();
- if (!sony_toc_read) {
- return -EIO;
- }
- if (copy_from_user(&schi, arg, sizeof schi))
- return -EFAULT;
-
- switch (sony_audio_status) {
- case CDROM_AUDIO_PLAY:
- if (read_subcode() < 0) {
- return -EIO;
- }
- break;
-
- case CDROM_AUDIO_PAUSED:
- case CDROM_AUDIO_COMPLETED:
- break;
-
- case CDROM_AUDIO_NO_STATUS:
- schi.cdsc_audiostatus = sony_audio_status;
- if (copy_to_user(arg, &schi, sizeof schi))
- return -EFAULT;
- return 0;
- break;
-
- case CDROM_AUDIO_INVALID:
- case CDROM_AUDIO_ERROR:
- default:
- return -EIO;
- }
-
- schi.cdsc_audiostatus = sony_audio_status;
- schi.cdsc_adr = last_sony_subcode->address;
- schi.cdsc_ctrl = last_sony_subcode->control;
- schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
- schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
- if (schi.cdsc_format == CDROM_MSF) {
- schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
- schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
- schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
-
- schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
- schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
- schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
- } else if (schi.cdsc_format == CDROM_LBA) {
- schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
- schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
- }
- return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0;
-}
-
-
-/*
- * The big ugly ioctl handler.
- */
-static int
-cdu_ioctl(struct inode *inode,
- struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- Byte status[2];
- Byte cmd_buff[10], params[10];
- int i;
- int dsc_status;
- void __user *argp = (void __user *)arg;
-
- if (check_drive_status() != 0)
- return -EIO;
-
- switch (cmd) {
- case CDROMSTART: /* Spin up the drive */
- if (spin_up_drive(status) < 0) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTART)\n",
- status[0]);
- return -EIO;
- }
- return 0;
- break;
-
- case CDROMSTOP: /* Spin down the drive */
- cmd_buff[0] = SONY535_HOLD;
- do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-
- /*
- * Spin the drive down, ignoring the error if the disk was
- * already not spinning.
- */
- sony_audio_status = CDROM_AUDIO_NO_STATUS;
- cmd_buff[0] = SONY535_SPIN_DOWN;
- dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
- if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) ||
- ((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTOP)\n",
- status[0]);
- return -EIO;
- }
- return 0;
- break;
-
- case CDROMPAUSE: /* Pause the drive */
- cmd_buff[0] = SONY535_HOLD; /* CDU-31 driver uses AUDIO_STOP, not pause */
- if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPAUSE)\n",
- status[0]);
- return -EIO;
- }
- /* Get the current position and save it for resuming */
- if (read_subcode() < 0) {
- return -EIO;
- }
- cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
- cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
- cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
- sony_audio_status = CDROM_AUDIO_PAUSED;
- return 0;
- break;
-
- case CDROMRESUME: /* Start the drive after being paused */
- set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
-
- if (sony_audio_status != CDROM_AUDIO_PAUSED) {
- return -EINVAL;
- }
- spin_up_drive(status);
-
- /* Start the drive at the saved position. */
- cmd_buff[0] = SONY535_PLAY_AUDIO;
- cmd_buff[1] = 0; /* play back starting at this address */
- cmd_buff[2] = cur_pos_msf[0];
- cmd_buff[3] = cur_pos_msf[1];
- cmd_buff[4] = cur_pos_msf[2];
- cmd_buff[5] = SONY535_PLAY_AUDIO;
- cmd_buff[6] = 2; /* set ending address */
- cmd_buff[7] = final_pos_msf[0];
- cmd_buff[8] = final_pos_msf[1];
- cmd_buff[9] = final_pos_msf[2];
- if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
- (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMRESUME)\n",
- status[0]);
- return -EIO;
- }
- sony_audio_status = CDROM_AUDIO_PLAY;
- return 0;
- break;
-
- case CDROMPLAYMSF: /* Play starting at the given MSF address. */
- if (copy_from_user(params, argp, 6))
- return -EFAULT;
- spin_up_drive(status);
- set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
-
- /* The parameters are given in int, must be converted */
- for (i = 0; i < 3; i++) {
- cmd_buff[2 + i] = int_to_bcd(params[i]);
- cmd_buff[7 + i] = int_to_bcd(params[i + 3]);
- }
- cmd_buff[0] = SONY535_PLAY_AUDIO;
- cmd_buff[1] = 0; /* play back starting at this address */
- /* cmd_buff[2-4] are filled in for loop above */
- cmd_buff[5] = SONY535_PLAY_AUDIO;
- cmd_buff[6] = 2; /* set ending address */
- /* cmd_buff[7-9] are filled in for loop above */
- if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
- (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYMSF)\n",
- status[0]);
- return -EIO;
- }
- /* Save the final position for pauses and resumes */
- final_pos_msf[0] = cmd_buff[7];
- final_pos_msf[1] = cmd_buff[8];
- final_pos_msf[2] = cmd_buff[9];
- sony_audio_status = CDROM_AUDIO_PLAY;
- return 0;
- break;
-
- case CDROMREADTOCHDR: /* Read the table of contents header */
- {
- struct cdrom_tochdr __user *hdr = argp;
- struct cdrom_tochdr loc_hdr;
-
- sony_get_toc();
- if (!sony_toc_read)
- return -EIO;
- loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
- loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
- if (copy_to_user(hdr, &loc_hdr, sizeof *hdr))
- return -EFAULT;
- }
- return 0;
- break;
-
- case CDROMREADTOCENTRY: /* Read a given table of contents entry */
- {
- struct cdrom_tocentry __user *entry = argp;
- struct cdrom_tocentry loc_entry;
- int track_idx;
- Byte *msf_val = NULL;
-
- sony_get_toc();
- if (!sony_toc_read) {
- return -EIO;
- }
-
- if (copy_from_user(&loc_entry, entry, sizeof loc_entry))
- return -EFAULT;
-
- /* Lead out is handled separately since it is special. */
- if (loc_entry.cdte_track == CDROM_LEADOUT) {
- loc_entry.cdte_adr = 0 /*sony_toc->address2 */ ;
- loc_entry.cdte_ctrl = sony_toc->control2;
- msf_val = sony_toc->lead_out_start_msf;
- } else {
- track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
- if (track_idx < 0)
- return -EINVAL;
- loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address */ ;
- loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
- msf_val = sony_toc->tracks[track_idx].track_start_msf;
- }
-
- /* Logical buffer address or MSF format requested? */
- if (loc_entry.cdte_format == CDROM_LBA) {
- loc_entry.cdte_addr.lba = msf_to_log(msf_val);
- } else if (loc_entry.cdte_format == CDROM_MSF) {
- loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
- loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1));
- loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2));
- }
- if (copy_to_user(entry, &loc_entry, sizeof *entry))
- return -EFAULT;
- }
- return 0;
- break;
-
- case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- {
- struct cdrom_ti ti;
- int track_idx;
-
- sony_get_toc();
- if (!sony_toc_read)
- return -EIO;
-
- if (copy_from_user(&ti, argp, sizeof ti))
- return -EFAULT;
- if ((ti.cdti_trk0 < sony_toc->first_track_num)
- || (sony_toc->last_track_num < ti.cdti_trk0)
- || (ti.cdti_trk1 < ti.cdti_trk0)) {
- return -EINVAL;
- }
- track_idx = find_track(int_to_bcd(ti.cdti_trk0));
- if (track_idx < 0)
- return -EINVAL;
- params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
- params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
- params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
- /*
- * If we want to stop after the last track, use the lead-out
- * MSF to do that.
- */
- if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) {
- log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1,
- &(params[4]));
- } else {
- track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1));
- if (track_idx < 0)
- return -EINVAL;
- log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1,
- &(params[4]));
- }
- params[0] = 0x03;
-
- spin_up_drive(status);
-
- set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
-
- /* Start the drive at the saved position. */
- cmd_buff[0] = SONY535_PLAY_AUDIO;
- cmd_buff[1] = 0; /* play back starting at this address */
- cmd_buff[2] = params[1];
- cmd_buff[3] = params[2];
- cmd_buff[4] = params[3];
- cmd_buff[5] = SONY535_PLAY_AUDIO;
- cmd_buff[6] = 2; /* set ending address */
- cmd_buff[7] = params[4];
- cmd_buff[8] = params[5];
- cmd_buff[9] = params[6];
- if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
- (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYTRKIND)\n",
- status[0]);
- printk("... Params: %x %x %x %x %x %x %x\n",
- params[0], params[1], params[2],
- params[3], params[4], params[5], params[6]);
- return -EIO;
- }
- /* Save the final position for pauses and resumes */
- final_pos_msf[0] = params[4];
- final_pos_msf[1] = params[5];
- final_pos_msf[2] = params[6];
- sony_audio_status = CDROM_AUDIO_PLAY;
- return 0;
- }
-
- case CDROMSUBCHNL: /* Get subchannel info */
- return sony_get_subchnl_info(argp);
-
- case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
- {
- struct cdrom_volctrl volctrl;
-
- if (copy_from_user(&volctrl, argp, sizeof volctrl))
- return -EFAULT;
- cmd_buff[0] = SONY535_SET_VOLUME;
- cmd_buff[1] = volctrl.channel0;
- cmd_buff[2] = volctrl.channel1;
- if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMVOLCTRL)\n",
- status[0]);
- return -EIO;
- }
- }
- return 0;
-
- case CDROMEJECT: /* Eject the drive */
- cmd_buff[0] = SONY535_STOP;
- do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
- cmd_buff[0] = SONY535_SPIN_DOWN;
- do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-
- sony_audio_status = CDROM_AUDIO_INVALID;
- cmd_buff[0] = SONY535_EJECT_CADDY;
- if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMEJECT)\n",
- status[0]);
- return -EIO;
- }
- return 0;
- break;
-
- default:
- return -EINVAL;
- }
-}
-
-
-/*
- * Open the drive for operations. Spin the drive up and read the table of
- * contents if these have not already been done.
- */
-static int
-cdu_open(struct inode *inode,
- struct file *filp)
-{
- Byte status[2], cmd_buff[2];
-
- if (sony_inuse)
- return -EBUSY;
- if (check_drive_status() != 0)
- return -EIO;
- sony_inuse = 1;
-
- if (spin_up_drive(status) != 0) {
- printk(CDU535_MESSAGE_NAME " error 0x%.2x (cdu_open, spin up)\n",
- status[0]);
- sony_inuse = 0;
- return -EIO;
- }
- sony_get_toc();
- if (!sony_toc_read) {
- cmd_buff[0] = SONY535_SPIN_DOWN;
- do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
- sony_inuse = 0;
- return -EIO;
- }
- check_disk_change(inode->i_bdev);
- sony_usage++;
-
-#ifdef LOCK_DOORS
- /* disable the eject button while mounted */
- cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
- do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
-#endif
-
- return 0;
-}
-
-
-/*
- * Close the drive. Spin it down if no task is using it. The spin
- * down will fail if playing audio, so audio play is OK.
- */
-static int
-cdu_release(struct inode *inode,
- struct file *filp)
-{
- Byte status[2], cmd_no;
-
- sony_inuse = 0;
-
- if (0 < sony_usage) {
- sony_usage--;
- }
- if (sony_usage == 0) {
- check_drive_status();
-
- if (sony_audio_status != CDROM_AUDIO_PLAY) {
- cmd_no = SONY535_SPIN_DOWN;
- do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
- }
-#ifdef LOCK_DOORS
- /* enable the eject button after umount */
- cmd_no = SONY535_ENABLE_EJECT_BUTTON;
- do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
-#endif
- }
- return 0;
-}
-
-static struct block_device_operations cdu_fops =
-{
- .owner = THIS_MODULE,
- .open = cdu_open,
- .release = cdu_release,
- .ioctl = cdu_ioctl,
- .media_changed = cdu535_check_media_change,
-};
-
-static struct gendisk *cdu_disk;
-
-/*
- * Initialize the driver.
- */
-static int __init sony535_init(void)
-{
- struct s535_sony_drive_config drive_config;
- Byte cmd_buff[3];
- Byte ret_buff[2];
- Byte status[2];
- unsigned long snap;
- int got_result = 0;
- int tmp_irq;
- int i;
- int err;
-
- /* Setting the base I/O address to 0 will disable it. */
- if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0))
- return 0;
-
- /* Set up all the register locations */
- result_reg = sony535_cd_base_io;
- command_reg = sony535_cd_base_io;
- data_reg = sony535_cd_base_io + 1;
- read_status_reg = sony535_cd_base_io + 2;
- select_unit_reg = sony535_cd_base_io + 3;
-
-#ifndef USE_IRQ
- sony535_irq_used = 0; /* polling only until this is ready... */
-#endif
- /* we need to poll until things get initialized */
- tmp_irq = sony535_irq_used;
- sony535_irq_used = 0;
-
-#if DEBUG > 0
- printk(KERN_INFO CDU535_MESSAGE_NAME ": probing base address %03X\n",
- sony535_cd_base_io);
-#endif
- /* look for the CD-ROM, follows the procedure in the DOS driver */
- inb(select_unit_reg);
- /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
- schedule_timeout_interruptible((HZ+17)*40/18);
- inb(result_reg);
-
- outb(0, read_status_reg); /* does a reset? */
- snap = jiffies;
- while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
- select_unit(0);
- if (inb(result_reg) != 0xff) {
- got_result = 1;
- break;
- }
- sony_sleep();
- }
-
- if (!got_result || check_drive_status() == TIME_OUT)
- goto Enodev;
-
- /* CD-ROM drive responded -- get the drive configuration */
- cmd_buff[0] = SONY535_INQUIRY;
- if (do_sony_cmd(cmd_buff, 1, status, (Byte *)&drive_config, 28, 1) != 0)
- goto Enodev;
-
- /* was able to get the configuration,
- * set drive mode as rest of init
- */
-#if DEBUG > 0
- /* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
- if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
- printk(CDU535_MESSAGE_NAME
- "Inquiry command returned status = 0x%x\n", status[0]);
-#endif
- /* now ready to use interrupts, if available */
- sony535_irq_used = tmp_irq;
-
- /* A negative sony535_irq_used will attempt an autoirq. */
- if (sony535_irq_used < 0) {
- unsigned long irq_mask, delay;
-
- irq_mask = probe_irq_on();
- enable_interrupts();
- outb(0, read_status_reg); /* does a reset? */
- delay = jiffies + HZ/10;
- while (time_before(jiffies, delay)) ;
-
- sony535_irq_used = probe_irq_off(irq_mask);
- disable_interrupts();
- }
- if (sony535_irq_used > 0) {
- if (request_irq(sony535_irq_used, cdu535_interrupt,
- IRQF_DISABLED, CDU535_HANDLE, NULL)) {
- printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
- " driver; polling instead.\n", sony535_irq_used);
- sony535_irq_used = 0;
- }
- }
- cmd_buff[0] = SONY535_SET_DRIVE_MODE;
- cmd_buff[1] = 0x0; /* default audio */
- if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) != 0)
- goto Enodev_irq;
-
- /* set the drive mode successful, we are set! */
- sony_buffer_size = SONY535_BUFFER_SIZE;
- sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
-
- printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
- drive_config.vendor_id,
- drive_config.product_id,
- drive_config.product_rev_level);
- printk(" base address %03X, ", sony535_cd_base_io);
- if (tmp_irq > 0)
- printk("IRQ%d, ", tmp_irq);
- printk("using %d byte buffer\n", sony_buffer_size);
-
- if (register_blkdev(MAJOR_NR, CDU535_HANDLE)) {
- err = -EIO;
- goto out1;
- }
- sonycd535_queue = blk_init_queue(do_cdu535_request, &sonycd535_lock);
- if (!sonycd535_queue) {
- err = -ENOMEM;
- goto out1a;
- }
-
- blk_queue_hardsect_size(sonycd535_queue, CDU535_BLOCK_SIZE);
- sony_toc = kmalloc(sizeof(struct s535_sony_toc), GFP_KERNEL);
- err = -ENOMEM;
- if (!sony_toc)
- goto out2;
- last_sony_subcode = kmalloc(sizeof(struct s535_sony_subcode), GFP_KERNEL);
- if (!last_sony_subcode)
- goto out3;
- sony_buffer = kmalloc(sizeof(Byte *) * sony_buffer_sectors, GFP_KERNEL);
- if (!sony_buffer)
- goto out4;
- for (i = 0; i < sony_buffer_sectors; i++) {
- sony_buffer[i] = kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
- if (!sony_buffer[i]) {
- while (--i>=0)
- kfree(sony_buffer[i]);
- goto out5;
- }
- }
- initialized = 1;
-
- cdu_disk = alloc_disk(1);
- if (!cdu_disk)
- goto out6;
- cdu_disk->major = MAJOR_NR;
- cdu_disk->first_minor = 0;
- cdu_disk->fops = &cdu_fops;
- sprintf(cdu_disk->disk_name, "cdu");
-
- if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
- printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
- sony535_cd_base_io);
- goto out7;
- }
- cdu_disk->queue = sonycd535_queue;
- add_disk(cdu_disk);
- return 0;
-
-out7:
- put_disk(cdu_disk);
-out6:
- for (i = 0; i < sony_buffer_sectors; i++)
- kfree(sony_buffer[i]);
-out5:
- kfree(sony_buffer);
-out4:
- kfree(last_sony_subcode);
-out3:
- kfree(sony_toc);
-out2:
- blk_cleanup_queue(sonycd535_queue);
-out1a:
- unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
-out1:
- if (sony535_irq_used)
- free_irq(sony535_irq_used, NULL);
- return err;
-Enodev_irq:
- if (sony535_irq_used)
- free_irq(sony535_irq_used, NULL);
-Enodev:
- printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
- return -EIO;
-}
-
-#ifndef MODULE
-
-/*
- * accept "kernel command line" parameters
- * (added by emoenke@gwdg.de)
- *
- * use: tell LILO:
- * sonycd535=0x320
- *
- * the address value has to be the existing CDROM port address.
- */
-static int __init
-sonycd535_setup(char *strings)
-{
- int ints[3];
- (void)get_options(strings, ARRAY_SIZE(ints), ints);
- /* if IRQ change and default io base desired,
- * then call with io base of 0
- */
- if (ints[0] > 0)
- if (ints[1] != 0)
- sony535_cd_base_io = ints[1];
- if (ints[0] > 1)
- sony535_irq_used = ints[2];
- if ((strings != NULL) && (*strings != '\0'))
- printk(CDU535_MESSAGE_NAME
- ": Warning: Unknown interface type: %s\n", strings);
-
- return 1;
-}
-
-__setup("sonycd535=", sonycd535_setup);
-
-#endif /* MODULE */
-
-static void __exit
-sony535_exit(void)
-{
- int i;
-
- release_region(sony535_cd_base_io, 4);
- for (i = 0; i < sony_buffer_sectors; i++)
- kfree(sony_buffer[i]);
- kfree(sony_buffer);
- kfree(last_sony_subcode);
- kfree(sony_toc);
- del_gendisk(cdu_disk);
- put_disk(cdu_disk);
- blk_cleanup_queue(sonycd535_queue);
- if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
- printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
- else
- printk(KERN_INFO CDU535_HANDLE " module released\n");
-}
-
-module_init(sony535_init);
-module_exit(sony535_exit);
-
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR);
diff --git a/drivers/cdrom/sonycd535.h b/drivers/cdrom/sonycd535.h
deleted file mode 100644
index 5dea1ef168d6..000000000000
--- a/drivers/cdrom/sonycd535.h
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef SONYCD535_H
-#define SONYCD535_H
-
-/*
- * define all the commands recognized by the CDU-531/5
- */
-#define SONY535_REQUEST_DRIVE_STATUS_1 (0x80)
-#define SONY535_REQUEST_SENSE (0x82)
-#define SONY535_REQUEST_DRIVE_STATUS_2 (0x84)
-#define SONY535_REQUEST_ERROR_STATUS (0x86)
-#define SONY535_REQUEST_AUDIO_STATUS (0x88)
-#define SONY535_INQUIRY (0x8a)
-
-#define SONY535_SET_INACTIVITY_TIME (0x90)
-
-#define SONY535_SEEK_AND_READ_N_BLOCKS_1 (0xa0)
-#define SONY535_SEEK_AND_READ_N_BLOCKS_2 (0xa4)
-#define SONY535_PLAY_AUDIO (0xa6)
-
-#define SONY535_REQUEST_DISC_CAPACITY (0xb0)
-#define SONY535_REQUEST_TOC_DATA (0xb2)
-#define SONY535_REQUEST_SUB_Q_DATA (0xb4)
-#define SONY535_REQUEST_ISRC (0xb6)
-#define SONY535_REQUEST_UPC_EAN (0xb8)
-
-#define SONY535_SET_DRIVE_MODE (0xc0)
-#define SONY535_REQUEST_DRIVE_MODE (0xc2)
-#define SONY535_SET_RETRY_COUNT (0xc4)
-
-#define SONY535_DIAGNOSTIC_1 (0xc6)
-#define SONY535_DIAGNOSTIC_4 (0xcc)
-#define SONY535_DIAGNOSTIC_5 (0xce)
-
-#define SONY535_EJECT_CADDY (0xd0)
-#define SONY535_DISABLE_EJECT_BUTTON (0xd2)
-#define SONY535_ENABLE_EJECT_BUTTON (0xd4)
-
-#define SONY535_HOLD (0xe0)
-#define SONY535_AUDIO_PAUSE_ON_OFF (0xe2)
-#define SONY535_SET_VOLUME (0xe8)
-
-#define SONY535_STOP (0xf0)
-#define SONY535_SPIN_UP (0xf2)
-#define SONY535_SPIN_DOWN (0xf4)
-
-#define SONY535_CLEAR_PARAMETERS (0xf6)
-#define SONY535_CLEAR_ENDING_ADDRESS (0xf8)
-
-/*
- * define some masks
- */
-#define SONY535_DATA_NOT_READY_BIT (0x1)
-#define SONY535_RESULT_NOT_READY_BIT (0x2)
-
-/*
- * drive status 1
- */
-#define SONY535_STATUS1_COMMAND_ERROR (0x1)
-#define SONY535_STATUS1_DATA_ERROR (0x2)
-#define SONY535_STATUS1_SEEK_ERROR (0x4)
-#define SONY535_STATUS1_DISC_TYPE_ERROR (0x8)
-#define SONY535_STATUS1_NOT_SPINNING (0x10)
-#define SONY535_STATUS1_EJECT_BUTTON_PRESSED (0x20)
-#define SONY535_STATUS1_CADDY_NOT_INSERTED (0x40)
-#define SONY535_STATUS1_BYTE_TWO_FOLLOWS (0x80)
-
-/*
- * drive status 2
- */
-#define SONY535_CDD_LOADING_ERROR (0x7)
-#define SONY535_CDD_NO_DISC (0x8)
-#define SONY535_CDD_UNLOADING_ERROR (0x9)
-#define SONY535_CDD_CADDY_NOT_INSERTED (0xd)
-#define SONY535_ATN_RESET_OCCURRED (0x2)
-#define SONY535_ATN_DISC_CHANGED (0x4)
-#define SONY535_ATN_RESET_AND_DISC_CHANGED (0x6)
-#define SONY535_ATN_EJECT_IN_PROGRESS (0xe)
-#define SONY535_ATN_BUSY (0xf)
-
-/*
- * define some parameters
- */
-#define SONY535_AUDIO_DRIVE_MODE (0)
-#define SONY535_CDROM_DRIVE_MODE (0xe0)
-
-#define SONY535_PLAY_OP_PLAYBACK (0)
-#define SONY535_PLAY_OP_ENTER_HOLD (1)
-#define SONY535_PLAY_OP_SET_AUDIO_ENDING_ADDR (2)
-#define SONY535_PLAY_OP_SCAN_FORWARD (3)
-#define SONY535_PLAY_OP_SCAN_BACKWARD (4)
-
-/*
- * convert from msf format to block number
- */
-#define SONY_BLOCK_NUMBER(m,s,f) (((m)*60L+(s))*75L+(f))
-#define SONY_BLOCK_NUMBER_MSF(x) (((x)[0]*60L+(x)[1])*75L+(x)[2])
-
-/*
- * error return values from the doSonyCmd() routines
- */
-#define TIME_OUT (-1)
-#define NO_CDROM (-2)
-#define BAD_STATUS (-3)
-#define CD_BUSY (-4)
-#define NOT_DATA_CD (-5)
-#define NO_ROOM (-6)
-
-#define LOG_START_OFFSET 150 /* Offset of first logical sector */
-
-#define SONY_JIFFIES_TIMEOUT (5*HZ) /* Maximum time
- the drive will wait/try for an
- operation */
-#define SONY_READY_RETRIES (50000) /* How many times to retry a
- spin waiting for a register
- to come ready */
-#define SONY535_FAST_POLLS (10000) /* how many times recheck
- status waiting for a data
- to become ready */
-
-typedef unsigned char Byte;
-
-/*
- * This is the complete status returned from the drive configuration request
- * command.
- */
-struct s535_sony_drive_config
-{
- char vendor_id[8];
- char product_id[16];
- char product_rev_level[4];
-};
-
-/* The following is returned from the request sub-q data command */
-struct s535_sony_subcode
-{
- unsigned char address :4;
- unsigned char control :4;
- unsigned char track_num;
- unsigned char index_num;
- unsigned char rel_msf[3];
- unsigned char abs_msf[3];
-};
-
-struct s535_sony_disc_capacity
-{
- Byte mFirstTrack, sFirstTrack, fFirstTrack;
- Byte mLeadOut, sLeadOut, fLeadOut;
-};
-
-/*
- * The following is returned from the request TOC (Table Of Contents) command.
- * (last_track_num-first_track_num+1) values are valid in tracks.
- */
-struct s535_sony_toc
-{
- unsigned char reserved0 :4;
- unsigned char control0 :4;
- unsigned char point0;
- unsigned char first_track_num;
- unsigned char reserved0a;
- unsigned char reserved0b;
- unsigned char reserved1 :4;
- unsigned char control1 :4;
- unsigned char point1;
- unsigned char last_track_num;
- unsigned char dummy1;
- unsigned char dummy2;
- unsigned char reserved2 :4;
- unsigned char control2 :4;
- unsigned char point2;
- unsigned char lead_out_start_msf[3];
- struct
- {
- unsigned char reserved :4;
- unsigned char control :4;
- unsigned char track;
- unsigned char track_start_msf[3];
- } tracks[100];
-
- unsigned int lead_out_start_lba;
-};
-
-#endif /* SONYCD535_H */
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 1b094509b1d2..90965b4def5c 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1005,8 +1005,8 @@ static const unsigned short x86_keycodes[256] =
284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
- 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361,
- 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114,
+ 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
+ 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index cc9a9d0df979..bbee97ff355f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -24,7 +24,7 @@
#include <linux/crash_dump.h>
#include <linux/backing-dev.h>
#include <linux/bootmem.h>
-#include <linux/pipe_fs_i.h>
+#include <linux/splice.h>
#include <linux/pfn.h>
#include <asm/uaccess.h>
@@ -75,6 +75,13 @@ static inline int uncached_access(struct file *file, unsigned long addr)
* On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
*/
return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+#elif defined(CONFIG_MIPS)
+ {
+ extern int __uncached_access(struct file *file,
+ unsigned long addr);
+
+ return __uncached_access(file, addr);
+ }
#else
/*
* Accessing memory above the top the kernel knows about or through a file pointer
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 661c12f6dda6..7f4c0a5050a1 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -623,7 +623,8 @@ repeat:
cyl = track / disk->head;
#ifdef DEBUG
printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n",
- req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ",
+ req->rq_disk->disk_name,
+ req_data_dir(req) == READ ? "read" : "writ",
cyl, head, sec, nsect, req->buffer);
#endif
if (blk_fs_request(req)) {
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index be6b93c20f60..ab4b2d9b5327 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -30,6 +30,7 @@ struct evdev {
wait_queue_head_t wait;
struct evdev_client *grab;
struct list_head client_list;
+ struct device dev;
};
struct evdev_client {
@@ -94,8 +95,10 @@ static int evdev_flush(struct file *file, fl_owner_t id)
return input_flush_device(&evdev->handle, file);
}
-static void evdev_free(struct evdev *evdev)
+static void evdev_free(struct device *dev)
{
+ struct evdev *evdev = container_of(dev, struct evdev, dev);
+
evdev_table[evdev->minor] = NULL;
kfree(evdev);
}
@@ -114,12 +117,10 @@ static int evdev_release(struct inode *inode, struct file *file)
list_del(&client->node);
kfree(client);
- if (!--evdev->open) {
- if (evdev->exist)
- input_close_device(&evdev->handle);
- else
- evdev_free(evdev);
- }
+ if (!--evdev->open && evdev->exist)
+ input_close_device(&evdev->handle);
+
+ put_device(&evdev->dev);
return 0;
}
@@ -139,24 +140,32 @@ static int evdev_open(struct inode *inode, struct file *file)
if (!evdev || !evdev->exist)
return -ENODEV;
+ get_device(&evdev->dev);
+
client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
+ if (!client) {
+ error = -ENOMEM;
+ goto err_put_evdev;
+ }
client->evdev = evdev;
list_add_tail(&client->node, &evdev->client_list);
if (!evdev->open++ && evdev->exist) {
error = input_open_device(&evdev->handle);
- if (error) {
- list_del(&client->node);
- kfree(client);
- return error;
- }
+ if (error)
+ goto err_free_client;
}
file->private_data = client;
return 0;
+
+ err_free_client:
+ list_del(&client->node);
+ kfree(client);
+ err_put_evdev:
+ put_device(&evdev->dev);
+ return error;
}
#ifdef CONFIG_COMPAT
@@ -625,8 +634,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct evdev *evdev;
- struct class_device *cdev;
- dev_t devt;
int minor;
int error;
@@ -649,38 +656,32 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
evdev->handle.name = evdev->name;
evdev->handle.handler = handler;
evdev->handle.private = evdev;
- sprintf(evdev->name, "event%d", minor);
-
- evdev_table[minor] = evdev;
+ snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
- devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+ snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
+ "event%d", minor);
+ evdev->dev.class = &input_class;
+ evdev->dev.parent = &dev->dev;
+ evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
+ evdev->dev.release = evdev_free;
+ device_initialize(&evdev->dev);
- cdev = class_device_create(&input_class, &dev->cdev, devt,
- dev->cdev.dev, evdev->name);
- if (IS_ERR(cdev)) {
- error = PTR_ERR(cdev);
- goto err_free_evdev;
- }
+ evdev_table[minor] = evdev;
- /* temporary symlink to keep userspace happy */
- error = sysfs_create_link(&input_class.subsys.kobj,
- &cdev->kobj, evdev->name);
+ error = device_add(&evdev->dev);
if (error)
- goto err_cdev_destroy;
+ goto err_free_evdev;
error = input_register_handle(&evdev->handle);
if (error)
- goto err_remove_link;
+ goto err_delete_evdev;
return 0;
- err_remove_link:
- sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
- err_cdev_destroy:
- class_device_destroy(&input_class, devt);
+ err_delete_evdev:
+ device_del(&evdev->dev);
err_free_evdev:
- kfree(evdev);
- evdev_table[minor] = NULL;
+ put_device(&evdev->dev);
return error;
}
@@ -690,10 +691,8 @@ static void evdev_disconnect(struct input_handle *handle)
struct evdev_client *client;
input_unregister_handle(handle);
+ device_del(&evdev->dev);
- sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
- class_device_destroy(&input_class,
- MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
evdev->exist = 0;
if (evdev->open) {
@@ -702,8 +701,9 @@ static void evdev_disconnect(struct input_handle *handle)
list_for_each_entry(client, &evdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&evdev->wait);
- } else
- evdev_free(evdev);
+ }
+
+ put_device(&evdev->dev);
}
static const struct input_device_id evdev_ids[] = {
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ccd8abafcb70..75b4d2a83dd9 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -442,7 +442,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
printk(KERN_ERR
"input: failed to attach handler %s to device %s, "
"error: %d\n",
- handler->name, kobject_name(&dev->cdev.kobj), error);
+ handler->name, kobject_name(&dev->dev.kobj), error);
return error;
}
@@ -527,7 +527,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
static int input_devices_seq_show(struct seq_file *seq, void *v)
{
struct input_dev *dev = container_of(v, struct input_dev, node);
- const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+ const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
struct input_handle *handle;
seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
@@ -682,15 +682,17 @@ static inline int input_proc_init(void) { return 0; }
static inline void input_proc_exit(void) { }
#endif
-#define INPUT_DEV_STRING_ATTR_SHOW(name) \
-static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \
-{ \
- struct input_dev *input_dev = to_input_dev(dev); \
- \
- return scnprintf(buf, PAGE_SIZE, "%s\n", \
- input_dev->name ? input_dev->name : ""); \
-} \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
+#define INPUT_DEV_STRING_ATTR_SHOW(name) \
+static ssize_t input_dev_show_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct input_dev *input_dev = to_input_dev(dev); \
+ \
+ return scnprintf(buf, PAGE_SIZE, "%s\n", \
+ input_dev->name ? input_dev->name : ""); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL)
INPUT_DEV_STRING_ATTR_SHOW(name);
INPUT_DEV_STRING_ATTR_SHOW(phys);
@@ -744,7 +746,9 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id,
return len;
}
-static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
+static ssize_t input_dev_show_modalias(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
struct input_dev *id = to_input_dev(dev);
ssize_t len;
@@ -753,13 +757,13 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
return min_t(int, len, PAGE_SIZE);
}
-static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
static struct attribute *input_dev_attrs[] = {
- &class_device_attr_name.attr,
- &class_device_attr_phys.attr,
- &class_device_attr_uniq.attr,
- &class_device_attr_modalias.attr,
+ &dev_attr_name.attr,
+ &dev_attr_phys.attr,
+ &dev_attr_uniq.attr,
+ &dev_attr_modalias.attr,
NULL
};
@@ -767,13 +771,15 @@ static struct attribute_group input_dev_attr_group = {
.attrs = input_dev_attrs,
};
-#define INPUT_DEV_ID_ATTR(name) \
-static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \
-{ \
- struct input_dev *input_dev = to_input_dev(dev); \
- return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
-} \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
+#define INPUT_DEV_ID_ATTR(name) \
+static ssize_t input_dev_show_id_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct input_dev *input_dev = to_input_dev(dev); \
+ return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL)
INPUT_DEV_ID_ATTR(bustype);
INPUT_DEV_ID_ATTR(vendor);
@@ -781,10 +787,10 @@ INPUT_DEV_ID_ATTR(product);
INPUT_DEV_ID_ATTR(version);
static struct attribute *input_dev_id_attrs[] = {
- &class_device_attr_bustype.attr,
- &class_device_attr_vendor.attr,
- &class_device_attr_product.attr,
- &class_device_attr_version.attr,
+ &dev_attr_bustype.attr,
+ &dev_attr_vendor.attr,
+ &dev_attr_product.attr,
+ &dev_attr_version.attr,
NULL
};
@@ -813,15 +819,17 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
return len;
}
-#define INPUT_DEV_CAP_ATTR(ev, bm) \
-static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \
-{ \
- struct input_dev *input_dev = to_input_dev(dev); \
- int len = input_print_bitmap(buf, PAGE_SIZE, \
- input_dev->bm##bit, ev##_MAX, 1); \
- return min_t(int, len, PAGE_SIZE); \
-} \
-static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
+#define INPUT_DEV_CAP_ATTR(ev, bm) \
+static ssize_t input_dev_show_cap_##bm(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct input_dev *input_dev = to_input_dev(dev); \
+ int len = input_print_bitmap(buf, PAGE_SIZE, \
+ input_dev->bm##bit, ev##_MAX, 1); \
+ return min_t(int, len, PAGE_SIZE); \
+} \
+static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
INPUT_DEV_CAP_ATTR(EV, ev);
INPUT_DEV_CAP_ATTR(KEY, key);
@@ -834,15 +842,15 @@ INPUT_DEV_CAP_ATTR(FF, ff);
INPUT_DEV_CAP_ATTR(SW, sw);
static struct attribute *input_dev_caps_attrs[] = {
- &class_device_attr_ev.attr,
- &class_device_attr_key.attr,
- &class_device_attr_rel.attr,
- &class_device_attr_abs.attr,
- &class_device_attr_msc.attr,
- &class_device_attr_led.attr,
- &class_device_attr_snd.attr,
- &class_device_attr_ff.attr,
- &class_device_attr_sw.attr,
+ &dev_attr_ev.attr,
+ &dev_attr_key.attr,
+ &dev_attr_rel.attr,
+ &dev_attr_abs.attr,
+ &dev_attr_msc.attr,
+ &dev_attr_led.attr,
+ &dev_attr_snd.attr,
+ &dev_attr_ff.attr,
+ &dev_attr_sw.attr,
NULL
};
@@ -858,9 +866,9 @@ static struct attribute_group *input_dev_attr_groups[] = {
NULL
};
-static void input_dev_release(struct class_device *class_dev)
+static void input_dev_release(struct device *device)
{
- struct input_dev *dev = to_input_dev(class_dev);
+ struct input_dev *dev = to_input_dev(device);
input_ff_destroy(dev);
kfree(dev);
@@ -947,10 +955,10 @@ static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_ind
return err; \
} while (0)
-static int input_dev_uevent(struct class_device *cdev, char **envp,
+static int input_dev_uevent(struct device *device, char **envp,
int num_envp, char *buffer, int buffer_size)
{
- struct input_dev *dev = to_input_dev(cdev);
+ struct input_dev *dev = to_input_dev(device);
int i = 0;
int len = 0;
@@ -988,10 +996,14 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
return 0;
}
+static struct device_type input_dev_type = {
+ .groups = input_dev_attr_groups,
+ .release = input_dev_release,
+ .uevent = input_dev_uevent,
+};
+
struct class input_class = {
- .name = "input",
- .release = input_dev_release,
- .uevent = input_dev_uevent,
+ .name = "input",
};
EXPORT_SYMBOL_GPL(input_class);
@@ -1010,9 +1022,9 @@ struct input_dev *input_allocate_device(void)
dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
if (dev) {
- dev->cdev.class = &input_class;
- dev->cdev.groups = input_dev_attr_groups;
- class_device_initialize(&dev->cdev);
+ dev->dev.type = &input_dev_type;
+ dev->dev.class = &input_class;
+ device_initialize(&dev->dev);
mutex_init(&dev->mutex);
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
@@ -1131,17 +1143,17 @@ int input_register_device(struct input_dev *dev)
list_add_tail(&dev->node, &input_dev_list);
- snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+ snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
- if (!dev->cdev.dev)
- dev->cdev.dev = dev->dev.parent;
+ if (dev->cdev.dev)
+ dev->dev.parent = dev->cdev.dev;
- error = class_device_add(&dev->cdev);
+ error = device_add(&dev->dev);
if (error)
return error;
- path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+ path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s as %s\n",
dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
kfree(path);
@@ -1173,7 +1185,7 @@ void input_unregister_device(struct input_dev *dev)
list_del_init(&dev->node);
- class_device_unregister(&dev->cdev);
+ device_unregister(&dev->dev);
input_wakeup_procfs_readers();
}
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 10e3b7bc925f..a9a0180bfd46 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -43,6 +43,8 @@ struct joydev {
struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
+ struct device dev;
+
struct js_corr corr[ABS_MAX + 1];
struct JS_DATA_SAVE_TYPE glue;
int nabs;
@@ -138,8 +140,10 @@ static int joydev_fasync(int fd, struct file *file, int on)
return retval < 0 ? retval : 0;
}
-static void joydev_free(struct joydev *joydev)
+static void joydev_free(struct device *dev)
{
+ struct joydev *joydev = container_of(dev, struct joydev, dev);
+
joydev_table[joydev->minor] = NULL;
kfree(joydev);
}
@@ -154,12 +158,10 @@ static int joydev_release(struct inode *inode, struct file *file)
list_del(&client->node);
kfree(client);
- if (!--joydev->open) {
- if (joydev->exist)
- input_close_device(&joydev->handle);
- else
- joydev_free(joydev);
- }
+ if (!--joydev->open && joydev->exist)
+ input_close_device(&joydev->handle);
+
+ put_device(&joydev->dev);
return 0;
}
@@ -178,24 +180,32 @@ static int joydev_open(struct inode *inode, struct file *file)
if (!joydev || !joydev->exist)
return -ENODEV;
+ get_device(&joydev->dev);
+
client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
+ if (!client) {
+ error = -ENOMEM;
+ goto err_put_joydev;
+ }
client->joydev = joydev;
list_add_tail(&client->node, &joydev->client_list);
if (!joydev->open++ && joydev->exist) {
error = input_open_device(&joydev->handle);
- if (error) {
- list_del(&client->node);
- kfree(client);
- return error;
- }
+ if (error)
+ goto err_free_client;
}
file->private_data = client;
return 0;
+
+ err_free_client:
+ list_del(&client->node);
+ kfree(client);
+ err_put_joydev:
+ put_device(&joydev->dev);
+ return error;
}
static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -481,8 +491,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct joydev *joydev;
- struct class_device *cdev;
- dev_t devt;
int i, j, t, minor;
int error;
@@ -505,7 +513,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
joydev->handle.name = joydev->name;
joydev->handle.handler = handler;
joydev->handle.private = joydev;
- sprintf(joydev->name, "js%d", minor);
+ snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
for (i = 0; i < ABS_MAX + 1; i++)
if (test_bit(i, dev->absbit)) {
@@ -547,36 +555,30 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
}
- joydev_table[minor] = joydev;
-
- devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+ snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id),
+ "js%d", minor);
+ joydev->dev.class = &input_class;
+ joydev->dev.parent = &dev->dev;
+ joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
+ joydev->dev.release = joydev_free;
+ device_initialize(&joydev->dev);
- cdev = class_device_create(&input_class, &dev->cdev, devt,
- dev->cdev.dev, joydev->name);
- if (IS_ERR(cdev)) {
- error = PTR_ERR(cdev);
- goto err_free_joydev;
- }
+ joydev_table[minor] = joydev;
- /* temporary symlink to keep userspace happy */
- error = sysfs_create_link(&input_class.subsys.kobj,
- &cdev->kobj, joydev->name);
+ error = device_add(&joydev->dev);
if (error)
- goto err_cdev_destroy;
+ goto err_free_joydev;
error = input_register_handle(&joydev->handle);
if (error)
- goto err_remove_link;
+ goto err_delete_joydev;
return 0;
- err_remove_link:
- sysfs_remove_link(&input_class.subsys.kobj, joydev->name);
- err_cdev_destroy:
- class_device_destroy(&input_class, devt);
+ err_delete_joydev:
+ device_del(&joydev->dev);
err_free_joydev:
- joydev_table[minor] = NULL;
- kfree(joydev);
+ put_device(&joydev->dev);
return error;
}
@@ -587,9 +589,8 @@ static void joydev_disconnect(struct input_handle *handle)
struct joydev_client *client;
input_unregister_handle(handle);
+ device_del(&joydev->dev);
- sysfs_remove_link(&input_class.subsys.kobj, joydev->name);
- class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
joydev->exist = 0;
if (joydev->open) {
@@ -597,8 +598,9 @@ static void joydev_disconnect(struct input_handle *handle)
list_for_each_entry(client, &joydev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&joydev->wait);
- } else
- joydev_free(joydev);
+ }
+
+ put_device(&joydev->dev);
}
static const struct input_device_id joydev_blacklist[] = {
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index b0023452ec90..12db72d83ea0 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -268,4 +268,11 @@ config JOYSTICK_XPAD
To compile this driver as a module, choose M here: the
module will be called xpad.
+config JOYSTICK_XPAD_FF
+ bool "X-Box gamepad rumble support"
+ depends on JOYSTICK_XPAD && INPUT
+ select INPUT_FF_MEMLESS
+ ---help---
+ Say Y here if you want to take advantage of xbox 360 rumble features.
+
endif
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 555319e6378c..4ed3a3eadf19 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -320,10 +320,10 @@ static int multiport_io(struct gameport* gameport, int sendflags, int sendcode,
static int dig_mode_start(struct gameport *gameport, u32 *packet)
{
- int i, seq_len = sizeof(init_seq)/sizeof(int);
+ int i;
int flags, tries = 0, bads = 0;
- for (i = 0; i < seq_len; i++) { /* Send magic sequence */
+ for (i = 0; i < ARRAY_SIZE(init_seq); i++) { /* Send magic sequence */
if (init_seq[i])
gameport_trigger(gameport);
udelay(GRIP_INIT_DELAY);
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 8c8cd95a6989..244089c52650 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -8,6 +8,7 @@
* Ivan Hawkes <blackhawk@ivanhawkes.com>
* 2005 Dominic Cerquetti <binary1230@yahoo.com>
* 2006 Adam Buchbinder <adam.buchbinder@gmail.com>
+ * 2007 Jan Kratochvil <honza@jikos.cz>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -28,6 +29,7 @@
* - information from http://euc.jp/periphs/xbox-controller.ja.html
* - the iForce driver drivers/char/joystick/iforce.c
* - the skeleton-driver drivers/usb/usb-skeleton.c
+ * - Xbox 360 information http://www.free60.org/wiki/Gamepad
*
* Thanks to:
* - ITO Takayuki for providing essential xpad information on his website
@@ -88,6 +90,9 @@
#define MAP_DPAD_TO_AXES 1
#define MAP_DPAD_UNKNOWN -1
+#define XTYPE_XBOX 0
+#define XTYPE_XBOX360 1
+
static int dpad_to_buttons;
module_param(dpad_to_buttons, bool, S_IRUGO);
MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
@@ -97,40 +102,42 @@ static const struct xpad_device {
u16 idProduct;
char *name;
u8 dpad_mapping;
+ u8 xtype;
} xpad_device[] = {
- { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES },
- { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES },
- { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES },
- { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES },
- { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS },
- { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES },
- { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES },
- { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES },
- { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES },
- { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS },
- { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS },
- { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
- { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
- { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES },
- { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES },
- { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES},
- { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES },
- { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES },
- { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES },
- { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES },
- { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS },
- { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS },
- { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES },
- { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN }
+ { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+ { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+ { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX }
};
static const signed short xpad_btn[] = {
@@ -146,6 +153,12 @@ static const signed short xpad_btn_pad[] = {
-1 /* terminating entry */
};
+static const signed short xpad360_btn[] = { /* buttons for x360 controller */
+ BTN_TL, BTN_TR, /* Button LB/RB */
+ BTN_MODE, /* The big X button */
+ -1
+};
+
static const signed short xpad_abs[] = {
ABS_X, ABS_Y, /* left stick */
ABS_RX, ABS_RY, /* right stick */
@@ -159,8 +172,12 @@ static const signed short xpad_abs_pad[] = {
-1 /* terminating entry */
};
+/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only
+ * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols,
+ * but we need only one of them. */
static struct usb_device_id xpad_table [] = {
{ USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
+ { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */
{ }
};
@@ -174,9 +191,16 @@ struct usb_xpad {
unsigned char *idata; /* input data */
dma_addr_t idata_dma;
+#ifdef CONFIG_JOYSTICK_XPAD_FF
+ struct urb *irq_out; /* urb for interrupt out report */
+ unsigned char *odata; /* output data */
+ dma_addr_t odata_dma;
+#endif
+
char phys[65]; /* physical device path */
int dpad_mapping; /* map d-pad to buttons or to axes */
+ int xtype; /* type of xbox device */
};
/*
@@ -212,8 +236,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
} else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
input_report_key(dev, BTN_LEFT, data[2] & 0x04);
input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
- input_report_key(dev, BTN_0, data[2] & 0x01); // up
- input_report_key(dev, BTN_1, data[2] & 0x02); // down
+ input_report_key(dev, BTN_0, data[2] & 0x01); /* up */
+ input_report_key(dev, BTN_1, data[2] & 0x02); /* down */
}
/* start/back buttons and stick press left/right */
@@ -235,6 +259,64 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
input_sync(dev);
}
+/*
+ * xpad360_process_packet
+ *
+ * Completes a request by converting the data into events for the
+ * input subsystem. It is version for xbox 360 controller
+ *
+ * The used report descriptor was taken from:
+ * http://www.free60.org/wiki/Gamepad
+ */
+
+static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
+{
+ struct input_dev *dev = xpad->dev;
+
+ /* digital pad */
+ if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
+ input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
+ input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
+ } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) {
+ /* dpad as buttons (right, left, down, up) */
+ input_report_key(dev, BTN_LEFT, data[2] & 0x04);
+ input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
+ input_report_key(dev, BTN_0, data[2] & 0x01); /* up */
+ input_report_key(dev, BTN_1, data[2] & 0x02); /* down */
+ }
+
+ /* start/back buttons */
+ input_report_key(dev, BTN_START, data[2] & 0x10);
+ input_report_key(dev, BTN_BACK, data[2] & 0x20);
+
+ /* stick press left/right */
+ input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
+ input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
+
+ /* buttons A,B,X,Y,TL,TR and MODE */
+ input_report_key(dev, BTN_A, data[3] & 0x10);
+ input_report_key(dev, BTN_B, data[3] & 0x20);
+ input_report_key(dev, BTN_X, data[3] & 0x40);
+ input_report_key(dev, BTN_Y, data[3] & 0x80);
+ input_report_key(dev, BTN_TL, data[3] & 0x01);
+ input_report_key(dev, BTN_TR, data[3] & 0x02);
+ input_report_key(dev, BTN_MODE, data[3] & 0x04);
+
+ /* left stick */
+ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6]));
+ input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[9] << 8) | (__s16)data[8]));
+
+ /* right stick */
+ input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10]));
+ input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[13] << 8) | (__s16)data[12]));
+
+ /* triggers left/right */
+ input_report_abs(dev, ABS_Z, data[4]);
+ input_report_abs(dev, ABS_RZ, data[5]);
+
+ input_sync(dev);
+}
+
static void xpad_irq_in(struct urb *urb)
{
struct usb_xpad *xpad = urb->context;
@@ -255,7 +337,10 @@ static void xpad_irq_in(struct urb *urb)
goto exit;
}
- xpad_process_packet(xpad, 0, xpad->idata);
+ if (xpad->xtype == XTYPE_XBOX360)
+ xpad360_process_packet(xpad, 0, xpad->idata);
+ else
+ xpad_process_packet(xpad, 0, xpad->idata);
exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
@@ -264,7 +349,114 @@ exit:
__FUNCTION__, retval);
}
-static int xpad_open (struct input_dev *dev)
+#ifdef CONFIG_JOYSTICK_XPAD_FF
+static void xpad_irq_out(struct urb *urb)
+{
+ int retval;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+ goto exit;
+ }
+
+exit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err("%s - usb_submit_urb failed with result %d",
+ __FUNCTION__, retval);
+}
+
+static int xpad_play_effect(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct usb_xpad *xpad = input_get_drvdata(dev);
+
+ if (effect->type == FF_RUMBLE) {
+ __u16 strong = effect->u.rumble.strong_magnitude;
+ __u16 weak = effect->u.rumble.weak_magnitude;
+ xpad->odata[0] = 0x00;
+ xpad->odata[1] = 0x08;
+ xpad->odata[2] = 0x00;
+ xpad->odata[3] = strong / 256;
+ xpad->odata[4] = weak / 256;
+ xpad->odata[5] = 0x00;
+ xpad->odata[6] = 0x00;
+ xpad->odata[7] = 0x00;
+ usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+ }
+
+ return 0;
+}
+
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
+{
+ struct usb_endpoint_descriptor *ep_irq_out;
+ int error = -ENOMEM;
+
+ if (xpad->xtype != XTYPE_XBOX360)
+ return 0;
+
+ xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
+ GFP_ATOMIC, &xpad->odata_dma );
+ if (!xpad->odata)
+ goto fail1;
+
+ xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
+ if (!xpad->irq_out)
+ goto fail2;
+
+ ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
+ usb_fill_int_urb(xpad->irq_out, xpad->udev,
+ usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
+ xpad->odata, XPAD_PKT_LEN,
+ xpad_irq_out, xpad, ep_irq_out->bInterval);
+ xpad->irq_out->transfer_dma = xpad->odata_dma;
+ xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
+
+ error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
+ if (error)
+ goto fail2;
+
+ return 0;
+
+ fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
+ fail1: return error;
+}
+
+static void xpad_stop_ff(struct usb_xpad *xpad)
+{
+ if (xpad->xtype == XTYPE_XBOX360)
+ usb_kill_urb(xpad->irq_out);
+}
+
+static void xpad_deinit_ff(struct usb_xpad *xpad)
+{
+ if (xpad->xtype == XTYPE_XBOX360) {
+ usb_free_urb(xpad->irq_out);
+ usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
+ xpad->odata, xpad->odata_dma);
+ }
+}
+
+#else
+static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
+static void xpad_stop_ff(struct usb_xpad *xpad) { }
+static void xpad_deinit_ff(struct usb_xpad *xpad) { }
+#endif
+
+static int xpad_open(struct input_dev *dev)
{
struct usb_xpad *xpad = input_get_drvdata(dev);
@@ -275,11 +467,12 @@ static int xpad_open (struct input_dev *dev)
return 0;
}
-static void xpad_close (struct input_dev *dev)
+static void xpad_close(struct input_dev *dev)
{
struct usb_xpad *xpad = input_get_drvdata(dev);
usb_kill_urb(xpad->irq_in);
+ xpad_stop_ff(xpad);
}
static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
@@ -335,6 +528,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->udev = udev;
xpad->dpad_mapping = xpad_device[i].dpad_mapping;
+ xpad->xtype = xpad_device[i].xtype;
if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
xpad->dpad_mapping = dpad_to_buttons;
xpad->dev = input_dev;
@@ -356,6 +550,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
/* set up buttons */
for (i = 0; xpad_btn[i] >= 0; i++)
set_bit(xpad_btn[i], input_dev->keybit);
+ if (xpad->xtype == XTYPE_XBOX360)
+ for (i = 0; xpad360_btn[i] >= 0; i++)
+ set_bit(xpad360_btn[i], input_dev->keybit);
if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
for (i = 0; xpad_btn_pad[i] >= 0; i++)
set_bit(xpad_btn_pad[i], input_dev->keybit);
@@ -367,6 +564,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
for (i = 0; xpad_abs_pad[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
+ error = xpad_init_ff(intf, xpad);
+ if (error)
+ goto fail2;
+
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
@@ -396,10 +597,10 @@ static void xpad_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (xpad) {
- usb_kill_urb(xpad->irq_in);
input_unregister_device(xpad->dev);
+ xpad_deinit_ff(xpad);
usb_free_urb(xpad->irq_in);
- usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+ usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
xpad->idata, xpad->idata_dma);
kfree(xpad);
}
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 9950fcb33650..41fc3d03b6eb 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -89,7 +89,7 @@ static unsigned char atkbd_set2_keycode[512] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
- 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142,
+ 159, 0,115, 0,164, 0, 0,116,158, 0,172,166, 0, 0, 0,142,
157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
@@ -111,7 +111,7 @@ static unsigned char atkbd_set3_keycode[512] = {
82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183,
184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0,
- 0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168,
+ 0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168,
148,149,147,140
};
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c
index f9e82c9ca421..ebe5eacf2990 100644
--- a/drivers/input/keyboard/pxa27x_keyboard.c
+++ b/drivers/input/keyboard/pxa27x_keyboard.c
@@ -140,7 +140,7 @@ static int pxakbd_resume(struct platform_device *pdev)
KPREC = pdata->reg_kprec;
/* Enable unit clock */
- pxa_set_cken(CKEN19_KEYPAD, 1);
+ pxa_set_cken(CKEN_KEYPAD, 1);
}
mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 88e29074ac90..9b26574f1466 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -65,9 +65,13 @@ config INPUT_COBALT_BTNS
config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface"
depends on X86 && !X86_64
+ select INPUT_POLLDEV
+ select NEW_LEDS
+ select LEDS_CLASS
help
Say Y here for support of Winstron laptop button interface, used on
- laptops of various brands, including Acer and Fujitsu-Siemens.
+ laptops of various brands, including Acer and Fujitsu-Siemens. If
+ available, mail and wifi leds will be controlable via /sys/class/leds.
To compile this driver as a module, choose M here: the module will
be called wistron_btns.
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 961aad7a0476..60121f10f8d9 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -20,37 +20,31 @@
#include <linux/io.h>
#include <linux/dmi.h>
#include <linux/init.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
#include <linux/interrupt.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mc146818rtc.h>
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/string.h>
-#include <linux/timer.h>
#include <linux/types.h>
#include <linux/platform_device.h>
+#include <linux/leds.h>
-/*
- * Number of attempts to read data from queue per poll;
- * the queue can hold up to 31 entries
- */
-#define MAX_POLL_ITERATIONS 64
-
-#define POLL_FREQUENCY 10 /* Number of polls per second */
-
-#if POLL_FREQUENCY > HZ
-#error "POLL_FREQUENCY too high"
-#endif
+/* How often we poll keys - msecs */
+#define POLL_INTERVAL_DEFAULT 500 /* when idle */
+#define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */
/* BIOS subsystem IDs */
#define WIFI 0x35
#define BLUETOOTH 0x34
+#define MAIL_LED 0x31
MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
MODULE_DESCRIPTION("Wistron laptop button driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION("0.2");
+MODULE_VERSION("0.3");
static int force; /* = 0; */
module_param(force, bool, 0);
@@ -248,9 +242,10 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
#define FE_WIFI_LED 0x02
#define FE_UNTESTED 0x80
-static const struct key_entry *keymap; /* = NULL; Current key map */
+static struct key_entry *keymap; /* = NULL; Current key map */
static int have_wifi;
static int have_bluetooth;
+static int have_leds;
static int __init dmi_matched(struct dmi_system_id *dmi)
{
@@ -263,6 +258,8 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
else if (key->type == KE_BLUETOOTH)
have_bluetooth = 1;
}
+ have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);
+
return 1;
}
@@ -966,118 +963,163 @@ static int __init select_keymap(void)
/* Input layer interface */
-static struct input_dev *input_dev;
+static struct input_polled_dev *wistron_idev;
+static unsigned long jiffies_last_press;
+static int wifi_enabled;
+static int bluetooth_enabled;
-static int __devinit setup_input_dev(void)
+static void report_key(struct input_dev *dev, unsigned int keycode)
{
- const struct key_entry *key;
- int error;
+ input_report_key(dev, keycode, 1);
+ input_sync(dev);
+ input_report_key(dev, keycode, 0);
+ input_sync(dev);
+}
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
+static void report_switch(struct input_dev *dev, unsigned int code, int value)
+{
+ input_report_switch(dev, code, value);
+ input_sync(dev);
+}
- input_dev->name = "Wistron laptop buttons";
- input_dev->phys = "wistron/input0";
- input_dev->id.bustype = BUS_HOST;
- input_dev->cdev.dev = &wistron_device->dev;
- for (key = keymap; key->type != KE_END; key++) {
- switch (key->type) {
- case KE_KEY:
- set_bit(EV_KEY, input_dev->evbit);
- set_bit(key->keycode, input_dev->keybit);
- break;
+ /* led management */
+static void wistron_mail_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0);
+}
- case KE_SW:
- set_bit(EV_SW, input_dev->evbit);
- set_bit(key->sw.code, input_dev->swbit);
- break;
+/* same as setting up wifi card, but for laptops on which the led is managed */
+static void wistron_wifi_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0);
+}
- default:
- ;
- }
- }
+static struct led_classdev wistron_mail_led = {
+ .name = "mail:green",
+ .brightness_set = wistron_mail_led_set,
+};
- /* reads information flags on KE_END */
- if (key->code & FE_UNTESTED)
- printk(KERN_WARNING "Untested laptop multimedia keys, "
- "please report success or failure to eric.piel"
- "@tremplin-utc.net\n");
+static struct led_classdev wistron_wifi_led = {
+ .name = "wifi:red",
+ .brightness_set = wistron_wifi_led_set,
+};
- error = input_register_device(input_dev);
- if (error) {
- input_free_device(input_dev);
- return error;
+static void __devinit wistron_led_init(struct device *parent)
+{
+ if (have_leds & FE_WIFI_LED) {
+ u16 wifi = bios_get_default_setting(WIFI);
+ if (wifi & 1) {
+ wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
+ if (led_classdev_register(parent, &wistron_wifi_led))
+ have_leds &= ~FE_WIFI_LED;
+ else
+ bios_set_state(WIFI, wistron_wifi_led.brightness);
+
+ } else
+ have_leds &= ~FE_WIFI_LED;
}
- return 0;
+ if (have_leds & FE_MAIL_LED) {
+ /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
+ wistron_mail_led.brightness = LED_OFF;
+ if (led_classdev_register(parent, &wistron_mail_led))
+ have_leds &= ~FE_MAIL_LED;
+ else
+ bios_set_state(MAIL_LED, wistron_mail_led.brightness);
+ }
}
-static void report_key(unsigned keycode)
+static void __devexit wistron_led_remove(void)
{
- input_report_key(input_dev, keycode, 1);
- input_sync(input_dev);
- input_report_key(input_dev, keycode, 0);
- input_sync(input_dev);
+ if (have_leds & FE_MAIL_LED)
+ led_classdev_unregister(&wistron_mail_led);
+
+ if (have_leds & FE_WIFI_LED)
+ led_classdev_unregister(&wistron_wifi_led);
}
-static void report_switch(unsigned code, int value)
+static inline void wistron_led_suspend(void)
{
- input_report_switch(input_dev, code, value);
- input_sync(input_dev);
+ if (have_leds & FE_MAIL_LED)
+ led_classdev_suspend(&wistron_mail_led);
+
+ if (have_leds & FE_WIFI_LED)
+ led_classdev_suspend(&wistron_wifi_led);
}
- /* Driver core */
+static inline void wistron_led_resume(void)
+{
+ if (have_leds & FE_MAIL_LED)
+ led_classdev_resume(&wistron_mail_led);
-static int wifi_enabled;
-static int bluetooth_enabled;
+ if (have_leds & FE_WIFI_LED)
+ led_classdev_resume(&wistron_wifi_led);
+}
+
+static struct key_entry *wistron_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
-static void poll_bios(unsigned long);
+ for (key = keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
-static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
+ return NULL;
+}
-static void handle_key(u8 code)
+static struct key_entry *wistron_get_entry_by_keycode(int keycode)
{
- const struct key_entry *key;
+ struct key_entry *key;
- for (key = keymap; key->type != KE_END; key++) {
- if (code == key->code) {
- switch (key->type) {
- case KE_KEY:
- report_key(key->keycode);
- break;
+ for (key = keymap; key->type != KE_END; key++)
+ if (key->type == KE_KEY && keycode == key->keycode)
+ return key;
- case KE_SW:
- report_switch(key->sw.code, key->sw.value);
- break;
+ return NULL;
+}
- case KE_WIFI:
- if (have_wifi) {
- wifi_enabled = !wifi_enabled;
- bios_set_state(WIFI, wifi_enabled);
- }
- break;
+static void handle_key(u8 code)
+{
+ const struct key_entry *key = wistron_get_entry_by_scancode(code);
- case KE_BLUETOOTH:
- if (have_bluetooth) {
- bluetooth_enabled = !bluetooth_enabled;
- bios_set_state(BLUETOOTH, bluetooth_enabled);
- }
- break;
+ if (key) {
+ switch (key->type) {
+ case KE_KEY:
+ report_key(wistron_idev->input, key->keycode);
+ break;
- case KE_END:
- break;
- default:
- BUG();
+ case KE_SW:
+ report_switch(wistron_idev->input,
+ key->sw.code, key->sw.value);
+ break;
+
+ case KE_WIFI:
+ if (have_wifi) {
+ wifi_enabled = !wifi_enabled;
+ bios_set_state(WIFI, wifi_enabled);
+ }
+ break;
+
+ case KE_BLUETOOTH:
+ if (have_bluetooth) {
+ bluetooth_enabled = !bluetooth_enabled;
+ bios_set_state(BLUETOOTH, bluetooth_enabled);
}
- return;
+ break;
+
+ default:
+ BUG();
}
- }
- printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
+ jiffies_last_press = jiffies;
+ } else
+ printk(KERN_NOTICE
+ "wistron_btns: Unknown key code %02X\n", code);
}
-static void poll_bios(unsigned long discard)
+static void poll_bios(bool discard)
{
u8 qlen;
u16 val;
@@ -1090,15 +1132,118 @@ static void poll_bios(unsigned long discard)
if (val != 0 && !discard)
handle_key((u8)val);
}
+}
+
+static void wistron_flush(struct input_polled_dev *dev)
+{
+ /* Flush stale event queue */
+ poll_bios(true);
+}
+
+static void wistron_poll(struct input_polled_dev *dev)
+{
+ poll_bios(false);
+
+ /* Increase poll frequency if user is currently pressing keys (< 2s ago) */
+ if (time_before(jiffies, jiffies_last_press + 2 * HZ))
+ dev->poll_interval = POLL_INTERVAL_BURST;
+ else
+ dev->poll_interval = POLL_INTERVAL_DEFAULT;
+}
+
+static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+ const struct key_entry *key = wistron_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = wistron_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!wistron_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
- mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
+ return -EINVAL;
}
+static int __devinit setup_input_dev(void)
+{
+ const struct key_entry *key;
+ struct input_dev *input_dev;
+ int error;
+
+ wistron_idev = input_allocate_polled_device();
+ if (!wistron_idev)
+ return -ENOMEM;
+
+ wistron_idev->flush = wistron_flush;
+ wistron_idev->poll = wistron_poll;
+ wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
+
+ input_dev = wistron_idev->input;
+ input_dev->name = "Wistron laptop buttons";
+ input_dev->phys = "wistron/input0";
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->dev.parent = &wistron_device->dev;
+
+ input_dev->getkeycode = wistron_getkeycode;
+ input_dev->setkeycode = wistron_setkeycode;
+
+ for (key = keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_KEY:
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(key->keycode, input_dev->keybit);
+ break;
+
+ case KE_SW:
+ set_bit(EV_SW, input_dev->evbit);
+ set_bit(key->sw.code, input_dev->swbit);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* reads information flags on KE_END */
+ if (key->code & FE_UNTESTED)
+ printk(KERN_WARNING "Untested laptop multimedia keys, "
+ "please report success or failure to eric.piel"
+ "@tremplin-utc.net\n");
+
+ error = input_register_polled_device(wistron_idev);
+ if (error) {
+ input_free_polled_device(wistron_idev);
+ return error;
+ }
+
+ return 0;
+}
+
+/* Driver core */
+
static int __devinit wistron_probe(struct platform_device *dev)
{
- int err = setup_input_dev();
- if (err)
- return err;
+ int err;
bios_attach();
cmos_address = bios_get_cmos_address();
@@ -1125,15 +1270,21 @@ static int __devinit wistron_probe(struct platform_device *dev)
bios_set_state(BLUETOOTH, bluetooth_enabled);
}
- poll_bios(1); /* Flush stale event queue and arm timer */
+ wistron_led_init(&dev->dev);
+ err = setup_input_dev();
+ if (err) {
+ bios_detach();
+ return err;
+ }
return 0;
}
static int __devexit wistron_remove(struct platform_device *dev)
{
- del_timer_sync(&poll_timer);
- input_unregister_device(input_dev);
+ wistron_led_remove();
+ input_unregister_polled_device(wistron_idev);
+ input_free_polled_device(wistron_idev);
bios_detach();
return 0;
@@ -1142,14 +1293,13 @@ static int __devexit wistron_remove(struct platform_device *dev)
#ifdef CONFIG_PM
static int wistron_suspend(struct platform_device *dev, pm_message_t state)
{
- del_timer_sync(&poll_timer);
-
if (have_wifi)
bios_set_state(WIFI, 0);
if (have_bluetooth)
bios_set_state(BLUETOOTH, 0);
+ wistron_led_suspend();
return 0;
}
@@ -1161,7 +1311,8 @@ static int wistron_resume(struct platform_device *dev)
if (have_bluetooth)
bios_set_state(BLUETOOTH, bluetooth_enabled);
- poll_bios(1);
+ wistron_led_resume();
+ poll_bios(true);
return 0;
}
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 50e06e8dd05d..7bbea097cda2 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -216,4 +216,20 @@ config MOUSE_HIL
help
Say Y here to support HIL pointers.
+config MOUSE_GPIO
+ tristate "GPIO mouse"
+ depends on GENERIC_GPIO
+ select INPUT_POLLDEV
+ help
+ This driver simulates a mouse on GPIO lines of various CPUs (and some
+ other chips).
+
+ Say Y here if your device has buttons or a simple joystick connected
+ directly to GPIO lines. Your board-specific setup logic must also
+ provide a platform device and platform data saying which GPIOs are
+ used.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gpio_mouse.
+
endif
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index aa4ba878533f..9e6e36330820 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_MOUSE_PS2) += psmouse.o
obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
+obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
psmouse-objs := psmouse-base.o synaptics.o
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
new file mode 100644
index 000000000000..0936d6ba015c
--- /dev/null
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -0,0 +1,196 @@
+/*
+ * Driver for simulating a mouse on GPIO lines.
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/input-polldev.h>
+#include <linux/gpio_mouse.h>
+
+#include <asm/gpio.h>
+
+/*
+ * Timer function which is run every scan_ms ms when the device is opened.
+ * The dev input varaible is set to the the input_dev pointer.
+ */
+static void gpio_mouse_scan(struct input_polled_dev *dev)
+{
+ struct gpio_mouse_platform_data *gpio = dev->private;
+ struct input_dev *input = dev->input;
+ int x, y;
+
+ if (gpio->bleft >= 0)
+ input_report_key(input, BTN_LEFT,
+ gpio_get_value(gpio->bleft) ^ gpio->polarity);
+ if (gpio->bmiddle >= 0)
+ input_report_key(input, BTN_MIDDLE,
+ gpio_get_value(gpio->bmiddle) ^ gpio->polarity);
+ if (gpio->bright >= 0)
+ input_report_key(input, BTN_RIGHT,
+ gpio_get_value(gpio->bright) ^ gpio->polarity);
+
+ x = (gpio_get_value(gpio->right) ^ gpio->polarity)
+ - (gpio_get_value(gpio->left) ^ gpio->polarity);
+ y = (gpio_get_value(gpio->down) ^ gpio->polarity)
+ - (gpio_get_value(gpio->up) ^ gpio->polarity);
+
+ input_report_rel(input, REL_X, x);
+ input_report_rel(input, REL_Y, y);
+ input_sync(input);
+}
+
+static int __init gpio_mouse_probe(struct platform_device *pdev)
+{
+ struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
+ struct input_polled_dev *input_poll;
+ struct input_dev *input;
+ int pin, i;
+ int error;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ error = -ENXIO;
+ goto out;
+ }
+
+ if (pdata->scan_ms < 0) {
+ dev_err(&pdev->dev, "invalid scan time\n");
+ error = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) {
+ pin = pdata->pins[i];
+
+ if (pin < 0) {
+
+ if (i <= GPIO_MOUSE_PIN_RIGHT) {
+ /* Mouse direction is required. */
+ dev_err(&pdev->dev,
+ "missing GPIO for directions\n");
+ error = -EINVAL;
+ goto out_free_gpios;
+ }
+
+ if (i == GPIO_MOUSE_PIN_BLEFT)
+ dev_dbg(&pdev->dev, "no left button defined\n");
+
+ } else {
+ error = gpio_request(pin, "gpio_mouse");
+ if (error) {
+ dev_err(&pdev->dev, "fail %d pin (%d idx)\n",
+ pin, i);
+ goto out_free_gpios;
+ }
+
+ gpio_direction_input(pin);
+ }
+ }
+
+ input_poll = input_allocate_polled_device();
+ if (!input_poll) {
+ dev_err(&pdev->dev, "not enough memory for input device\n");
+ error = -ENOMEM;
+ goto out_free_gpios;
+ }
+
+ platform_set_drvdata(pdev, input_poll);
+
+ /* set input-polldev handlers */
+ input_poll->private = pdata;
+ input_poll->poll = gpio_mouse_scan;
+ input_poll->poll_interval = pdata->scan_ms;
+
+ input = input_poll->input;
+ input->name = pdev->name;
+ input->id.bustype = BUS_HOST;
+ input->dev.parent = &pdev->dev;
+
+ input_set_capability(input, EV_REL, REL_X);
+ input_set_capability(input, EV_REL, REL_Y);
+ if (pdata->bleft >= 0)
+ input_set_capability(input, EV_KEY, BTN_LEFT);
+ if (pdata->bmiddle >= 0)
+ input_set_capability(input, EV_KEY, BTN_MIDDLE);
+ if (pdata->bright >= 0)
+ input_set_capability(input, EV_KEY, BTN_RIGHT);
+
+ error = input_register_polled_device(input_poll);
+ if (error) {
+ dev_err(&pdev->dev, "could not register input device\n");
+ goto out_free_polldev;
+ }
+
+ dev_dbg(&pdev->dev, "%d ms scan time, buttons: %s%s%s\n",
+ pdata->scan_ms,
+ pdata->bleft < 0 ? "" : "left ",
+ pdata->bmiddle < 0 ? "" : "middle ",
+ pdata->bright < 0 ? "" : "right");
+
+ return 0;
+
+ out_free_polldev:
+ input_free_polled_device(input_poll);
+ platform_set_drvdata(pdev, NULL);
+
+ out_free_gpios:
+ while (--i >= 0) {
+ pin = pdata->pins[i];
+ if (pin)
+ gpio_free(pin);
+ }
+ out:
+ return error;
+}
+
+static int __devexit gpio_mouse_remove(struct platform_device *pdev)
+{
+ struct input_polled_dev *input = platform_get_drvdata(pdev);
+ struct gpio_mouse_platform_data *pdata = input->private;
+ int pin, i;
+
+ input_unregister_polled_device(input);
+ input_free_polled_device(input);
+
+ for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) {
+ pin = pdata->pins[i];
+ if (pin >= 0)
+ gpio_free(pin);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+struct platform_driver gpio_mouse_device_driver = {
+ .remove = __devexit_p(gpio_mouse_remove),
+ .driver = {
+ .name = "gpio_mouse",
+ }
+};
+
+static int __init gpio_mouse_init(void)
+{
+ return platform_driver_probe(&gpio_mouse_device_driver,
+ gpio_mouse_probe);
+}
+module_init(gpio_mouse_init);
+
+static void __exit gpio_mouse_exit(void)
+{
+ platform_driver_unregister(&gpio_mouse_device_driver);
+}
+module_exit(gpio_mouse_exit);
+
+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
+MODULE_DESCRIPTION("GPIO mouse driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index f15f695777f8..b9f0fb2530e2 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -178,6 +178,15 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
}
/*
+ * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first
+ * byte.
+ */
+ if (psmouse->type == PSMOUSE_CORTRON) {
+ input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
+ packet[0] |= 0x08;
+ }
+
+/*
* Generic PS/2 Mouse
*/
@@ -539,6 +548,20 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
return 0;
}
+/*
+ * Cortron PS/2 protocol detection. There's no special way to detect it, so it
+ * must be forced by sysfs protocol writing.
+ */
+static int cortron_detect(struct psmouse *psmouse, int set_properties)
+{
+ if (set_properties) {
+ psmouse->vendor = "Cortron";
+ psmouse->name = "PS/2 Trackball";
+ set_bit(BTN_SIDE, psmouse->dev->keybit);
+ }
+
+ return 0;
+}
/*
* psmouse_extensions() probes for any extensions to the basic PS/2 protocol
@@ -740,6 +763,12 @@ static const struct psmouse_protocol psmouse_protocols[] = {
},
#endif
{
+ .type = PSMOUSE_CORTRON,
+ .name = "CortronPS/2",
+ .alias = "cortps",
+ .detect = cortron_detect,
+ },
+ {
.type = PSMOUSE_AUTO,
.name = "auto",
.alias = "any",
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 3964e8acbc54..27a68835b5ba 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -88,6 +88,7 @@ enum psmouse_type {
PSMOUSE_LIFEBOOK,
PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2,
+ PSMOUSE_CORTRON,
PSMOUSE_AUTO /* This one should always be last */
};
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 3f4866d8d18c..9173916b8be5 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -64,6 +64,7 @@ struct mousedev {
wait_queue_head_t wait;
struct list_head client_list;
struct input_handle handle;
+ struct device dev;
struct list_head mixdev_node;
int mixdev_open;
@@ -112,7 +113,7 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
static struct input_handler mousedev_handler;
static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
-static struct mousedev mousedev_mix;
+static struct mousedev *mousedev_mix;
static LIST_HEAD(mousedev_mix_list);
#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
@@ -218,10 +219,10 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int
if (value) {
set_bit(index, &mousedev->packet.buttons);
- set_bit(index, &mousedev_mix.packet.buttons);
+ set_bit(index, &mousedev_mix->packet.buttons);
} else {
clear_bit(index, &mousedev->packet.buttons);
- clear_bit(index, &mousedev_mix.packet.buttons);
+ clear_bit(index, &mousedev_mix->packet.buttons);
}
}
@@ -287,11 +288,11 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
* motion packet so we won't mess current position.
*/
set_bit(0, &mousedev->packet.buttons);
- set_bit(0, &mousedev_mix.packet.buttons);
- mousedev_notify_readers(mousedev, &mousedev_mix.packet);
- mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
+ set_bit(0, &mousedev_mix->packet.buttons);
+ mousedev_notify_readers(mousedev, &mousedev_mix->packet);
+ mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet);
clear_bit(0, &mousedev->packet.buttons);
- clear_bit(0, &mousedev_mix.packet.buttons);
+ clear_bit(0, &mousedev_mix->packet.buttons);
}
mousedev->touch = mousedev->pkt_count = 0;
mousedev->frac_dx = 0;
@@ -343,7 +344,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
}
mousedev_notify_readers(mousedev, &mousedev->packet);
- mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
+ mousedev_notify_readers(mousedev_mix, &mousedev->packet);
mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
mousedev->packet.abs_event = 0;
@@ -362,8 +363,10 @@ static int mousedev_fasync(int fd, struct file *file, int on)
return retval < 0 ? retval : 0;
}
-static void mousedev_free(struct mousedev *mousedev)
+static void mousedev_free(struct device *dev)
{
+ struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
+
mousedev_table[mousedev->minor] = NULL;
kfree(mousedev);
}
@@ -372,15 +375,16 @@ static int mixdev_add_device(struct mousedev *mousedev)
{
int error;
- if (mousedev_mix.open) {
+ if (mousedev_mix->open) {
error = input_open_device(&mousedev->handle);
if (error)
return error;
mousedev->open++;
- mousedev->mixdev_open++;
+ mousedev->mixdev_open = 1;
}
+ get_device(&mousedev->dev);
list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
return 0;
@@ -395,36 +399,40 @@ static void mixdev_remove_device(struct mousedev *mousedev)
}
list_del_init(&mousedev->mixdev_node);
+ put_device(&mousedev->dev);
}
static void mixdev_open_devices(void)
{
struct mousedev *mousedev;
+ if (mousedev_mix->open++)
+ return;
+
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
- if (mousedev->exist && !mousedev->open) {
- if (input_open_device(&mousedev->handle))
- continue;
+ if (!mousedev->mixdev_open) {
+ if (!mousedev->open && mousedev->exist)
+ if (input_open_device(&mousedev->handle))
+ continue;
mousedev->open++;
- mousedev->mixdev_open++;
+ mousedev->mixdev_open = 1;
}
}
}
static void mixdev_close_devices(void)
{
- struct mousedev *mousedev, *next;
+ struct mousedev *mousedev;
- list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) {
+ if (--mousedev_mix->open)
+ return;
+
+ list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
if (mousedev->mixdev_open) {
mousedev->mixdev_open = 0;
- if (!--mousedev->open) {
- if (mousedev->exist)
- input_close_device(&mousedev->handle);
- else
- mousedev_free(mousedev);
- }
+ if (!--mousedev->open && mousedev->exist)
+ input_close_device(&mousedev->handle);
}
}
}
@@ -439,14 +447,12 @@ static int mousedev_release(struct inode *inode, struct file *file)
list_del(&client->node);
kfree(client);
- if (!--mousedev->open) {
- if (mousedev->minor == MOUSEDEV_MIX)
- mixdev_close_devices();
- else if (mousedev->exist)
- input_close_device(&mousedev->handle);
- else
- mousedev_free(mousedev);
- }
+ if (mousedev->minor == MOUSEDEV_MIX)
+ mixdev_close_devices();
+ else if (!--mousedev->open && mousedev->exist)
+ input_close_device(&mousedev->handle);
+
+ put_device(&mousedev->dev);
return 0;
}
@@ -473,9 +479,13 @@ static int mousedev_open(struct inode *inode, struct file *file)
if (!mousedev)
return -ENODEV;
+ get_device(&mousedev->dev);
+
client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
+ if (!client) {
+ error = -ENOMEM;
+ goto err_put_mousedev;
+ }
spin_lock_init(&client->packet_lock);
client->pos_x = xres / 2;
@@ -483,21 +493,23 @@ static int mousedev_open(struct inode *inode, struct file *file)
client->mousedev = mousedev;
list_add_tail(&client->node, &mousedev->client_list);
- if (!mousedev->open++) {
- if (mousedev->minor == MOUSEDEV_MIX)
- mixdev_open_devices();
- else if (mousedev->exist) {
- error = input_open_device(&mousedev->handle);
- if (error) {
- list_del(&client->node);
- kfree(client);
- return error;
- }
- }
+ if (mousedev->minor == MOUSEDEV_MIX)
+ mixdev_open_devices();
+ else if (!mousedev->open++ && mousedev->exist) {
+ error = input_open_device(&mousedev->handle);
+ if (error)
+ goto err_free_client;
}
file->private_data = client;
return 0;
+
+ err_free_client:
+ list_del(&client->node);
+ kfree(client);
+ err_put_mousedev:
+ put_device(&mousedev->dev);
+ return error;
}
static inline int mousedev_limit_delta(int delta, int limit)
@@ -680,57 +692,96 @@ static const struct file_operations mousedev_fops = {
.fasync = mousedev_fasync,
};
-static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
- const struct input_device_id *id)
+static struct mousedev *mousedev_create(struct input_dev *dev,
+ struct input_handler *handler,
+ int minor)
{
struct mousedev *mousedev;
- struct class_device *cdev;
- dev_t devt;
- int minor;
int error;
- for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
- if (minor == MOUSEDEV_MINORS) {
- printk(KERN_ERR "mousedev: no more free mousedev devices\n");
- return -ENFILE;
- }
-
mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
- if (!mousedev)
- return -ENOMEM;
+ if (!mousedev) {
+ error = -ENOMEM;
+ goto err_out;
+ }
INIT_LIST_HEAD(&mousedev->client_list);
INIT_LIST_HEAD(&mousedev->mixdev_node);
init_waitqueue_head(&mousedev->wait);
+ if (minor == MOUSEDEV_MIX)
+ strlcpy(mousedev->name, "mice", sizeof(mousedev->name));
+ else
+ snprintf(mousedev->name, sizeof(mousedev->name),
+ "mouse%d", minor);
+
mousedev->minor = minor;
mousedev->exist = 1;
mousedev->handle.dev = dev;
mousedev->handle.name = mousedev->name;
mousedev->handle.handler = handler;
mousedev->handle.private = mousedev;
- sprintf(mousedev->name, "mouse%d", minor);
- mousedev_table[minor] = mousedev;
+ strlcpy(mousedev->dev.bus_id, mousedev->name,
+ sizeof(mousedev->dev.bus_id));
+ mousedev->dev.class = &input_class;
+ if (dev)
+ mousedev->dev.parent = &dev->dev;
+ mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor);
+ mousedev->dev.release = mousedev_free;
+ device_initialize(&mousedev->dev);
- devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+ mousedev_table[minor] = mousedev;
- cdev = class_device_create(&input_class, &dev->cdev, devt,
- dev->cdev.dev, mousedev->name);
- if (IS_ERR(cdev)) {
- error = PTR_ERR(cdev);
+ error = device_add(&mousedev->dev);
+ if (error)
goto err_free_mousedev;
+
+ return mousedev;
+
+ err_free_mousedev:
+ put_device(&mousedev->dev);
+ err_out:
+ return ERR_PTR(error);
+}
+
+static void mousedev_destroy(struct mousedev *mousedev)
+{
+ struct mousedev_client *client;
+
+ device_del(&mousedev->dev);
+ mousedev->exist = 0;
+
+ if (mousedev->open) {
+ input_close_device(&mousedev->handle);
+ list_for_each_entry(client, &mousedev->client_list, node)
+ kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ wake_up_interruptible(&mousedev->wait);
}
- /* temporary symlink to keep userspace happy */
- error = sysfs_create_link(&input_class.subsys.kobj,
- &cdev->kobj, mousedev->name);
- if (error)
- goto err_cdev_destroy;
+ put_device(&mousedev->dev);
+}
+
+static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ struct mousedev *mousedev;
+ int minor;
+ int error;
+
+ for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
+ if (minor == MOUSEDEV_MINORS) {
+ printk(KERN_ERR "mousedev: no more free mousedev devices\n");
+ return -ENFILE;
+ }
+
+ mousedev = mousedev_create(dev, handler, minor);
+ if (IS_ERR(mousedev))
+ return PTR_ERR(mousedev);
error = input_register_handle(&mousedev->handle);
if (error)
- goto err_remove_link;
+ goto err_delete_mousedev;
error = mixdev_add_device(mousedev);
if (error)
@@ -740,37 +791,18 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev
err_unregister_handle:
input_unregister_handle(&mousedev->handle);
- err_remove_link:
- sysfs_remove_link(&input_class.subsys.kobj, mousedev->name);
- err_cdev_destroy:
- class_device_destroy(&input_class, devt);
- err_free_mousedev:
- mousedev_table[minor] = NULL;
- kfree(mousedev);
+ err_delete_mousedev:
+ device_unregister(&mousedev->dev);
return error;
}
static void mousedev_disconnect(struct input_handle *handle)
{
struct mousedev *mousedev = handle->private;
- struct mousedev_client *client;
-
- input_unregister_handle(handle);
-
- sysfs_remove_link(&input_class.subsys.kobj, mousedev->name);
- class_device_destroy(&input_class,
- MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
- mousedev->exist = 0;
mixdev_remove_device(mousedev);
-
- if (mousedev->open) {
- input_close_device(handle);
- list_for_each_entry(client, &mousedev->client_list, node)
- kill_fasync(&client->fasync, SIGIO, POLL_HUP);
- wake_up_interruptible(&mousedev->wait);
- } else
- mousedev_free(mousedev);
+ input_unregister_handle(handle);
+ mousedev_destroy(mousedev);
}
static const struct input_device_id mousedev_ids[] = {
@@ -822,25 +854,16 @@ static int psaux_registered;
static int __init mousedev_init(void)
{
- struct class_device *cdev;
int error;
+ mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX);
+ if (IS_ERR(mousedev_mix))
+ return PTR_ERR(mousedev_mix);
+
error = input_register_handler(&mousedev_handler);
- if (error)
+ if (error) {
+ mousedev_destroy(mousedev_mix);
return error;
-
- memset(&mousedev_mix, 0, sizeof(struct mousedev));
- INIT_LIST_HEAD(&mousedev_mix.client_list);
- init_waitqueue_head(&mousedev_mix.wait);
- mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
- mousedev_mix.exist = 1;
- mousedev_mix.minor = MOUSEDEV_MIX;
-
- cdev = class_device_create(&input_class, NULL,
- MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
- if (IS_ERR(cdev)) {
- input_unregister_handler(&mousedev_handler);
- return PTR_ERR(cdev);
}
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -863,9 +886,8 @@ static void __exit mousedev_exit(void)
if (psaux_registered)
misc_deregister(&psaux_mouse);
#endif
- class_device_destroy(&input_class,
- MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
input_unregister_handler(&mousedev_handler);
+ mousedev_destroy(mousedev_mix);
}
module_init(mousedev_init);
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 887357666c68..0403622ae267 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -160,7 +160,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, size_t cou
{
struct serio_raw_list *list = file->private_data;
struct serio_raw *serio_raw = list->serio_raw;
- char c;
+ char uninitialized_var(c);
ssize_t retval = 0;
if (!serio_raw->serio)
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index cc0a498763d8..94683f58c9e1 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -82,8 +82,8 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.5 (May-15-2004)"
-#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio"
+#define DRIVER_VERSION "v2.3 (May 2, 2007)"
+#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen"
#define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)"
/*
@@ -112,7 +112,7 @@
* (returned as Report 3 - absolute coordinates from the mouse)
*
* bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 0 1 0
+ * byte0 0 0 0 0 0 0 1 1
* byte1 X7 X6 X5 X4 X3 X2 X1 X0
* byte2 X15 X14 X13 X12 X11 X10 X9 X8
* byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
@@ -134,7 +134,7 @@
* (returned as Report 5 - macrokeys from the mouse)
*
* bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 1 0 0
+ * byte0 0 0 0 0 0 1 0 1
* byte1 0 0 0 BS2 BS Tip IR DV
* byte2 0 0 0 0 0 0 1 0
* byte3 0 0 0 K4 K3 K2 K1 K0
@@ -218,15 +218,9 @@
#define AIPTEK_WHEEL_DISABLE (-10101)
/* ToolCode values, which BTW are 0x140 .. 0x14f
- * We have things set up such that if TOOL_BUTTON_FIRED_BIT is
- * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx.
- *
- * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will
- * get reset.
+ * We have things set up such that if the tool button has changed,
+ * the tools get reset.
*/
-#define TOOL_BUTTON(x) ((x) & 0x14f)
-#define TOOL_BUTTON_FIRED(x) ((x) & 0x200)
-#define TOOL_BUTTON_FIRED_BIT 0x200
/* toolMode codes
*/
#define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN
@@ -264,9 +258,9 @@
/* Mouse button programming
*/
-#define AIPTEK_MOUSE_LEFT_BUTTON 0x01
-#define AIPTEK_MOUSE_RIGHT_BUTTON 0x02
-#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x04
+#define AIPTEK_MOUSE_LEFT_BUTTON 0x04
+#define AIPTEK_MOUSE_RIGHT_BUTTON 0x08
+#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x10
/* Stylus button programming
*/
@@ -294,7 +288,6 @@ struct aiptek_features {
int modelCode; /* Tablet model code (not unique) */
int firmwareCode; /* prom/eeprom version */
char usbPath[64 + 1]; /* device's physical usb path */
- char inputPath[64 + 1]; /* input device path */
};
struct aiptek_settings {
@@ -327,9 +320,32 @@ struct aiptek {
int inDelay; /* jitter: in jitter delay? */
unsigned long endDelay; /* jitter: time when delay ends */
int previousJitterable; /* jitterable prev value */
+
+ int lastMacro; /* macro key to reset */
+ int previousToolMode; /* pen, pencil, brush, etc. tool */
unsigned char *data; /* incoming packet data */
};
+static const int eventTypes[] = {
+ EV_KEY, EV_ABS, EV_REL, EV_MSC,
+};
+
+static const int absEvents[] = {
+ ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y,
+ ABS_WHEEL, ABS_MISC,
+};
+
+static const int relEvents[] = {
+ REL_X, REL_Y, REL_WHEEL,
+};
+
+static const int buttonEvents[] = {
+ BTN_LEFT, BTN_RIGHT, BTN_MIDDLE,
+ BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
+ BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH,
+ BTN_STYLUS, BTN_STYLUS2,
+};
+
/*
* Permit easy lookup of keyboard events to send, versus
* the bitmap which comes from the tablet. This hides the
@@ -345,23 +361,39 @@ static const int macroKeyEvents[] = {
};
/***********************************************************************
- * Relative reports deliver values in 2's complement format to
- * deal with negative offsets.
+ * Map values to strings and back. Every map shoudl have the following
+ * as its last element: { NULL, AIPTEK_INVALID_VALUE }.
*/
-static int aiptek_convert_from_2s_complement(unsigned char c)
+#define AIPTEK_INVALID_VALUE -1
+
+struct aiptek_map {
+ const char *string;
+ int value;
+};
+
+static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count)
{
- int ret;
- unsigned char b = c;
- int negate = 0;
+ const struct aiptek_map *p;
- if ((b & 0x80) != 0) {
- b = ~b;
- b--;
- negate = 1;
- }
- ret = b;
- ret = (negate == 1) ? -ret : ret;
- return ret;
+ if (str[count - 1] == '\n')
+ count--;
+
+ for (p = map; p->string; p++)
+ if (!strncmp(str, p->string, count))
+ return p->value;
+
+ return AIPTEK_INVALID_VALUE;
+}
+
+static const char *map_val_to_str(const struct aiptek_map *map, int val)
+{
+ const struct aiptek_map *p;
+
+ for (p = map; p->value != AIPTEK_INVALID_VALUE; p++)
+ if (val == p->value)
+ return p->string;
+
+ return "unknown";
}
/***********************************************************************
@@ -385,6 +417,9 @@ static int aiptek_convert_from_2s_complement(unsigned char c)
* Proximity. Why two events? I thought it interesting to know if the
* Proximity event occurred while the tablet was in absolute or relative
* mode.
+ * Update: REL_MISC proved not to be such a good idea. With REL_MISC you
+ * get an event transmitted each time. ABS_MISC works better, since it
+ * can be set and re-set. Thus, only using ABS_MISC from now on.
*
* Other tablets use the notion of a certain minimum stylus pressure
* to infer proximity. While that could have been done, that is yet
@@ -441,8 +476,8 @@ static void aiptek_irq(struct urb *urb)
aiptek->diagnostic =
AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;
} else {
- x = aiptek_convert_from_2s_complement(data[2]);
- y = aiptek_convert_from_2s_complement(data[3]);
+ x = (signed char) data[2];
+ y = (signed char) data[3];
/* jitterable keeps track of whether any button has been pressed.
* We're also using it to remap the physical mouse button mask
@@ -451,18 +486,20 @@ static void aiptek_irq(struct urb *urb)
* that a non-zero value indicates that one or more
* mouse button was pressed.)
*/
- jitterable = data[5] & 0x07;
+ jitterable = data[1] & 0x07;
- left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
- right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
- middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
+ left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0;
+ right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0;
+ middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0;
input_report_key(inputdev, BTN_LEFT, left);
input_report_key(inputdev, BTN_MIDDLE, middle);
input_report_key(inputdev, BTN_RIGHT, right);
+
+ input_report_abs(inputdev, ABS_MISC,
+ 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
input_report_rel(inputdev, REL_X, x);
input_report_rel(inputdev, REL_Y, y);
- input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
/* Wheel support is in the form of a single-event
* firing.
@@ -472,6 +509,11 @@ static void aiptek_irq(struct urb *urb)
aiptek->curSetting.wheel);
aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
}
+ if (aiptek->lastMacro != -1) {
+ input_report_key(inputdev,
+ macroKeyEvents[aiptek->lastMacro], 0);
+ aiptek->lastMacro = -1;
+ }
input_sync(inputdev);
}
}
@@ -489,8 +531,8 @@ static void aiptek_irq(struct urb *urb)
y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
z = le16_to_cpu(get_unaligned((__le16 *) (data + 6)));
- p = (data[5] & 0x01) != 0 ? 1 : 0;
- dv = (data[5] & 0x02) != 0 ? 1 : 0;
+ dv = (data[5] & 0x01) != 0 ? 1 : 0;
+ p = (data[5] & 0x02) != 0 ? 1 : 0;
tip = (data[5] & 0x04) != 0 ? 1 : 0;
/* Use jitterable to re-arrange button masks
@@ -505,16 +547,18 @@ static void aiptek_irq(struct urb *urb)
* all 'bad' reports...
*/
if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
+ /* If the selected tool changed, reset the old
+ * tool key, and set the new one.
*/
- if (TOOL_BUTTON_FIRED
- (aiptek->curSetting.toolMode) == 0) {
+ if (aiptek->previousToolMode !=
+ aiptek->curSetting.toolMode) {
+ input_report_key(inputdev,
+ aiptek->previousToolMode, 0);
input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
+ aiptek->curSetting.toolMode,
1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+ aiptek->previousToolMode =
+ aiptek->curSetting.toolMode;
}
if (p != 0) {
@@ -550,6 +594,11 @@ static void aiptek_irq(struct urb *urb)
}
}
input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS);
+ if (aiptek->lastMacro != -1) {
+ input_report_key(inputdev,
+ macroKeyEvents[aiptek->lastMacro], 0);
+ aiptek->lastMacro = -1;
+ }
input_sync(inputdev);
}
}
@@ -568,23 +617,25 @@ static void aiptek_irq(struct urb *urb)
jitterable = data[5] & 0x1c;
- p = (data[5] & 0x01) != 0 ? 1 : 0;
- dv = (data[5] & 0x02) != 0 ? 1 : 0;
+ dv = (data[5] & 0x01) != 0 ? 1 : 0;
+ p = (data[5] & 0x02) != 0 ? 1 : 0;
left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
+ /* If the selected tool changed, reset the old
+ * tool key, and set the new one.
*/
- if (TOOL_BUTTON_FIRED
- (aiptek->curSetting.toolMode) == 0) {
+ if (aiptek->previousToolMode !=
+ aiptek->curSetting.toolMode) {
+ input_report_key(inputdev,
+ aiptek->previousToolMode, 0);
input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
+ aiptek->curSetting.toolMode,
1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+ aiptek->previousToolMode =
+ aiptek->curSetting.toolMode;
}
if (p != 0) {
@@ -605,7 +656,12 @@ static void aiptek_irq(struct urb *urb)
aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
}
}
- input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
+ input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
+ if (aiptek->lastMacro != -1) {
+ input_report_key(inputdev,
+ macroKeyEvents[aiptek->lastMacro], 0);
+ aiptek->lastMacro = -1;
+ }
input_sync(inputdev);
}
}
@@ -615,98 +671,83 @@ static void aiptek_irq(struct urb *urb)
else if (data[0] == 4) {
jitterable = data[1] & 0x18;
- p = (data[1] & 0x01) != 0 ? 1 : 0;
- dv = (data[1] & 0x02) != 0 ? 1 : 0;
+ dv = (data[1] & 0x01) != 0 ? 1 : 0;
+ p = (data[1] & 0x02) != 0 ? 1 : 0;
tip = (data[1] & 0x04) != 0 ? 1 : 0;
bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
- macro = data[3];
+ macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1;
z = le16_to_cpu(get_unaligned((__le16 *) (data + 4)));
- if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
+ if (dv) {
+ /* If the selected tool changed, reset the old
+ * tool key, and set the new one.
*/
- if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
+ if (aiptek->previousToolMode !=
+ aiptek->curSetting.toolMode) {
+ input_report_key(inputdev,
+ aiptek->previousToolMode, 0);
input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
+ aiptek->curSetting.toolMode,
1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+ aiptek->previousToolMode =
+ aiptek->curSetting.toolMode;
}
+ }
- if (p != 0) {
- input_report_key(inputdev, BTN_TOUCH, tip);
- input_report_key(inputdev, BTN_STYLUS, bs);
- input_report_key(inputdev, BTN_STYLUS2, pck);
- input_report_abs(inputdev, ABS_PRESSURE, z);
- }
+ if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
+ input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
+ aiptek->lastMacro = -1;
+ }
- /* For safety, we're sending key 'break' codes for the
- * neighboring macro keys.
- */
- if (macro > 0) {
- input_report_key(inputdev,
- macroKeyEvents[macro - 1], 0);
- }
- if (macro < 25) {
- input_report_key(inputdev,
- macroKeyEvents[macro + 1], 0);
- }
- input_report_key(inputdev, macroKeyEvents[macro], p);
- input_report_abs(inputdev, ABS_MISC,
- p | AIPTEK_REPORT_TOOL_STYLUS);
- input_sync(inputdev);
+ if (macro != -1 && macro != aiptek->lastMacro) {
+ input_report_key(inputdev, macroKeyEvents[macro], 1);
+ aiptek->lastMacro = macro;
}
+ input_report_abs(inputdev, ABS_MISC,
+ p | AIPTEK_REPORT_TOOL_STYLUS);
+ input_sync(inputdev);
}
/* Report 5s come from the macro keys when pressed by mouse
*/
else if (data[0] == 5) {
jitterable = data[1] & 0x1c;
- p = (data[1] & 0x01) != 0 ? 1 : 0;
- dv = (data[1] & 0x02) != 0 ? 1 : 0;
+ dv = (data[1] & 0x01) != 0 ? 1 : 0;
+ p = (data[1] & 0x02) != 0 ? 1 : 0;
left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
- macro = data[3];
+ macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0;
- if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
+ if (dv) {
+ /* If the selected tool changed, reset the old
+ * tool key, and set the new one.
*/
- if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
- input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
- 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
- }
-
- if (p != 0) {
- input_report_key(inputdev, BTN_LEFT, left);
- input_report_key(inputdev, BTN_MIDDLE, middle);
- input_report_key(inputdev, BTN_RIGHT, right);
+ if (aiptek->previousToolMode !=
+ aiptek->curSetting.toolMode) {
+ input_report_key(inputdev,
+ aiptek->previousToolMode, 0);
+ input_report_key(inputdev,
+ aiptek->curSetting.toolMode, 1);
+ aiptek->previousToolMode = aiptek->curSetting.toolMode;
}
+ }
- /* For safety, we're sending key 'break' codes for the
- * neighboring macro keys.
- */
- if (macro > 0) {
- input_report_key(inputdev,
- macroKeyEvents[macro - 1], 0);
- }
- if (macro < 25) {
- input_report_key(inputdev,
- macroKeyEvents[macro + 1], 0);
- }
+ if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
+ input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
+ aiptek->lastMacro = -1;
+ }
+ if (macro != -1 && macro != aiptek->lastMacro) {
input_report_key(inputdev, macroKeyEvents[macro], 1);
- input_report_rel(inputdev, ABS_MISC,
- p | AIPTEK_REPORT_TOOL_MOUSE);
- input_sync(inputdev);
+ aiptek->lastMacro = macro;
}
+
+ input_report_abs(inputdev, ABS_MISC,
+ p | AIPTEK_REPORT_TOOL_MOUSE);
+ input_sync(inputdev);
}
/* We have no idea which tool can generate a report 6. Theoretically,
* neither need to, having been given reports 4 & 5 for such use.
@@ -725,15 +766,18 @@ static void aiptek_irq(struct urb *urb)
0);
}
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
- */
- if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
+ /* If the selected tool changed, reset the old
+ tool key, and set the new one.
+ */
+ if (aiptek->previousToolMode !=
+ aiptek->curSetting.toolMode) {
+ input_report_key(inputdev,
+ aiptek->previousToolMode, 0);
input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.
- toolMode), 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
+ aiptek->curSetting.toolMode,
+ 1);
+ aiptek->previousToolMode =
+ aiptek->curSetting.toolMode;
}
input_report_key(inputdev, macroKeyEvents[macro], 1);
@@ -1007,9 +1051,6 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "%dx%d\n",
aiptek->inputdev->absmax[ABS_X] + 1,
aiptek->inputdev->absmax[ABS_Y] + 1);
@@ -1024,117 +1065,35 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);
/***********************************************************************
- * support routines for the 'product_id' file
- */
-static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n",
- aiptek->inputdev->id.product);
-}
-
-static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
-
-/***********************************************************************
- * support routines for the 'vendor_id' file
- */
-static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
-}
-
-static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
-
-/***********************************************************************
- * support routines for the 'vendor' file
- */
-static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- int retval;
-
- if (aiptek == NULL)
- return 0;
-
- retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer);
- return retval;
-}
-
-static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL);
-
-/***********************************************************************
- * support routines for the 'product' file
- */
-static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- int retval;
-
- if (aiptek == NULL)
- return 0;
-
- retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product);
- return retval;
-}
-
-static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL);
-
-/***********************************************************************
* support routines for the 'pointer_mode' file. Note that this file
* both displays current setting and allows reprogramming.
*/
+static struct aiptek_map pointer_mode_map[] = {
+ { "stylus", AIPTEK_POINTER_ONLY_STYLUS_MODE },
+ { "mouse", AIPTEK_POINTER_ONLY_MOUSE_MODE },
+ { "either", AIPTEK_POINTER_EITHER_MODE },
+ { NULL, AIPTEK_INVALID_VALUE }
+};
+
static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.pointerMode) {
- case AIPTEK_POINTER_ONLY_STYLUS_MODE:
- s = "stylus";
- break;
-
- case AIPTEK_POINTER_ONLY_MOUSE_MODE:
- s = "mouse";
- break;
-
- case AIPTEK_POINTER_EITHER_MODE:
- s = "either";
- break;
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(pointer_mode_map,
+ aiptek->curSetting.pointerMode));
}
static ssize_t
store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
+ int new_mode = map_str_to_val(pointer_mode_map, buf, count);
- if (strcmp(buf, "stylus") == 0) {
- aiptek->newSetting.pointerMode =
- AIPTEK_POINTER_ONLY_STYLUS_MODE;
- } else if (strcmp(buf, "mouse") == 0) {
- aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE;
- } else if (strcmp(buf, "either") == 0) {
- aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE;
- }
+ if (new_mode == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
+
+ aiptek->newSetting.pointerMode = new_mode;
return count;
}
@@ -1146,44 +1105,32 @@ static DEVICE_ATTR(pointer_mode,
* support routines for the 'coordinate_mode' file. Note that this file
* both displays current setting and allows reprogramming.
*/
+
+static struct aiptek_map coordinate_mode_map[] = {
+ { "absolute", AIPTEK_COORDINATE_ABSOLUTE_MODE },
+ { "relative", AIPTEK_COORDINATE_RELATIVE_MODE },
+ { NULL, AIPTEK_INVALID_VALUE }
+};
+
static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.coordinateMode) {
- case AIPTEK_COORDINATE_ABSOLUTE_MODE:
- s = "absolute";
- break;
-
- case AIPTEK_COORDINATE_RELATIVE_MODE:
- s = "relative";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(coordinate_mode_map,
+ aiptek->curSetting.coordinateMode));
}
static ssize_t
store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
+ int new_mode = map_str_to_val(coordinate_mode_map, buf, count);
- if (strcmp(buf, "absolute") == 0) {
- aiptek->newSetting.pointerMode =
- AIPTEK_COORDINATE_ABSOLUTE_MODE;
- } else if (strcmp(buf, "relative") == 0) {
- aiptek->newSetting.pointerMode =
- AIPTEK_COORDINATE_RELATIVE_MODE;
- }
+ if (new_mode == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
+
+ aiptek->newSetting.coordinateMode = new_mode;
return count;
}
@@ -1195,73 +1142,37 @@ static DEVICE_ATTR(coordinate_mode,
* support routines for the 'tool_mode' file. Note that this file
* both displays current setting and allows reprogramming.
*/
+
+static struct aiptek_map tool_mode_map[] = {
+ { "mouse", AIPTEK_TOOL_BUTTON_MOUSE_MODE },
+ { "eraser", AIPTEK_TOOL_BUTTON_ERASER_MODE },
+ { "pencil", AIPTEK_TOOL_BUTTON_PENCIL_MODE },
+ { "pen", AIPTEK_TOOL_BUTTON_PEN_MODE },
+ { "brush", AIPTEK_TOOL_BUTTON_BRUSH_MODE },
+ { "airbrush", AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE },
+ { "lens", AIPTEK_TOOL_BUTTON_LENS_MODE },
+ { NULL, AIPTEK_INVALID_VALUE }
+};
+
static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) {
- case AIPTEK_TOOL_BUTTON_MOUSE_MODE:
- s = "mouse";
- break;
-
- case AIPTEK_TOOL_BUTTON_ERASER_MODE:
- s = "eraser";
- break;
-
- case AIPTEK_TOOL_BUTTON_PENCIL_MODE:
- s = "pencil";
- break;
-
- case AIPTEK_TOOL_BUTTON_PEN_MODE:
- s = "pen";
- break;
-
- case AIPTEK_TOOL_BUTTON_BRUSH_MODE:
- s = "brush";
- break;
-
- case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE:
- s = "airbrush";
- break;
-
- case AIPTEK_TOOL_BUTTON_LENS_MODE:
- s = "lens";
- break;
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(tool_mode_map,
+ aiptek->curSetting.toolMode));
}
static ssize_t
store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
+ int new_mode = map_str_to_val(tool_mode_map, buf, count);
- if (strcmp(buf, "mouse") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE;
- } else if (strcmp(buf, "eraser") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_ERASER_MODE;
- } else if (strcmp(buf, "pencil") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PENCIL_MODE;
- } else if (strcmp(buf, "pen") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE;
- } else if (strcmp(buf, "brush") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_BRUSH_MODE;
- } else if (strcmp(buf, "airbrush") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE;
- } else if (strcmp(buf, "lens") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_LENS_MODE;
- }
+ if (new_mode == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
+ aiptek->newSetting.toolMode = new_mode;
return count;
}
@@ -1277,9 +1188,6 @@ static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *att
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) {
return snprintf(buf, PAGE_SIZE, "disable\n");
} else {
@@ -1294,9 +1202,6 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
struct aiptek *aiptek = dev_get_drvdata(dev);
int x;
- if (aiptek == NULL)
- return 0;
-
if (strcmp(buf, "disable") == 0) {
aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
} else {
@@ -1319,9 +1224,6 @@ static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *att
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) {
return snprintf(buf, PAGE_SIZE, "disable\n");
} else {
@@ -1336,9 +1238,6 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char
struct aiptek *aiptek = dev_get_drvdata(dev);
int y;
- if (aiptek == NULL)
- return 0;
-
if (strcmp(buf, "disable") == 0) {
aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
} else {
@@ -1361,9 +1260,6 @@ static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribut
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay);
}
@@ -1372,9 +1268,6 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10);
return count;
}
@@ -1391,9 +1284,6 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_at
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "%d\n",
aiptek->curSetting.programmableDelay);
}
@@ -1403,9 +1293,6 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10);
return count;
}
@@ -1415,23 +1302,6 @@ static DEVICE_ATTR(delay,
show_tabletProgrammableDelay, store_tabletProgrammableDelay);
/***********************************************************************
- * support routines for the 'input_path' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "/dev/input/%s\n",
- aiptek->features.inputPath);
-}
-
-static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL);
-
-/***********************************************************************
* support routines for the 'event_count' file. Note that this file
* only displays current setting.
*/
@@ -1439,9 +1309,6 @@ static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attri
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount);
}
@@ -1456,9 +1323,6 @@ static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_at
struct aiptek *aiptek = dev_get_drvdata(dev);
char *retMsg;
- if (aiptek == NULL)
- return 0;
-
switch (aiptek->diagnostic) {
case AIPTEK_DIAGNOSTIC_NA:
retMsg = "no errors\n";
@@ -1493,45 +1357,32 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL);
* support routines for the 'stylus_upper' file. Note that this file
* both displays current setting and allows for setting changing.
*/
+
+static struct aiptek_map stylus_button_map[] = {
+ { "upper", AIPTEK_STYLUS_UPPER_BUTTON },
+ { "lower", AIPTEK_STYLUS_LOWER_BUTTON },
+ { NULL, AIPTEK_INVALID_VALUE }
+};
+
static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.stylusButtonUpper) {
- case AIPTEK_STYLUS_UPPER_BUTTON:
- s = "upper";
- break;
-
- case AIPTEK_STYLUS_LOWER_BUTTON:
- s = "lower";
- break;
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(stylus_button_map,
+ aiptek->curSetting.stylusButtonUpper));
}
static ssize_t
store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ int new_button = map_str_to_val(stylus_button_map, buf, count);
- if (aiptek == NULL)
- return 0;
+ if (new_button == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
- if (strcmp(buf, "upper") == 0) {
- aiptek->newSetting.stylusButtonUpper =
- AIPTEK_STYLUS_UPPER_BUTTON;
- } else if (strcmp(buf, "lower") == 0) {
- aiptek->newSetting.stylusButtonUpper =
- AIPTEK_STYLUS_LOWER_BUTTON;
- }
+ aiptek->newSetting.stylusButtonUpper = new_button;
return count;
}
@@ -1543,45 +1394,26 @@ static DEVICE_ATTR(stylus_upper,
* support routines for the 'stylus_lower' file. Note that this file
* both displays current setting and allows for setting changing.
*/
+
static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.stylusButtonLower) {
- case AIPTEK_STYLUS_UPPER_BUTTON:
- s = "upper";
- break;
-
- case AIPTEK_STYLUS_LOWER_BUTTON:
- s = "lower";
- break;
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(stylus_button_map,
+ aiptek->curSetting.stylusButtonLower));
}
static ssize_t
store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ int new_button = map_str_to_val(stylus_button_map, buf, count);
- if (aiptek == NULL)
- return 0;
+ if (new_button == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
- if (strcmp(buf, "upper") == 0) {
- aiptek->newSetting.stylusButtonLower =
- AIPTEK_STYLUS_UPPER_BUTTON;
- } else if (strcmp(buf, "lower") == 0) {
- aiptek->newSetting.stylusButtonLower =
- AIPTEK_STYLUS_LOWER_BUTTON;
- }
+ aiptek->newSetting.stylusButtonLower = new_button;
return count;
}
@@ -1593,49 +1425,33 @@ static DEVICE_ATTR(stylus_lower,
* support routines for the 'mouse_left' file. Note that this file
* both displays current setting and allows for setting changing.
*/
+
+static struct aiptek_map mouse_button_map[] = {
+ { "left", AIPTEK_MOUSE_LEFT_BUTTON },
+ { "middle", AIPTEK_MOUSE_MIDDLE_BUTTON },
+ { "right", AIPTEK_MOUSE_RIGHT_BUTTON },
+ { NULL, AIPTEK_INVALID_VALUE }
+};
+
static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.mouseButtonLeft) {
- case AIPTEK_MOUSE_LEFT_BUTTON:
- s = "left";
- break;
-
- case AIPTEK_MOUSE_MIDDLE_BUTTON:
- s = "middle";
- break;
-
- case AIPTEK_MOUSE_RIGHT_BUTTON:
- s = "right";
- break;
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(mouse_button_map,
+ aiptek->curSetting.mouseButtonLeft));
}
static ssize_t
store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ int new_button = map_str_to_val(mouse_button_map, buf, count);
- if (aiptek == NULL)
- return 0;
+ if (new_button == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
- if (strcmp(buf, "left") == 0) {
- aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON;
- } else if (strcmp(buf, "middle") == 0) {
- aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_MIDDLE_BUTTON;
- } else if (strcmp(buf, "right") == 0) {
- aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_RIGHT_BUTTON;
- }
+ aiptek->newSetting.mouseButtonLeft = new_button;
return count;
}
@@ -1650,48 +1466,22 @@ static DEVICE_ATTR(mouse_left,
static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.mouseButtonMiddle) {
- case AIPTEK_MOUSE_LEFT_BUTTON:
- s = "left";
- break;
-
- case AIPTEK_MOUSE_MIDDLE_BUTTON:
- s = "middle";
- break;
-
- case AIPTEK_MOUSE_RIGHT_BUTTON:
- s = "right";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(mouse_button_map,
+ aiptek->curSetting.mouseButtonMiddle));
}
static ssize_t
store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ int new_button = map_str_to_val(mouse_button_map, buf, count);
- if (aiptek == NULL)
- return 0;
+ if (new_button == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
- if (strcmp(buf, "left") == 0) {
- aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON;
- } else if (strcmp(buf, "middle") == 0) {
- aiptek->newSetting.mouseButtonMiddle =
- AIPTEK_MOUSE_MIDDLE_BUTTON;
- } else if (strcmp(buf, "right") == 0) {
- aiptek->newSetting.mouseButtonMiddle =
- AIPTEK_MOUSE_RIGHT_BUTTON;
- }
+ aiptek->newSetting.mouseButtonMiddle = new_button;
return count;
}
@@ -1706,47 +1496,22 @@ static DEVICE_ATTR(mouse_middle,
static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.mouseButtonRight) {
- case AIPTEK_MOUSE_LEFT_BUTTON:
- s = "left";
- break;
-
- case AIPTEK_MOUSE_MIDDLE_BUTTON:
- s = "middle";
- break;
- case AIPTEK_MOUSE_RIGHT_BUTTON:
- s = "right";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ map_val_to_str(mouse_button_map,
+ aiptek->curSetting.mouseButtonRight));
}
static ssize_t
store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ int new_button = map_str_to_val(mouse_button_map, buf, count);
- if (aiptek == NULL)
- return 0;
+ if (new_button == AIPTEK_INVALID_VALUE)
+ return -EINVAL;
- if (strcmp(buf, "left") == 0) {
- aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON;
- } else if (strcmp(buf, "middle") == 0) {
- aiptek->newSetting.mouseButtonRight =
- AIPTEK_MOUSE_MIDDLE_BUTTON;
- } else if (strcmp(buf, "right") == 0) {
- aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON;
- }
+ aiptek->newSetting.mouseButtonRight = new_button;
return count;
}
@@ -1762,9 +1527,6 @@ static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *att
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) {
return snprintf(buf, PAGE_SIZE, "disable\n");
} else {
@@ -1778,9 +1540,6 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10);
return count;
}
@@ -1794,11 +1553,6 @@ static DEVICE_ATTR(wheel,
*/
static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
/* There is nothing useful to display, so a one-line manual
* is in order...
*/
@@ -1811,9 +1565,6 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
/* We do not care what you write to this file. Merely the action
* of writing to this file triggers a tablet reprogramming.
*/
@@ -1837,9 +1588,6 @@ static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *a
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode);
}
@@ -1853,9 +1601,6 @@ static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode);
}
@@ -1869,86 +1614,39 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
return snprintf(buf, PAGE_SIZE, "%04x\n",
aiptek->features.firmwareCode);
}
static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL);
-/***********************************************************************
- * This routine removes all existing sysfs files managed by this device
- * driver.
- */
-static void aiptek_delete_files(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_size);
- device_remove_file(dev, &dev_attr_product_id);
- device_remove_file(dev, &dev_attr_vendor_id);
- device_remove_file(dev, &dev_attr_vendor);
- device_remove_file(dev, &dev_attr_product);
- device_remove_file(dev, &dev_attr_pointer_mode);
- device_remove_file(dev, &dev_attr_coordinate_mode);
- device_remove_file(dev, &dev_attr_tool_mode);
- device_remove_file(dev, &dev_attr_xtilt);
- device_remove_file(dev, &dev_attr_ytilt);
- device_remove_file(dev, &dev_attr_jitter);
- device_remove_file(dev, &dev_attr_delay);
- device_remove_file(dev, &dev_attr_input_path);
- device_remove_file(dev, &dev_attr_event_count);
- device_remove_file(dev, &dev_attr_diagnostic);
- device_remove_file(dev, &dev_attr_odm_code);
- device_remove_file(dev, &dev_attr_model_code);
- device_remove_file(dev, &dev_attr_firmware_code);
- device_remove_file(dev, &dev_attr_stylus_lower);
- device_remove_file(dev, &dev_attr_stylus_upper);
- device_remove_file(dev, &dev_attr_mouse_left);
- device_remove_file(dev, &dev_attr_mouse_middle);
- device_remove_file(dev, &dev_attr_mouse_right);
- device_remove_file(dev, &dev_attr_wheel);
- device_remove_file(dev, &dev_attr_execute);
-}
-
-/***********************************************************************
- * This routine creates the sysfs files managed by this device
- * driver.
- */
-static int aiptek_add_files(struct device *dev)
-{
- int ret;
+static struct attribute *aiptek_attributes[] = {
+ &dev_attr_size.attr,
+ &dev_attr_pointer_mode.attr,
+ &dev_attr_coordinate_mode.attr,
+ &dev_attr_tool_mode.attr,
+ &dev_attr_xtilt.attr,
+ &dev_attr_ytilt.attr,
+ &dev_attr_jitter.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_event_count.attr,
+ &dev_attr_diagnostic.attr,
+ &dev_attr_odm_code.attr,
+ &dev_attr_model_code.attr,
+ &dev_attr_firmware_code.attr,
+ &dev_attr_stylus_lower.attr,
+ &dev_attr_stylus_upper.attr,
+ &dev_attr_mouse_left.attr,
+ &dev_attr_mouse_middle.attr,
+ &dev_attr_mouse_right.attr,
+ &dev_attr_wheel.attr,
+ &dev_attr_execute.attr,
+ NULL
+};
- if ((ret = device_create_file(dev, &dev_attr_size)) ||
- (ret = device_create_file(dev, &dev_attr_product_id)) ||
- (ret = device_create_file(dev, &dev_attr_vendor_id)) ||
- (ret = device_create_file(dev, &dev_attr_vendor)) ||
- (ret = device_create_file(dev, &dev_attr_product)) ||
- (ret = device_create_file(dev, &dev_attr_pointer_mode)) ||
- (ret = device_create_file(dev, &dev_attr_coordinate_mode)) ||
- (ret = device_create_file(dev, &dev_attr_tool_mode)) ||
- (ret = device_create_file(dev, &dev_attr_xtilt)) ||
- (ret = device_create_file(dev, &dev_attr_ytilt)) ||
- (ret = device_create_file(dev, &dev_attr_jitter)) ||
- (ret = device_create_file(dev, &dev_attr_delay)) ||
- (ret = device_create_file(dev, &dev_attr_input_path)) ||
- (ret = device_create_file(dev, &dev_attr_event_count)) ||
- (ret = device_create_file(dev, &dev_attr_diagnostic)) ||
- (ret = device_create_file(dev, &dev_attr_odm_code)) ||
- (ret = device_create_file(dev, &dev_attr_model_code)) ||
- (ret = device_create_file(dev, &dev_attr_firmware_code)) ||
- (ret = device_create_file(dev, &dev_attr_stylus_lower)) ||
- (ret = device_create_file(dev, &dev_attr_stylus_upper)) ||
- (ret = device_create_file(dev, &dev_attr_mouse_left)) ||
- (ret = device_create_file(dev, &dev_attr_mouse_middle)) ||
- (ret = device_create_file(dev, &dev_attr_mouse_right)) ||
- (ret = device_create_file(dev, &dev_attr_wheel)) ||
- (ret = device_create_file(dev, &dev_attr_execute))) {
- err("aiptek: killing own sysfs device files\n");
- aiptek_delete_files(dev);
- }
- return ret;
-}
+static struct attribute_group aiptek_attribute_group = {
+ .attrs = aiptek_attributes,
+};
/***********************************************************************
* This routine is called when a tablet has been identified. It basically
@@ -1961,8 +1659,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct usb_endpoint_descriptor *endpoint;
struct aiptek *aiptek;
struct input_dev *inputdev;
- struct input_handle *inputhandle;
- struct list_head *node, *next;
int i;
int speeds[] = { 0,
AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1984,17 +1680,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
inputdev = input_allocate_device();
- if (!aiptek || !inputdev)
+ if (!aiptek || !inputdev) {
+ warn("aiptek: cannot allocate memory or input device");
goto fail1;
+ }
aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
GFP_ATOMIC, &aiptek->data_dma);
- if (!aiptek->data)
+ if (!aiptek->data) {
+ warn("aiptek: cannot allocate usb buffer");
goto fail1;
+ }
aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!aiptek->urb)
+ if (!aiptek->urb) {
+ warn("aiptek: cannot allocate urb");
goto fail2;
+ }
aiptek->inputdev = inputdev;
aiptek->usbdev = usbdev;
@@ -2002,6 +1704,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
aiptek->inDelay = 0;
aiptek->endDelay = 0;
aiptek->previousJitterable = 0;
+ aiptek->lastMacro = -1;
/* Set up the curSettings struct. Said struct contains the current
* programmable parameters. The newSetting struct contains changes
@@ -2054,36 +1757,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* Now program the capacities of the tablet, in terms of being
* an input device.
*/
- inputdev->evbit[0] |= BIT(EV_KEY)
- | BIT(EV_ABS)
- | BIT(EV_REL)
- | BIT(EV_MSC);
-
- inputdev->absbit[0] |= BIT(ABS_MISC);
+ for (i = 0; i < ARRAY_SIZE(eventTypes); ++i)
+ __set_bit(eventTypes[i], inputdev->evbit);
- inputdev->relbit[0] |=
- (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
+ for (i = 0; i < ARRAY_SIZE(absEvents); ++i)
+ __set_bit(absEvents[i], inputdev->absbit);
- inputdev->keybit[LONG(BTN_LEFT)] |=
- (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
+ for (i = 0; i < ARRAY_SIZE(relEvents); ++i)
+ __set_bit(relEvents[i], inputdev->relbit);
- inputdev->keybit[LONG(BTN_DIGI)] |=
- (BIT(BTN_TOOL_PEN) |
- BIT(BTN_TOOL_RUBBER) |
- BIT(BTN_TOOL_PENCIL) |
- BIT(BTN_TOOL_AIRBRUSH) |
- BIT(BTN_TOOL_BRUSH) |
- BIT(BTN_TOOL_MOUSE) |
- BIT(BTN_TOOL_LENS) |
- BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
+ __set_bit(MSC_SERIAL, inputdev->mscbit);
- inputdev->mscbit[0] = BIT(MSC_SERIAL);
+ /* Set up key and button codes */
+ for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i)
+ __set_bit(buttonEvents[i], inputdev->keybit);
- /* Programming the tablet macro keys needs to be done with a for loop
- * as the keycodes are discontiguous.
- */
for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
- set_bit(macroKeyEvents[i], inputdev->keybit);
+ __set_bit(macroKeyEvents[i], inputdev->keybit);
/*
* Program the input device coordinate capacities. We do not yet
@@ -2134,25 +1824,11 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
}
}
- /* Register the tablet as an Input Device
- */
- err = input_register_device(aiptek->inputdev);
- if (err)
+ /* Murphy says that some day someone will have a tablet that fails the
+ above test. That's you, Frederic Rodrigo */
+ if (i == ARRAY_SIZE(speeds)) {
+ info("input: Aiptek tried all speeds, no sane response");
goto fail2;
-
- /* We now will look for the evdev device which is mapped to
- * the tablet. The partial name is kept in the link list of
- * input_handles associated with this input device.
- * What identifies an evdev input_handler is that it begins
- * with 'event', continues with a digit, and that in turn
- * is mapped to input/eventN.
- */
- list_for_each_safe(node, next, &inputdev->h_list) {
- inputhandle = to_handle(node);
- if (strncmp(inputhandle->name, "event", 5) == 0) {
- strcpy(aiptek->features.inputPath, inputhandle->name);
- break;
- }
}
/* Associate this driver's struct with the usb interface.
@@ -2161,18 +1837,27 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* Set up the sysfs files
*/
- aiptek_add_files(&intf->dev);
+ err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
+ if (err) {
+ warn("aiptek: cannot create sysfs group err: %d", err);
+ goto fail3;
+ }
- /* Make sure the evdev module is loaded. Assuming evdev IS a module :-)
+ /* Register the tablet as an Input Device
*/
- if (request_module("evdev") != 0)
- info("aiptek: error loading 'evdev' module");
-
+ err = input_register_device(aiptek->inputdev);
+ if (err) {
+ warn("aiptek: input_register_device returned err: %d", err);
+ goto fail4;
+ }
return 0;
+ fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
+ fail3: usb_free_urb(aiptek->urb);
fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
aiptek->data_dma);
- fail1: input_free_device(inputdev);
+ fail1: usb_set_intfdata(intf, NULL);
+ input_free_device(inputdev);
kfree(aiptek);
return err;
}
@@ -2192,7 +1877,7 @@ static void aiptek_disconnect(struct usb_interface *intf)
*/
usb_kill_urb(aiptek->urb);
input_unregister_device(aiptek->inputdev);
- aiptek_delete_files(&intf->dev);
+ sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
usb_free_urb(aiptek->urb);
usb_buffer_free(interface_to_usbdev(intf),
AIPTEK_PACKET_LENGTH,
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index ef01a807ec0f..6542edb6f76e 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -11,7 +11,7 @@
* Copyright (c) 2000 Daniel Egger <egger@suse.de>
* Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
* Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
- * Copyright (c) 2002-2006 Ping Cheng <pingc@wacom.com>
+ * Copyright (c) 2002-2007 Ping Cheng <pingc@wacom.com>
*
* ChangeLog:
* v0.1 (vp) - Initial release
@@ -62,8 +62,9 @@
* - Minor data report fix
* v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
* - where wacom_sys.c deals with system specific code,
- * - and wacom_wac.c deals with Wacom specific code
+ * - and wacom_wac.c deals with Wacom specific code
* - Support Intuos3 4x6
+ * v1.47 (pc) - Added support for Bamboo
*/
/*
@@ -84,7 +85,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.46"
+#define DRIVER_VERSION "v1.47"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
#define DRIVER_LICENSE "GPL"
@@ -123,6 +124,7 @@ extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wa
extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern __u16 wacom_le16_to_cpu(unsigned char *data);
extern __u16 wacom_be16_to_cpu(unsigned char *data);
extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 83bddef66067..064e123c9b76 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -138,6 +138,12 @@ static void wacom_close(struct input_dev *dev)
usb_kill_urb(wacom->irq);
}
+void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+ input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5);
+ input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
+}
+
void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
input_dev->evbit[0] |= BIT(EV_MSC);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 7661f03a2db2..fc03ba256f4c 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -178,7 +178,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
case 2: /* Mouse with wheel */
wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
- if (wacom->features->type == WACOM_G4) {
+ if (wacom->features->type == WACOM_G4 ||
+ wacom->features->type == WACOM_MO) {
rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
wacom_report_rel(wcombo, REL_WHEEL, -rw);
} else
@@ -190,7 +191,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
id = CURSOR_DEVICE_ID;
wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
- if (wacom->features->type == WACOM_G4)
+ if (wacom->features->type == WACOM_G4 ||
+ wacom->features->type == WACOM_MO)
wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
else
wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
@@ -226,7 +228,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
}
/* send pad data */
- if (wacom->features->type == WACOM_G4) {
+ switch (wacom->features->type) {
+ case WACOM_G4:
if (data[7] & 0xf8) {
wacom_input_sync(wcombo); /* sync last event */
wacom->id[1] = 1;
@@ -247,6 +250,33 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_MISC, 0);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
}
+ break;
+ case WACOM_MO:
+ if ((data[7] & 0xf8) || (data[8] & 0x80)) {
+ wacom_input_sync(wcombo); /* sync last event */
+ wacom->id[1] = 1;
+ wacom->serial[1] = (data[7] & 0xf8);
+ wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
+ wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
+ wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
+ wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
+ wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
+ wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
+ wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+ wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+ } else if (wacom->id[1]) {
+ wacom_input_sync(wcombo); /* sync last event */
+ wacom->id[1] = 0;
+ wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
+ wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
+ wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
+ wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
+ wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
+ wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+ wacom_report_abs(wcombo, ABS_MISC, 0);
+ wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+ }
+ break;
}
return 1;
}
@@ -331,7 +361,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_EXTRA, 0);
wacom_report_abs(wcombo, ABS_THROTTLE, 0);
wacom_report_abs(wcombo, ABS_RZ, 0);
- } else {
+ } else {
wacom_report_abs(wcombo, ABS_PRESSURE, 0);
wacom_report_abs(wcombo, ABS_TILT_X, 0);
wacom_report_abs(wcombo, ABS_TILT_Y, 0);
@@ -423,9 +453,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
return result-1;
/* Only large I3 and I1 & I2 support Lense Cursor */
- if((wacom->tool[idx] == BTN_TOOL_LENS)
+ if ((wacom->tool[idx] == BTN_TOOL_LENS)
&& ((wacom->features->type == INTUOS3)
- || (wacom->features->type == INTUOS3S)))
+ || (wacom->features->type == INTUOS3S)))
return 0;
/* Cintiq doesn't send data when RDY bit isn't set */
@@ -517,6 +547,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
break;
case WACOM_G4:
case GRAPHIRE:
+ case WACOM_MO:
return (wacom_graphire_irq(wacom_wac, wcombo));
break;
case PTU:
@@ -538,6 +569,8 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
switch (wacom_wac->features->type) {
+ case WACOM_MO:
+ input_dev_mo(input_dev, wacom_wac);
case WACOM_G4:
input_dev_g4(input_dev, wacom_wac);
/* fall through */
@@ -579,6 +612,7 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE },
{ "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE },
{ "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE },
+ { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO },
{ "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
{ "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
{ "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
@@ -627,6 +661,7 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index a5e12e8756de..a302e229bb8a 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,7 @@ enum {
INTUOS3,
INTUOS3L,
CINTIQ,
+ WACOM_MO,
MAX_TYPE
};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index e5cca9bd0406..69371779806a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -177,6 +177,7 @@ config TOUCHSCREEN_USB_COMPOSITE
- some other eTurboTouch
- Gunze AHL61
- DMC TSC-10/25
+ - IRTOUCHSYSTEMS/UNITOP
Have a look at <http://linux.chapter7.ch/touchkit/> for
a usage description and the required user-space stuff.
@@ -219,4 +220,9 @@ config TOUCHSCREEN_USB_DMC_TSC10
bool "DMC TSC-10/25 device support" if EMBEDDED
depends on TOUCHSCREEN_USB_COMPOSITE
+config TOUCHSCREEN_USB_IRTOUCH
+ default y
+ bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
endif
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index e3f22852bd09..b407028ffc59 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -9,6 +9,7 @@
* - eTurboTouch
* - Gunze AHL61
* - DMC TSC-10/25
+ * - IRTOUCHSYSTEMS/UNITOP
*
* Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
* Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -110,6 +111,7 @@ enum {
DEVTYPE_ETURBO,
DEVTYPE_GUNZE,
DEVTYPE_DMC_TSC10,
+ DEVTYPE_IRTOUCH,
};
static struct usb_device_id usbtouch_devices[] = {
@@ -150,6 +152,11 @@ static struct usb_device_id usbtouch_devices[] = {
{USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10},
#endif
+#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+ {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
+ {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
+#endif
+
{}
};
@@ -416,6 +423,21 @@ static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
/*****************************************************************************
+ * IRTOUCH Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+ dev->x = (pkt[3] << 8) | pkt[2];
+ dev->y = (pkt[5] << 8) | pkt[4];
+ dev->touch = (pkt[1] & 0x03) ? 1 : 0;
+
+ return 1;
+}
+#endif
+
+
+/*****************************************************************************
* the different device descriptors
*/
static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -504,6 +526,17 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.read_data = dmc_tsc10_read_data,
},
#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+ [DEVTYPE_IRTOUCH] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .rept_size = 8,
+ .read_data = irtouch_read_data,
+ },
+#endif
};
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 2db364898e15..d2f882e98e5e 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -109,9 +109,11 @@ struct tsdev {
int open;
int minor;
char name[8];
+ struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
- struct input_handle handle;
+ struct device dev;
+
int x, y, pressure;
struct ts_calibration cal;
};
@@ -163,9 +165,13 @@ static int tsdev_open(struct inode *inode, struct file *file)
if (!tsdev || !tsdev->exist)
return -ENODEV;
+ get_device(&tsdev->dev);
+
client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
+ if (!client) {
+ error = -ENOMEM;
+ goto err_put_tsdev;
+ }
client->tsdev = tsdev;
client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0;
@@ -173,19 +179,25 @@ static int tsdev_open(struct inode *inode, struct file *file)
if (!tsdev->open++ && tsdev->exist) {
error = input_open_device(&tsdev->handle);
- if (error) {
- list_del(&client->node);
- kfree(client);
- return error;
- }
+ if (error)
+ goto err_free_client;
}
file->private_data = client;
return 0;
+
+ err_free_client:
+ list_del(&client->node);
+ kfree(client);
+ err_put_tsdev:
+ put_device(&tsdev->dev);
+ return error;
}
-static void tsdev_free(struct tsdev *tsdev)
+static void tsdev_free(struct device *dev)
{
+ struct tsdev *tsdev = container_of(dev, struct tsdev, dev);
+
tsdev_table[tsdev->minor] = NULL;
kfree(tsdev);
}
@@ -200,12 +212,10 @@ static int tsdev_release(struct inode *inode, struct file *file)
list_del(&client->node);
kfree(client);
- if (!--tsdev->open) {
- if (tsdev->exist)
- input_close_device(&tsdev->handle);
- else
- tsdev_free(tsdev);
- }
+ if (!--tsdev->open && tsdev->exist)
+ input_close_device(&tsdev->handle);
+
+ put_device(&tsdev->dev);
return 0;
}
@@ -361,7 +371,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
int x, y, tmp;
do_gettimeofday(&time);
- client->event[client->head].millisecs = time.tv_usec / 100;
+ client->event[client->head].millisecs = time.tv_usec / 1000;
client->event[client->head].pressure = tsdev->pressure;
x = tsdev->x;
@@ -388,8 +398,6 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct tsdev *tsdev;
- struct class_device *cdev;
- dev_t devt;
int minor, delta;
int error;
@@ -407,14 +415,13 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
INIT_LIST_HEAD(&tsdev->client_list);
init_waitqueue_head(&tsdev->wait);
- sprintf(tsdev->name, "ts%d", minor);
-
tsdev->exist = 1;
tsdev->minor = minor;
tsdev->handle.dev = dev;
tsdev->handle.name = tsdev->name;
tsdev->handle.handler = handler;
tsdev->handle.private = tsdev;
+ snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor);
/* Precompute the rough calibration matrix */
delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
@@ -429,36 +436,30 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
tsdev->cal.yscale = (yres << 8) / delta;
tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
- tsdev_table[minor] = tsdev;
-
- devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+ snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id),
+ "ts%d", minor);
+ tsdev->dev.class = &input_class;
+ tsdev->dev.parent = &dev->dev;
+ tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor);
+ tsdev->dev.release = tsdev_free;
+ device_initialize(&tsdev->dev);
- cdev = class_device_create(&input_class, &dev->cdev, devt,
- dev->cdev.dev, tsdev->name);
- if (IS_ERR(cdev)) {
- error = PTR_ERR(cdev);
- goto err_free_tsdev;
- }
+ tsdev_table[minor] = tsdev;
- /* temporary symlink to keep userspace happy */
- error = sysfs_create_link(&input_class.subsys.kobj,
- &cdev->kobj, tsdev->name);
+ error = device_add(&tsdev->dev);
if (error)
- goto err_cdev_destroy;
+ goto err_free_tsdev;
error = input_register_handle(&tsdev->handle);
if (error)
- goto err_remove_link;
+ goto err_delete_tsdev;
return 0;
- err_remove_link:
- sysfs_remove_link(&input_class.subsys.kobj, tsdev->name);
- err_cdev_destroy:
- class_device_destroy(&input_class, devt);
+ err_delete_tsdev:
+ device_del(&tsdev->dev);
err_free_tsdev:
- tsdev_table[minor] = NULL;
- kfree(tsdev);
+ put_device(&tsdev->dev);
return error;
}
@@ -468,10 +469,8 @@ static void tsdev_disconnect(struct input_handle *handle)
struct tsdev_client *client;
input_unregister_handle(handle);
+ device_del(&tsdev->dev);
- sysfs_remove_link(&input_class.subsys.kobj, tsdev->name);
- class_device_destroy(&input_class,
- MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
tsdev->exist = 0;
if (tsdev->open) {
@@ -479,8 +478,9 @@ static void tsdev_disconnect(struct input_handle *handle)
list_for_each_entry(client, &tsdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&tsdev->wait);
- } else
- tsdev_free(tsdev);
+ }
+
+ put_device(&tsdev->dev);
}
static const struct input_device_id tsdev_ids[] = {
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
index ac515b0ef67c..ea55654e5948 100644
--- a/drivers/misc/eeprom_93cx6.c
+++ b/drivers/misc/eeprom_93cx6.c
@@ -55,10 +55,10 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
/*
* Add a short delay for the pulse to work.
- * According to the specifications the minimal time
- * should be 450ns so a 1us delay is sufficient.
+ * According to the specifications the "maximum minimum"
+ * time should be 450ns.
*/
- udelay(1);
+ ndelay(450);
}
static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 9320a8c73239..a49cb9737cd8 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -14,3 +14,21 @@ config MMC_BLOCK
mount the filesystem. Almost everyone wishing MMC support
should say Y or M here.
+config MMC_BLOCK_BOUNCE
+ bool "Use bounce buffer for simple hosts"
+ depends on MMC_BLOCK
+ default y
+ help
+ SD/MMC is a high latency protocol where it is crucial to
+ send large requests in order to get high performance. Many
+ controllers, however, are restricted to continuous memory
+ (i.e. they can't do scatter-gather), something the kernel
+ rarely can provide.
+
+ Say Y here to help these restricted hosts by bouncing
+ requests back and forth from a large buffer. You will get
+ a big performance gain at the cost of up to 64 KiB of
+ physical memory.
+
+ If unsure, say Y here.
+
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 540ff4bea54c..cbd4b6e3e17c 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -262,7 +262,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
}
brq.data.sg = mq->sg;
- brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg);
+ brq.data.sg_len = mmc_queue_map_sg(mq);
+
+ mmc_queue_bounce_pre(mq);
if (brq.data.blocks !=
(req->nr_sectors >> (md->block_bits - 9))) {
@@ -279,6 +281,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
}
mmc_wait_for_req(card->host, &brq.mrq);
+
+ mmc_queue_bounce_post(mq);
+
if (brq.cmd.error) {
printk(KERN_ERR "%s: error %d sending read/write command\n",
req->rq_disk->disk_name, brq.cmd.error);
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dd97bc798409..4fb2089dc690 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -17,6 +17,8 @@
#include <linux/mmc/host.h>
#include "queue.h"
+#define MMC_QUEUE_BOUNCESZ 65536
+
#define MMC_QUEUE_SUSPENDED (1 << 0)
/*
@@ -118,6 +120,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
struct mmc_host *host = card->host;
u64 limit = BLK_BOUNCE_HIGH;
int ret;
+ unsigned int bouncesz;
if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
limit = *mmc_dev(host)->dma_mask;
@@ -127,21 +130,61 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
if (!mq->queue)
return -ENOMEM;
- blk_queue_prep_rq(mq->queue, mmc_prep_request);
- blk_queue_bounce_limit(mq->queue, limit);
- blk_queue_max_sectors(mq->queue, host->max_req_size / 512);
- blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
- blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
- blk_queue_max_segment_size(mq->queue, host->max_seg_size);
-
mq->queue->queuedata = mq;
mq->req = NULL;
- mq->sg = kmalloc(sizeof(struct scatterlist) * host->max_phys_segs,
- GFP_KERNEL);
- if (!mq->sg) {
- ret = -ENOMEM;
- goto cleanup_queue;
+ blk_queue_prep_rq(mq->queue, mmc_prep_request);
+
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+ if (host->max_hw_segs == 1) {
+ bouncesz = MMC_QUEUE_BOUNCESZ;
+
+ if (bouncesz > host->max_req_size)
+ bouncesz = host->max_req_size;
+ if (bouncesz > host->max_seg_size)
+ bouncesz = host->max_seg_size;
+
+ mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
+ if (!mq->bounce_buf) {
+ printk(KERN_WARNING "%s: unable to allocate "
+ "bounce buffer\n", mmc_card_name(card));
+ } else {
+ blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH);
+ blk_queue_max_sectors(mq->queue, bouncesz / 512);
+ blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
+ blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
+ blk_queue_max_segment_size(mq->queue, bouncesz);
+
+ mq->sg = kmalloc(sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (!mq->sg) {
+ ret = -ENOMEM;
+ goto free_bounce_buf;
+ }
+
+ mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
+ bouncesz / 512, GFP_KERNEL);
+ if (!mq->bounce_sg) {
+ ret = -ENOMEM;
+ goto free_sg;
+ }
+ }
+ }
+#endif
+
+ if (!mq->bounce_buf) {
+ blk_queue_bounce_limit(mq->queue, limit);
+ blk_queue_max_sectors(mq->queue, host->max_req_size / 512);
+ blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
+ blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
+ blk_queue_max_segment_size(mq->queue, host->max_seg_size);
+
+ mq->sg = kmalloc(sizeof(struct scatterlist) *
+ host->max_phys_segs, GFP_KERNEL);
+ if (!mq->sg) {
+ ret = -ENOMEM;
+ goto cleanup_queue;
+ }
}
init_MUTEX(&mq->thread_sem);
@@ -149,14 +192,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");
if (IS_ERR(mq->thread)) {
ret = PTR_ERR(mq->thread);
- goto free_sg;
+ goto free_bounce_sg;
}
return 0;
-
+ free_bounce_sg:
+ if (mq->bounce_sg)
+ kfree(mq->bounce_sg);
+ mq->bounce_sg = NULL;
free_sg:
kfree(mq->sg);
mq->sg = NULL;
+ free_bounce_buf:
+ if (mq->bounce_buf)
+ kfree(mq->bounce_buf);
+ mq->bounce_buf = NULL;
cleanup_queue:
blk_cleanup_queue(mq->queue);
return ret;
@@ -178,9 +228,17 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
/* Then terminate our worker thread */
kthread_stop(mq->thread);
+ if (mq->bounce_sg)
+ kfree(mq->bounce_sg);
+ mq->bounce_sg = NULL;
+
kfree(mq->sg);
mq->sg = NULL;
+ if (mq->bounce_buf)
+ kfree(mq->bounce_buf);
+ mq->bounce_buf = NULL;
+
blk_cleanup_queue(mq->queue);
mq->card = NULL;
@@ -231,3 +289,108 @@ void mmc_queue_resume(struct mmc_queue *mq)
}
}
+static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
+ struct scatterlist *src, unsigned int src_len)
+{
+ unsigned int chunk;
+ char *dst_buf, *src_buf;
+ unsigned int dst_size, src_size;
+
+ dst_buf = NULL;
+ src_buf = NULL;
+ dst_size = 0;
+ src_size = 0;
+
+ while (src_len) {
+ BUG_ON(dst_len == 0);
+
+ if (dst_size == 0) {
+ dst_buf = page_address(dst->page) + dst->offset;
+ dst_size = dst->length;
+ }
+
+ if (src_size == 0) {
+ src_buf = page_address(src->page) + src->offset;
+ src_size = src->length;
+ }
+
+ chunk = min(dst_size, src_size);
+
+ memcpy(dst_buf, src_buf, chunk);
+
+ dst_buf += chunk;
+ src_buf += chunk;
+ dst_size -= chunk;
+ src_size -= chunk;
+
+ if (dst_size == 0) {
+ dst++;
+ dst_len--;
+ }
+
+ if (src_size == 0) {
+ src++;
+ src_len--;
+ }
+ }
+}
+
+unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
+{
+ unsigned int sg_len;
+
+ if (!mq->bounce_buf)
+ return blk_rq_map_sg(mq->queue, mq->req, mq->sg);
+
+ BUG_ON(!mq->bounce_sg);
+
+ sg_len = blk_rq_map_sg(mq->queue, mq->req, mq->bounce_sg);
+
+ mq->bounce_sg_len = sg_len;
+
+ /*
+ * Shortcut in the event we only get a single entry.
+ */
+ if (sg_len == 1) {
+ memcpy(mq->sg, mq->bounce_sg, sizeof(struct scatterlist));
+ return 1;
+ }
+
+ mq->sg[0].page = virt_to_page(mq->bounce_buf);
+ mq->sg[0].offset = offset_in_page(mq->bounce_buf);
+ mq->sg[0].length = 0;
+
+ while (sg_len) {
+ mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
+ sg_len--;
+ }
+
+ return 1;
+}
+
+void mmc_queue_bounce_pre(struct mmc_queue *mq)
+{
+ if (!mq->bounce_buf)
+ return;
+
+ if (mq->bounce_sg_len == 1)
+ return;
+ if (rq_data_dir(mq->req) != WRITE)
+ return;
+
+ copy_sg(mq->sg, 1, mq->bounce_sg, mq->bounce_sg_len);
+}
+
+void mmc_queue_bounce_post(struct mmc_queue *mq)
+{
+ if (!mq->bounce_buf)
+ return;
+
+ if (mq->bounce_sg_len == 1)
+ return;
+ if (rq_data_dir(mq->req) != READ)
+ return;
+
+ copy_sg(mq->bounce_sg, mq->bounce_sg_len, mq->sg, 1);
+}
+
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 1590b3f3f1f7..64e66e0d4994 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -14,6 +14,9 @@ struct mmc_queue {
void *data;
struct request_queue *queue;
struct scatterlist *sg;
+ char *bounce_buf;
+ struct scatterlist *bounce_sg;
+ unsigned int bounce_sg_len;
};
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
@@ -21,4 +24,8 @@ extern void mmc_cleanup_queue(struct mmc_queue *);
extern void mmc_queue_suspend(struct mmc_queue *);
extern void mmc_queue_resume(struct mmc_queue *);
+extern unsigned int mmc_queue_map_sg(struct mmc_queue *);
+extern void mmc_queue_bounce_pre(struct mmc_queue *);
+extern void mmc_queue_bounce_post(struct mmc_queue *);
+
#endif
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 1075b02ae754..3fdd08c7f143 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,5 +7,6 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
endif
obj-$(CONFIG_MMC) += mmc_core.o
-mmc_core-y := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o
+mmc_core-y := core.o sysfs.o bus.o host.o \
+ mmc.o mmc_ops.o sd.o sd_ops.o
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
new file mode 100644
index 000000000000..348b566bf4fd
--- /dev/null
+++ b/drivers/mmc/core/bus.c
@@ -0,0 +1,253 @@
+/*
+ * linux/drivers/mmc/core/bus.c
+ *
+ * Copyright (C) 2003 Russell King, All Rights Reserved.
+ * Copyright (C) 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMC card bus driver model
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include "sysfs.h"
+#include "core.h"
+#include "bus.h"
+
+#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
+#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
+
+static ssize_t mmc_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mmc_card *card = dev_to_mmc_card(dev);
+
+ switch (card->type) {
+ case MMC_TYPE_MMC:
+ return sprintf(buf, "MMC\n");
+ case MMC_TYPE_SD:
+ return sprintf(buf, "SD\n");
+ default:
+ return -EFAULT;
+ }
+}
+
+static struct device_attribute mmc_dev_attrs[] = {
+ MMC_ATTR_RO(type),
+ __ATTR_NULL,
+};
+
+/*
+ * This currently matches any MMC driver to any MMC card - drivers
+ * themselves make the decision whether to drive this card in their
+ * probe method.
+ */
+static int mmc_bus_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static int
+mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
+ int buf_size)
+{
+ struct mmc_card *card = dev_to_mmc_card(dev);
+ int retval = 0, i = 0, length = 0;
+
+#define add_env(fmt,val) do { \
+ retval = add_uevent_var(envp, num_envp, &i, \
+ buf, buf_size, &length, \
+ fmt, val); \
+ if (retval) \
+ return retval; \
+} while (0);
+
+ switch (card->type) {
+ case MMC_TYPE_MMC:
+ add_env("MMC_TYPE=%s", "MMC");
+ break;
+ case MMC_TYPE_SD:
+ add_env("MMC_TYPE=%s", "SD");
+ break;
+ }
+
+ add_env("MMC_NAME=%s", mmc_card_name(card));
+
+#undef add_env
+
+ envp[i] = NULL;
+
+ return 0;
+}
+
+static int mmc_bus_probe(struct device *dev)
+{
+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
+ struct mmc_card *card = dev_to_mmc_card(dev);
+
+ return drv->probe(card);
+}
+
+static int mmc_bus_remove(struct device *dev)
+{
+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
+ struct mmc_card *card = dev_to_mmc_card(dev);
+
+ drv->remove(card);
+
+ return 0;
+}
+
+static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+{
+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
+ struct mmc_card *card = dev_to_mmc_card(dev);
+ int ret = 0;
+
+ if (dev->driver && drv->suspend)
+ ret = drv->suspend(card, state);
+ return ret;
+}
+
+static int mmc_bus_resume(struct device *dev)
+{
+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
+ struct mmc_card *card = dev_to_mmc_card(dev);
+ int ret = 0;
+
+ if (dev->driver && drv->resume)
+ ret = drv->resume(card);
+ return ret;
+}
+
+static struct bus_type mmc_bus_type = {
+ .name = "mmc",
+ .dev_attrs = mmc_dev_attrs,
+ .match = mmc_bus_match,
+ .uevent = mmc_bus_uevent,
+ .probe = mmc_bus_probe,
+ .remove = mmc_bus_remove,
+ .suspend = mmc_bus_suspend,
+ .resume = mmc_bus_resume,
+};
+
+int mmc_register_bus(void)
+{
+ return bus_register(&mmc_bus_type);
+}
+
+void mmc_unregister_bus(void)
+{
+ bus_unregister(&mmc_bus_type);
+}
+
+/**
+ * mmc_register_driver - register a media driver
+ * @drv: MMC media driver
+ */
+int mmc_register_driver(struct mmc_driver *drv)
+{
+ drv->drv.bus = &mmc_bus_type;
+ return driver_register(&drv->drv);
+}
+
+EXPORT_SYMBOL(mmc_register_driver);
+
+/**
+ * mmc_unregister_driver - unregister a media driver
+ * @drv: MMC media driver
+ */
+void mmc_unregister_driver(struct mmc_driver *drv)
+{
+ drv->drv.bus = &mmc_bus_type;
+ driver_unregister(&drv->drv);
+}
+
+EXPORT_SYMBOL(mmc_unregister_driver);
+
+static void mmc_release_card(struct device *dev)
+{
+ struct mmc_card *card = dev_to_mmc_card(dev);
+
+ kfree(card);
+}
+
+/*
+ * Allocate and initialise a new MMC card structure.
+ */
+struct mmc_card *mmc_alloc_card(struct mmc_host *host)
+{
+ struct mmc_card *card;
+
+ card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
+ if (!card)
+ return ERR_PTR(-ENOMEM);
+
+ memset(card, 0, sizeof(struct mmc_card));
+
+ card->host = host;
+
+ device_initialize(&card->dev);
+
+ card->dev.parent = mmc_classdev(host);
+ card->dev.bus = &mmc_bus_type;
+ card->dev.release = mmc_release_card;
+
+ return card;
+}
+
+/*
+ * Register a new MMC card with the driver model.
+ */
+int mmc_add_card(struct mmc_card *card)
+{
+ int ret;
+
+ snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
+ "%s:%04x", mmc_hostname(card->host), card->rca);
+
+ card->dev.uevent_suppress = 1;
+
+ ret = device_add(&card->dev);
+ if (ret)
+ return ret;
+
+ if (card->host->bus_ops->sysfs_add) {
+ ret = card->host->bus_ops->sysfs_add(card->host, card);
+ if (ret) {
+ device_del(&card->dev);
+ return ret;
+ }
+ }
+
+ card->dev.uevent_suppress = 0;
+
+ kobject_uevent(&card->dev.kobj, KOBJ_ADD);
+
+ mmc_card_set_present(card);
+
+ return 0;
+}
+
+/*
+ * Unregister a new MMC card with the driver model, and
+ * (eventually) free it.
+ */
+void mmc_remove_card(struct mmc_card *card)
+{
+ if (mmc_card_present(card)) {
+ if (card->host->bus_ops->sysfs_remove)
+ card->host->bus_ops->sysfs_remove(card->host, card);
+ device_del(&card->dev);
+ }
+
+ put_device(&card->dev);
+}
+
diff --git a/drivers/mmc/core/bus.h b/drivers/mmc/core/bus.h
new file mode 100644
index 000000000000..4f35431116a8
--- /dev/null
+++ b/drivers/mmc/core/bus.h
@@ -0,0 +1,22 @@
+/*
+ * linux/drivers/mmc/core/bus.h
+ *
+ * Copyright (C) 2003 Russell King, All Rights Reserved.
+ * Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _MMC_CORE_BUS_H
+#define _MMC_CORE_BUS_H
+
+struct mmc_card *mmc_alloc_card(struct mmc_host *host);
+int mmc_add_card(struct mmc_card *card);
+void mmc_remove_card(struct mmc_card *card);
+
+int mmc_register_bus(void);
+void mmc_unregister_bus(void);
+
+#endif
+
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7385acfa1dd9..b5d8a6d90cca 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -27,7 +27,8 @@
#include <linux/mmc/sd.h>
#include "core.h"
-#include "sysfs.h"
+#include "bus.h"
+#include "host.h"
#include "mmc_ops.h"
#include "sd_ops.h"
@@ -35,6 +36,25 @@
extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);
+static struct workqueue_struct *workqueue;
+
+/*
+ * Internal function. Schedule delayed work in the MMC work queue.
+ */
+static int mmc_schedule_delayed_work(struct delayed_work *work,
+ unsigned long delay)
+{
+ return queue_delayed_work(workqueue, work, delay);
+}
+
+/*
+ * Internal function. Flush all scheduled work from the MMC work queue.
+ */
+static void mmc_flush_scheduled_work(void)
+{
+ flush_workqueue(workqueue);
+}
+
/**
* mmc_request_done - finish processing an MMC request
* @host: MMC host which completed request
@@ -369,22 +389,6 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
}
/*
- * Allocate a new MMC card
- */
-struct mmc_card *mmc_alloc_card(struct mmc_host *host)
-{
- struct mmc_card *card;
-
- card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
- if (!card)
- return ERR_PTR(-ENOMEM);
-
- mmc_init_card(card, host);
-
- return card;
-}
-
-/*
* Apply power to the MMC stack. This is a two-stage process.
* First, we enable power to the card without the clock running.
* We then wait a bit for the power to stabilise. Finally,
@@ -512,7 +516,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
EXPORT_SYMBOL(mmc_detect_change);
-static void mmc_rescan(struct work_struct *work)
+void mmc_rescan(struct work_struct *work)
{
struct mmc_host *host =
container_of(work, struct mmc_host, detect.work);
@@ -561,69 +565,13 @@ static void mmc_rescan(struct work_struct *work)
}
}
-
-/**
- * mmc_alloc_host - initialise the per-host structure.
- * @extra: sizeof private data structure
- * @dev: pointer to host device model structure
- *
- * Initialise the per-host structure.
- */
-struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
+void mmc_start_host(struct mmc_host *host)
{
- struct mmc_host *host;
-
- host = mmc_alloc_host_sysfs(extra, dev);
- if (host) {
- spin_lock_init(&host->lock);
- init_waitqueue_head(&host->wq);
- INIT_DELAYED_WORK(&host->detect, mmc_rescan);
-
- /*
- * By default, hosts do not support SGIO or large requests.
- * They have to set these according to their abilities.
- */
- host->max_hw_segs = 1;
- host->max_phys_segs = 1;
- host->max_seg_size = PAGE_CACHE_SIZE;
-
- host->max_req_size = PAGE_CACHE_SIZE;
- host->max_blk_size = 512;
- host->max_blk_count = PAGE_CACHE_SIZE / 512;
- }
-
- return host;
-}
-
-EXPORT_SYMBOL(mmc_alloc_host);
-
-/**
- * mmc_add_host - initialise host hardware
- * @host: mmc host
- */
-int mmc_add_host(struct mmc_host *host)
-{
- int ret;
-
- ret = mmc_add_host_sysfs(host);
- if (ret == 0) {
- mmc_power_off(host);
- mmc_detect_change(host, 0);
- }
-
- return ret;
+ mmc_power_off(host);
+ mmc_detect_change(host, 0);
}
-EXPORT_SYMBOL(mmc_add_host);
-
-/**
- * mmc_remove_host - remove host hardware
- * @host: mmc host
- *
- * Unregister and remove all cards associated with this host,
- * and power down the MMC bus.
- */
-void mmc_remove_host(struct mmc_host *host)
+void mmc_stop_host(struct mmc_host *host)
{
#ifdef CONFIG_MMC_DEBUG
unsigned long flags;
@@ -648,24 +596,8 @@ void mmc_remove_host(struct mmc_host *host)
BUG_ON(host->card);
mmc_power_off(host);
- mmc_remove_host_sysfs(host);
}
-EXPORT_SYMBOL(mmc_remove_host);
-
-/**
- * mmc_free_host - free the host structure
- * @host: mmc host
- *
- * Free the host once all references to it have been dropped.
- */
-void mmc_free_host(struct mmc_host *host)
-{
- mmc_free_host_sysfs(host);
-}
-
-EXPORT_SYMBOL(mmc_free_host);
-
#ifdef CONFIG_PM
/**
@@ -726,4 +658,31 @@ EXPORT_SYMBOL(mmc_resume_host);
#endif
+static int __init mmc_init(void)
+{
+ int ret;
+
+ workqueue = create_singlethread_workqueue("kmmcd");
+ if (!workqueue)
+ return -ENOMEM;
+
+ ret = mmc_register_bus();
+ if (ret == 0) {
+ ret = mmc_register_host_class();
+ if (ret)
+ mmc_unregister_bus();
+ }
+ return ret;
+}
+
+static void __exit mmc_exit(void)
+{
+ mmc_unregister_host_class();
+ mmc_unregister_bus();
+ destroy_workqueue(workqueue);
+}
+
+module_init(mmc_init);
+module_exit(mmc_exit);
+
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 177264d090ac..ae006b30dd86 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -18,6 +18,8 @@
struct mmc_bus_ops {
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
+ int (*sysfs_add)(struct mmc_host *, struct mmc_card *card);
+ void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card);
void (*suspend)(struct mmc_host *);
void (*resume)(struct mmc_host *);
};
@@ -54,8 +56,6 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
-struct mmc_card *mmc_alloc_card(struct mmc_host *host);
-
static inline void mmc_delay(unsigned int ms)
{
if (ms < 1000 / HZ) {
@@ -66,5 +66,9 @@ static inline void mmc_delay(unsigned int ms)
}
}
+void mmc_rescan(struct work_struct *work);
+void mmc_start_host(struct mmc_host *host);
+void mmc_stop_host(struct mmc_host *host);
+
#endif
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
new file mode 100644
index 000000000000..1433d95c40bb
--- /dev/null
+++ b/drivers/mmc/core/host.c
@@ -0,0 +1,156 @@
+/*
+ * linux/drivers/mmc/core/host.c
+ *
+ * Copyright (C) 2003 Russell King, All Rights Reserved.
+ * Copyright (C) 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMC host class device management
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/idr.h>
+#include <linux/pagemap.h>
+
+#include <linux/mmc/host.h>
+
+#include "core.h"
+#include "host.h"
+
+#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
+
+static void mmc_host_classdev_release(struct device *dev)
+{
+ struct mmc_host *host = cls_dev_to_mmc_host(dev);
+ kfree(host);
+}
+
+static struct class mmc_host_class = {
+ .name = "mmc_host",
+ .dev_release = mmc_host_classdev_release,
+};
+
+int mmc_register_host_class(void)
+{
+ return class_register(&mmc_host_class);
+}
+
+void mmc_unregister_host_class(void)
+{
+ class_unregister(&mmc_host_class);
+}
+
+static DEFINE_IDR(mmc_host_idr);
+static DEFINE_SPINLOCK(mmc_host_lock);
+
+/**
+ * mmc_alloc_host - initialise the per-host structure.
+ * @extra: sizeof private data structure
+ * @dev: pointer to host device model structure
+ *
+ * Initialise the per-host structure.
+ */
+struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
+{
+ struct mmc_host *host;
+
+ host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
+ if (!host)
+ return NULL;
+
+ memset(host, 0, sizeof(struct mmc_host) + extra);
+
+ host->parent = dev;
+ host->class_dev.parent = dev;
+ host->class_dev.class = &mmc_host_class;
+ device_initialize(&host->class_dev);
+
+ spin_lock_init(&host->lock);
+ init_waitqueue_head(&host->wq);
+ INIT_DELAYED_WORK(&host->detect, mmc_rescan);
+
+ /*
+ * By default, hosts do not support SGIO or large requests.
+ * They have to set these according to their abilities.
+ */
+ host->max_hw_segs = 1;
+ host->max_phys_segs = 1;
+ host->max_seg_size = PAGE_CACHE_SIZE;
+
+ host->max_req_size = PAGE_CACHE_SIZE;
+ host->max_blk_size = 512;
+ host->max_blk_count = PAGE_CACHE_SIZE / 512;
+
+ return host;
+}
+
+EXPORT_SYMBOL(mmc_alloc_host);
+
+/**
+ * mmc_add_host - initialise host hardware
+ * @host: mmc host
+ */
+int mmc_add_host(struct mmc_host *host)
+{
+ int err;
+
+ if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
+ return -ENOMEM;
+
+ spin_lock(&mmc_host_lock);
+ err = idr_get_new(&mmc_host_idr, host, &host->index);
+ spin_unlock(&mmc_host_lock);
+ if (err)
+ return err;
+
+ snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
+ "mmc%d", host->index);
+
+ err = device_add(&host->class_dev);
+ if (err)
+ return err;
+
+ mmc_start_host(host);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(mmc_add_host);
+
+/**
+ * mmc_remove_host - remove host hardware
+ * @host: mmc host
+ *
+ * Unregister and remove all cards associated with this host,
+ * and power down the MMC bus.
+ */
+void mmc_remove_host(struct mmc_host *host)
+{
+ mmc_stop_host(host);
+
+ device_del(&host->class_dev);
+
+ spin_lock(&mmc_host_lock);
+ idr_remove(&mmc_host_idr, host->index);
+ spin_unlock(&mmc_host_lock);
+}
+
+EXPORT_SYMBOL(mmc_remove_host);
+
+/**
+ * mmc_free_host - free the host structure
+ * @host: mmc host
+ *
+ * Free the host once all references to it have been dropped.
+ */
+void mmc_free_host(struct mmc_host *host)
+{
+ put_device(&host->class_dev);
+}
+
+EXPORT_SYMBOL(mmc_free_host);
+
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
new file mode 100644
index 000000000000..c2dc3d2d9f9a
--- /dev/null
+++ b/drivers/mmc/core/host.h
@@ -0,0 +1,18 @@
+/*
+ * linux/drivers/mmc/core/host.h
+ *
+ * Copyright (C) 2003 Russell King, All Rights Reserved.
+ * Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _MMC_CORE_HOST_H
+#define _MMC_CORE_HOST_H
+
+int mmc_register_host_class(void);
+void mmc_unregister_host_class(void);
+
+#endif
+
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 42cc2867ed7d..66f85bfa8dbb 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -18,6 +18,7 @@
#include "core.h"
#include "sysfs.h"
+#include "bus.h"
#include "mmc_ops.h"
static const unsigned int tran_exp[] = {
@@ -236,7 +237,7 @@ out:
* In the case of a resume, "curcard" will contain the card
* we're trying to reinitialise.
*/
-static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
+static int mmc_init_card(struct mmc_host *host, u32 ocr,
struct mmc_card *oldcard)
{
struct mmc_card *card;
@@ -413,8 +414,7 @@ static void mmc_detect(struct mmc_host *host)
mmc_release_host(host);
if (err != MMC_ERR_NONE) {
- mmc_remove_card(host->card);
- host->card = NULL;
+ mmc_remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
@@ -422,6 +422,53 @@ static void mmc_detect(struct mmc_host *host)
}
}
+MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
+ card->raw_cid[2], card->raw_cid[3]);
+MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
+ card->raw_csd[2], card->raw_csd[3]);
+MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev);
+MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev);
+MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid);
+MMC_ATTR_FN(name, "%s\n", card->cid.prod_name);
+MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid);
+MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial);
+
+static struct device_attribute mmc_dev_attrs[] = {
+ MMC_ATTR_RO(cid),
+ MMC_ATTR_RO(csd),
+ MMC_ATTR_RO(date),
+ MMC_ATTR_RO(fwrev),
+ MMC_ATTR_RO(hwrev),
+ MMC_ATTR_RO(manfid),
+ MMC_ATTR_RO(name),
+ MMC_ATTR_RO(oemid),
+ MMC_ATTR_RO(serial),
+ __ATTR_NULL,
+};
+
+/*
+ * Adds sysfs entries as relevant.
+ */
+static int mmc_sysfs_add(struct mmc_host *host, struct mmc_card *card)
+{
+ int ret;
+
+ ret = mmc_add_attrs(card, mmc_dev_attrs);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * Removes the sysfs entries added by mmc_sysfs_add().
+ */
+static void mmc_sysfs_remove(struct mmc_host *host, struct mmc_card *card)
+{
+ mmc_remove_attrs(card, mmc_dev_attrs);
+}
+
#ifdef CONFIG_MMC_UNSAFE_RESUME
/*
@@ -453,11 +500,9 @@ static void mmc_resume(struct mmc_host *host)
mmc_claim_host(host);
- err = mmc_sd_init_card(host, host->ocr, host->card);
+ err = mmc_init_card(host, host->ocr, host->card);
if (err != MMC_ERR_NONE) {
- mmc_remove_card(host->card);
- host->card = NULL;
-
+ mmc_remove(host);
mmc_detach_bus(host);
}
@@ -474,6 +519,8 @@ static void mmc_resume(struct mmc_host *host)
static const struct mmc_bus_ops mmc_ops = {
.remove = mmc_remove,
.detect = mmc_detect,
+ .sysfs_add = mmc_sysfs_add,
+ .sysfs_remove = mmc_sysfs_remove,
.suspend = mmc_suspend,
.resume = mmc_resume,
};
@@ -512,13 +559,13 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
/*
* Detect and init the card.
*/
- err = mmc_sd_init_card(host, host->ocr, NULL);
+ err = mmc_init_card(host, host->ocr, NULL);
if (err != MMC_ERR_NONE)
goto err;
mmc_release_host(host);
- err = mmc_register_card(host->card);
+ err = mmc_add_card(host->card);
if (err)
goto reclaim_host;
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 918477c490b0..1240684083f1 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -19,11 +19,10 @@
#include "core.h"
#include "sysfs.h"
+#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"
-#include "core.h"
-
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
0, 0, 0, 0
@@ -487,8 +486,7 @@ static void mmc_sd_detect(struct mmc_host *host)
mmc_release_host(host);
if (err != MMC_ERR_NONE) {
- mmc_remove_card(host->card);
- host->card = NULL;
+ mmc_sd_remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
@@ -496,6 +494,55 @@ static void mmc_sd_detect(struct mmc_host *host)
}
}
+MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
+ card->raw_cid[2], card->raw_cid[3]);
+MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
+ card->raw_csd[2], card->raw_csd[3]);
+MMC_ATTR_FN(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
+MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev);
+MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev);
+MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid);
+MMC_ATTR_FN(name, "%s\n", card->cid.prod_name);
+MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid);
+MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial);
+
+static struct device_attribute mmc_sd_dev_attrs[] = {
+ MMC_ATTR_RO(cid),
+ MMC_ATTR_RO(csd),
+ MMC_ATTR_RO(scr),
+ MMC_ATTR_RO(date),
+ MMC_ATTR_RO(fwrev),
+ MMC_ATTR_RO(hwrev),
+ MMC_ATTR_RO(manfid),
+ MMC_ATTR_RO(name),
+ MMC_ATTR_RO(oemid),
+ MMC_ATTR_RO(serial),
+ __ATTR_NULL,
+};
+
+/*
+ * Adds sysfs entries as relevant.
+ */
+static int mmc_sd_sysfs_add(struct mmc_host *host, struct mmc_card *card)
+{
+ int ret;
+
+ ret = mmc_add_attrs(card, mmc_sd_dev_attrs);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * Removes the sysfs entries added by mmc_sysfs_add().
+ */
+static void mmc_sd_sysfs_remove(struct mmc_host *host, struct mmc_card *card)
+{
+ mmc_remove_attrs(card, mmc_sd_dev_attrs);
+}
+
#ifdef CONFIG_MMC_UNSAFE_RESUME
/*
@@ -529,9 +576,7 @@ static void mmc_sd_resume(struct mmc_host *host)
err = mmc_sd_init_card(host, host->ocr, host->card);
if (err != MMC_ERR_NONE) {
- mmc_remove_card(host->card);
- host->card = NULL;
-
+ mmc_sd_remove(host);
mmc_detach_bus(host);
}
@@ -548,6 +593,8 @@ static void mmc_sd_resume(struct mmc_host *host)
static const struct mmc_bus_ops mmc_sd_ops = {
.remove = mmc_sd_remove,
.detect = mmc_sd_detect,
+ .sysfs_add = mmc_sd_sysfs_add,
+ .sysfs_remove = mmc_sd_sysfs_remove,
.suspend = mmc_sd_suspend,
.resume = mmc_sd_resume,
};
@@ -599,7 +646,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
mmc_release_host(host);
- err = mmc_register_card(host->card);
+ err = mmc_add_card(host->card);
if (err)
goto reclaim_host;
diff --git a/drivers/mmc/core/sysfs.c b/drivers/mmc/core/sysfs.c
index 843b1fbba557..00a97e70f914 100644
--- a/drivers/mmc/core/sysfs.c
+++ b/drivers/mmc/core/sysfs.c
@@ -2,6 +2,7 @@
* linux/drivers/mmc/core/sysfs.c
*
* Copyright (C) 2003 Russell King, All Rights Reserved.
+ * Copyright 2007 Pierre Ossman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -9,352 +10,34 @@
*
* MMC sysfs/driver model support.
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/device.h>
-#include <linux/idr.h>
-#include <linux/workqueue.h>
#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
#include "sysfs.h"
-#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
-#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
-#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
-
-#define MMC_ATTR(name, fmt, args...) \
-static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct mmc_card *card = dev_to_mmc_card(dev); \
- return sprintf(buf, fmt, args); \
-}
-
-MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
- card->raw_cid[2], card->raw_cid[3]);
-MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
- card->raw_csd[2], card->raw_csd[3]);
-MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
-MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
-MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
-MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
-MMC_ATTR(manfid, "0x%06x\n", card->cid.manfid);
-MMC_ATTR(name, "%s\n", card->cid.prod_name);
-MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid);
-MMC_ATTR(serial, "0x%08x\n", card->cid.serial);
-
-#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
-
-static struct device_attribute mmc_dev_attrs[] = {
- MMC_ATTR_RO(cid),
- MMC_ATTR_RO(csd),
- MMC_ATTR_RO(date),
- MMC_ATTR_RO(fwrev),
- MMC_ATTR_RO(hwrev),
- MMC_ATTR_RO(manfid),
- MMC_ATTR_RO(name),
- MMC_ATTR_RO(oemid),
- MMC_ATTR_RO(serial),
- __ATTR_NULL
-};
-
-static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr);
-
-
-static void mmc_release_card(struct device *dev)
-{
- struct mmc_card *card = dev_to_mmc_card(dev);
-
- kfree(card);
-}
-
-/*
- * This currently matches any MMC driver to any MMC card - drivers
- * themselves make the decision whether to drive this card in their
- * probe method.
- */
-static int mmc_bus_match(struct device *dev, struct device_driver *drv)
-{
- return 1;
-}
-
-static int
-mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
- int buf_size)
-{
- struct mmc_card *card = dev_to_mmc_card(dev);
- char ccc[13];
- int retval = 0, i = 0, length = 0;
-
-#define add_env(fmt,val) do { \
- retval = add_uevent_var(envp, num_envp, &i, \
- buf, buf_size, &length, \
- fmt, val); \
- if (retval) \
- return retval; \
-} while (0);
-
- for (i = 0; i < 12; i++)
- ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';
- ccc[12] = '\0';
-
- add_env("MMC_CCC=%s", ccc);
- add_env("MMC_MANFID=%06x", card->cid.manfid);
- add_env("MMC_NAME=%s", mmc_card_name(card));
- add_env("MMC_OEMID=%04x", card->cid.oemid);
-#undef add_env
- envp[i] = NULL;
-
- return 0;
-}
-
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
-{
- struct mmc_driver *drv = to_mmc_driver(dev->driver);
- struct mmc_card *card = dev_to_mmc_card(dev);
- int ret = 0;
-
- if (dev->driver && drv->suspend)
- ret = drv->suspend(card, state);
- return ret;
-}
-
-static int mmc_bus_resume(struct device *dev)
-{
- struct mmc_driver *drv = to_mmc_driver(dev->driver);
- struct mmc_card *card = dev_to_mmc_card(dev);
- int ret = 0;
-
- if (dev->driver && drv->resume)
- ret = drv->resume(card);
- return ret;
-}
-
-static int mmc_bus_probe(struct device *dev)
-{
- struct mmc_driver *drv = to_mmc_driver(dev->driver);
- struct mmc_card *card = dev_to_mmc_card(dev);
-
- return drv->probe(card);
-}
-
-static int mmc_bus_remove(struct device *dev)
-{
- struct mmc_driver *drv = to_mmc_driver(dev->driver);
- struct mmc_card *card = dev_to_mmc_card(dev);
-
- drv->remove(card);
-
- return 0;
-}
-
-static struct bus_type mmc_bus_type = {
- .name = "mmc",
- .dev_attrs = mmc_dev_attrs,
- .match = mmc_bus_match,
- .uevent = mmc_bus_uevent,
- .probe = mmc_bus_probe,
- .remove = mmc_bus_remove,
- .suspend = mmc_bus_suspend,
- .resume = mmc_bus_resume,
-};
-
-/**
- * mmc_register_driver - register a media driver
- * @drv: MMC media driver
- */
-int mmc_register_driver(struct mmc_driver *drv)
-{
- drv->drv.bus = &mmc_bus_type;
- return driver_register(&drv->drv);
-}
-
-EXPORT_SYMBOL(mmc_register_driver);
-
-/**
- * mmc_unregister_driver - unregister a media driver
- * @drv: MMC media driver
- */
-void mmc_unregister_driver(struct mmc_driver *drv)
-{
- drv->drv.bus = &mmc_bus_type;
- driver_unregister(&drv->drv);
-}
-
-EXPORT_SYMBOL(mmc_unregister_driver);
-
-
-/*
- * Internal function. Initialise a MMC card structure.
- */
-void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
-{
- memset(card, 0, sizeof(struct mmc_card));
- card->host = host;
- device_initialize(&card->dev);
- card->dev.parent = mmc_classdev(host);
- card->dev.bus = &mmc_bus_type;
- card->dev.release = mmc_release_card;
-}
-
-/*
- * Internal function. Register a new MMC card with the driver model.
- */
-int mmc_register_card(struct mmc_card *card)
+int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs)
{
- int ret;
+ int error = 0;
+ int i;
- snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
- "%s:%04x", mmc_hostname(card->host), card->rca);
-
- ret = device_add(&card->dev);
- if (ret == 0) {
- if (mmc_card_sd(card)) {
- ret = device_create_file(&card->dev, &mmc_dev_attr_scr);
- if (ret)
- device_del(&card->dev);
+ for (i = 0; attr_name(attrs[i]); i++) {
+ error = device_create_file(&card->dev, &attrs[i]);
+ if (error) {
+ while (--i >= 0)
+ device_remove_file(&card->dev, &attrs[i]);
+ break;
}
}
- if (ret == 0)
- mmc_card_set_present(card);
- return ret;
-}
-
-/*
- * Internal function. Unregister a new MMC card with the
- * driver model, and (eventually) free it.
- */
-void mmc_remove_card(struct mmc_card *card)
-{
- if (mmc_card_present(card)) {
- if (mmc_card_sd(card))
- device_remove_file(&card->dev, &mmc_dev_attr_scr);
-
- device_del(&card->dev);
- }
-
- put_device(&card->dev);
-}
-
-
-static void mmc_host_classdev_release(struct device *dev)
-{
- struct mmc_host *host = cls_dev_to_mmc_host(dev);
- kfree(host);
-}
-
-static struct class mmc_host_class = {
- .name = "mmc_host",
- .dev_release = mmc_host_classdev_release,
-};
-
-static DEFINE_IDR(mmc_host_idr);
-static DEFINE_SPINLOCK(mmc_host_lock);
-
-/*
- * Internal function. Allocate a new MMC host.
- */
-struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
-{
- struct mmc_host *host;
-
- host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
- if (host) {
- memset(host, 0, sizeof(struct mmc_host) + extra);
-
- host->parent = dev;
- host->class_dev.parent = dev;
- host->class_dev.class = &mmc_host_class;
- device_initialize(&host->class_dev);
- }
- return host;
+ return error;
}
-/*
- * Internal function. Register a new MMC host with the MMC class.
- */
-int mmc_add_host_sysfs(struct mmc_host *host)
+void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs)
{
- int err;
-
- if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
- return -ENOMEM;
-
- spin_lock(&mmc_host_lock);
- err = idr_get_new(&mmc_host_idr, host, &host->index);
- spin_unlock(&mmc_host_lock);
- if (err)
- return err;
-
- snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
- "mmc%d", host->index);
-
- return device_add(&host->class_dev);
-}
+ int i;
-/*
- * Internal function. Unregister a MMC host with the MMC class.
- */
-void mmc_remove_host_sysfs(struct mmc_host *host)
-{
- device_del(&host->class_dev);
-
- spin_lock(&mmc_host_lock);
- idr_remove(&mmc_host_idr, host->index);
- spin_unlock(&mmc_host_lock);
-}
-
-/*
- * Internal function. Free a MMC host.
- */
-void mmc_free_host_sysfs(struct mmc_host *host)
-{
- put_device(&host->class_dev);
-}
-
-static struct workqueue_struct *workqueue;
-
-/*
- * Internal function. Schedule delayed work in the MMC work queue.
- */
-int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay)
-{
- return queue_delayed_work(workqueue, work, delay);
-}
-
-/*
- * Internal function. Flush all scheduled work from the MMC work queue.
- */
-void mmc_flush_scheduled_work(void)
-{
- flush_workqueue(workqueue);
-}
-
-static int __init mmc_init(void)
-{
- int ret;
-
- workqueue = create_singlethread_workqueue("kmmcd");
- if (!workqueue)
- return -ENOMEM;
-
- ret = bus_register(&mmc_bus_type);
- if (ret == 0) {
- ret = class_register(&mmc_host_class);
- if (ret)
- bus_unregister(&mmc_bus_type);
- }
- return ret;
-}
-
-static void __exit mmc_exit(void)
-{
- class_unregister(&mmc_host_class);
- bus_unregister(&mmc_bus_type);
- destroy_workqueue(workqueue);
+ for (i = 0; attr_name(attrs[i]); i++)
+ device_remove_file(&card->dev, &attrs[i]);
}
-module_init(mmc_init);
-module_exit(mmc_exit);
diff --git a/drivers/mmc/core/sysfs.h b/drivers/mmc/core/sysfs.h
index 80e29b358282..4b8f670bd10f 100644
--- a/drivers/mmc/core/sysfs.h
+++ b/drivers/mmc/core/sysfs.h
@@ -11,17 +11,16 @@
#ifndef _MMC_CORE_SYSFS_H
#define _MMC_CORE_SYSFS_H
-void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
-int mmc_register_card(struct mmc_card *card);
-void mmc_remove_card(struct mmc_card *card);
+#define MMC_ATTR_FN(name, fmt, args...) \
+static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ struct mmc_card *card = container_of(dev, struct mmc_card, dev);\
+ return sprintf(buf, fmt, args); \
+}
-struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
-int mmc_add_host_sysfs(struct mmc_host *host);
-void mmc_remove_host_sysfs(struct mmc_host *host);
-void mmc_free_host_sysfs(struct mmc_host *host);
+#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
-int mmc_schedule_work(struct work_struct *work);
-int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay);
-void mmc_flush_scheduled_work(void);
+int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs);
+void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs);
#endif
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 5b00c194b628..28c881895ab7 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -78,8 +78,6 @@
#define DRIVER_NAME "at91_mci"
-#undef SUPPORT_4WIRE
-
#define FL_SENT_COMMAND (1 << 0)
#define FL_SENT_STOP (1 << 1)
@@ -131,7 +129,7 @@ struct at91mci_host
/*
* Copy from sg to a dma block - used for transfers
*/
-static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
+static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
{
unsigned int len, i, size;
unsigned *dmabuf = host->buffer;
@@ -180,7 +178,7 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
/*
* Prepare a dma read
*/
-static void at91mci_pre_dma_read(struct at91mci_host *host)
+static void at91_mci_pre_dma_read(struct at91mci_host *host)
{
int i;
struct scatterlist *sg;
@@ -248,7 +246,7 @@ static void at91mci_pre_dma_read(struct at91mci_host *host)
/*
* Handle after a dma read
*/
-static void at91mci_post_dma_read(struct at91mci_host *host)
+static void at91_mci_post_dma_read(struct at91mci_host *host)
{
struct mmc_command *cmd;
struct mmc_data *data;
@@ -268,8 +266,6 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
}
while (host->in_use_index < host->transfer_index) {
- unsigned int *buffer;
-
struct scatterlist *sg;
pr_debug("finishing index %d\n", host->in_use_index);
@@ -280,29 +276,31 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
- /* Swap the contents of the buffer */
- buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
- pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
-
data->bytes_xfered += sg->length;
if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
+ unsigned int *buffer;
int index;
+ /* Swap the contents of the buffer */
+ buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+ pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
+
for (index = 0; index < (sg->length / 4); index++)
buffer[index] = swab32(buffer[index]);
+
+ kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
}
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
flush_dcache_page(sg->page);
}
/* Is there another transfer to trigger? */
if (host->transfer_index < data->sg_len)
- at91mci_pre_dma_read(host);
+ at91_mci_pre_dma_read(host);
else {
+ at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
}
pr_debug("post dma read done\n");
@@ -323,7 +321,6 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
/* Now wait for cmd ready */
at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
cmd = host->cmd;
if (!cmd) return;
@@ -331,18 +328,53 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
data = cmd->data;
if (!data) return;
+ if (cmd->data->flags & MMC_DATA_MULTI) {
+ pr_debug("multiple write : wait for BLKE...\n");
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+ } else
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+
data->bytes_xfered = host->total_length;
}
+/*Handle after command sent ready*/
+static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
+{
+ if (!host->cmd)
+ return 1;
+ else if (!host->cmd->data) {
+ if (host->flags & FL_SENT_STOP) {
+ /*After multi block write, we must wait for NOTBUSY*/
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
+ } else return 1;
+ } else if (host->cmd->data->flags & MMC_DATA_WRITE) {
+ /*After sendding multi-block-write command, start DMA transfer*/
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE);
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
+ at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
+ }
+
+ /* command not completed, have to wait */
+ return 0;
+}
+
+
/*
* Enable the controller
*/
static void at91_mci_enable(struct at91mci_host *host)
{
+ unsigned int mr;
+
at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
- at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a);
+ mr = AT91_MCI_PDCMODE | 0x34a;
+
+ if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+ mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
+
+ at91_mci_write(host, AT91_MCI_MR, mr);
/* use Slot A or B (only one at same time) */
at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
@@ -358,9 +390,8 @@ static void at91_mci_disable(struct at91mci_host *host)
/*
* Send a command
- * return the interrupts to enable
*/
-static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
+static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
{
unsigned int cmdr, mr;
unsigned int block_length;
@@ -371,8 +402,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
host->cmd = cmd;
- /* Not sure if this is needed */
-#if 0
+ /* Needed for leaving busy state before CMD1 */
if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
pr_debug("Clearing timeout\n");
at91_mci_write(host, AT91_MCI_ARGR, 0);
@@ -382,7 +412,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR));
}
}
-#endif
+
cmdr = cmd->opcode;
if (mmc_resp_type(cmd) == MMC_RSP_NONE)
@@ -439,50 +469,48 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
at91_mci_write(host, ATMEL_PDC_TCR, 0);
at91_mci_write(host, ATMEL_PDC_TNPR, 0);
at91_mci_write(host, ATMEL_PDC_TNCR, 0);
+ ier = AT91_MCI_CMDRDY;
+ } else {
+ /* zero block length and PDC mode */
+ mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
+ at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
- at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
- at91_mci_write(host, AT91_MCI_CMDR, cmdr);
- return AT91_MCI_CMDRDY;
- }
-
- mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */
- at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);
-
- /*
- * Disable the PDC controller
- */
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
- if (cmdr & AT91_MCI_TRCMD_START) {
- data->bytes_xfered = 0;
- host->transfer_index = 0;
- host->in_use_index = 0;
- if (cmdr & AT91_MCI_TRDIR) {
- /*
- * Handle a read
- */
- host->buffer = NULL;
- host->total_length = 0;
-
- at91mci_pre_dma_read(host);
- ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
- }
- else {
- /*
- * Handle a write
- */
- host->total_length = block_length * blocks;
- host->buffer = dma_alloc_coherent(NULL,
- host->total_length,
- &host->physical_address, GFP_KERNEL);
-
- at91mci_sg_to_dma(host, data);
-
- pr_debug("Transmitting %d bytes\n", host->total_length);
+ /*
+ * Disable the PDC controller
+ */
+ at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
- at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
- at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
- ier = AT91_MCI_TXBUFE;
+ if (cmdr & AT91_MCI_TRCMD_START) {
+ data->bytes_xfered = 0;
+ host->transfer_index = 0;
+ host->in_use_index = 0;
+ if (cmdr & AT91_MCI_TRDIR) {
+ /*
+ * Handle a read
+ */
+ host->buffer = NULL;
+ host->total_length = 0;
+
+ at91_mci_pre_dma_read(host);
+ ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
+ }
+ else {
+ /*
+ * Handle a write
+ */
+ host->total_length = block_length * blocks;
+ host->buffer = dma_alloc_coherent(NULL,
+ host->total_length,
+ &host->physical_address, GFP_KERNEL);
+
+ at91_mci_sg_to_dma(host, data);
+
+ pr_debug("Transmitting %d bytes\n", host->total_length);
+
+ at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
+ at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
+ ier = AT91_MCI_CMDRDY;
+ }
}
}
@@ -497,39 +525,24 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
if (cmdr & AT91_MCI_TRCMD_START) {
if (cmdr & AT91_MCI_TRDIR)
at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
- else
- at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
}
- return ier;
-}
-
-/*
- * Wait for a command to complete
- */
-static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd)
-{
- unsigned int ier;
-
- ier = at91_mci_send_command(host, cmd);
-
- pr_debug("setting ier to %08X\n", ier);
- /* Stop on errors or the required value */
+ /* Enable selected interrupts */
at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier);
}
/*
* Process the next step in the request
*/
-static void at91mci_process_next(struct at91mci_host *host)
+static void at91_mci_process_next(struct at91mci_host *host)
{
if (!(host->flags & FL_SENT_COMMAND)) {
host->flags |= FL_SENT_COMMAND;
- at91mci_process_command(host, host->request->cmd);
+ at91_mci_send_command(host, host->request->cmd);
}
else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
host->flags |= FL_SENT_STOP;
- at91mci_process_command(host, host->request->stop);
+ at91_mci_send_command(host, host->request->stop);
}
else
mmc_request_done(host->mmc, host->request);
@@ -538,7 +551,7 @@ static void at91mci_process_next(struct at91mci_host *host)
/*
* Handle a command that has been completed
*/
-static void at91mci_completed_command(struct at91mci_host *host)
+static void at91_mci_completed_command(struct at91mci_host *host)
{
struct mmc_command *cmd = host->cmd;
unsigned int status;
@@ -583,7 +596,7 @@ static void at91mci_completed_command(struct at91mci_host *host)
else
cmd->error = MMC_ERR_NONE;
- at91mci_process_next(host);
+ at91_mci_process_next(host);
}
/*
@@ -595,7 +608,7 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->request = mrq;
host->flags = 0;
- at91mci_process_next(host);
+ at91_mci_process_next(host);
}
/*
@@ -698,29 +711,33 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
at91_mci_handle_transmitted(host);
}
+ if (int_status & AT91_MCI_ENDRX) {
+ pr_debug("ENDRX\n");
+ at91_mci_post_dma_read(host);
+ }
+
if (int_status & AT91_MCI_RXBUFF) {
pr_debug("RX buffer full\n");
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
+ at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+ at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX);
+ completed = 1;
}
if (int_status & AT91_MCI_ENDTX)
pr_debug("Transmit has ended\n");
- if (int_status & AT91_MCI_ENDRX) {
- pr_debug("Receive has ended\n");
- at91mci_post_dma_read(host);
- }
-
if (int_status & AT91_MCI_NOTBUSY) {
pr_debug("Card is ready\n");
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY);
+ completed = 1;
}
if (int_status & AT91_MCI_DTIP)
pr_debug("Data transfer in progress\n");
- if (int_status & AT91_MCI_BLKE)
+ if (int_status & AT91_MCI_BLKE) {
pr_debug("Block transfer has ended\n");
+ completed = 1;
+ }
if (int_status & AT91_MCI_TXRDY)
pr_debug("Ready to transmit\n");
@@ -730,14 +747,14 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
if (int_status & AT91_MCI_CMDRDY) {
pr_debug("Command ready\n");
- completed = 1;
+ completed = at91_mci_handle_cmdrdy(host);
}
}
if (completed) {
pr_debug("Completed command\n");
at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
- at91mci_completed_command(host);
+ at91_mci_completed_command(host);
} else
at91_mci_write(host, AT91_MCI_IDR, int_status);
@@ -830,11 +847,11 @@ static int __init at91_mci_probe(struct platform_device *pdev)
host->bus_mode = 0;
host->board = pdev->dev.platform_data;
if (host->board->wire4) {
-#ifdef SUPPORT_4WIRE
- mmc->caps |= MMC_CAP_4_BIT_DATA;
-#else
- printk("AT91 MMC: 4 wire bus mode not supported by this driver - using 1 wire\n");
-#endif
+ if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+ else
+ printk("AT91 MMC: 4 wire bus mode not supported"
+ " - using 1 wire\n");
}
/*
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a359efdd77eb..10d15c39d003 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -70,6 +70,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
.driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE,
},
+ {
+ .vendor = PCI_VENDOR_ID_ENE,
+ .device = PCI_DEVICE_ID_ENE_CB712_SD_2,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE,
+ },
+
{ /* Generic SD host controller */
PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
},
@@ -1022,7 +1030,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
}
- intmask &= SDHCI_INT_BUS_POWER;
+ intmask &= ~SDHCI_INT_BUS_POWER;
if (intmask) {
printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 78872c3f3760..b96ac8e119dc 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -84,7 +84,7 @@ static unsigned long __initdata doc_locations[] = {
#elif defined(CONFIG_MOMENCO_OCELOT)
0x2f000000,
0xff000000,
-#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
+#elif defined(CONFIG_MOMENCO_OCELOT_G)
0xff000000,
##else
#warning Unknown architecture for DiskOnChip. No default probe locations defined
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index b665e4ac2208..f88ebc5b685e 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -258,12 +258,6 @@ config MTD_TSUNAMI
help
Support for the flash chip on Tsunami TIG bus.
-config MTD_LASAT
- tristate "LASAT flash device"
- depends on LASAT && MTD_CFI
- help
- Support for the flash chips on the Lasat 100 and 200 boards.
-
config MTD_NETtel
tristate "CFI flash device on SnapGear/SecureEdge"
depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 3acbb5d01ca4..970b189271a2 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -47,7 +47,6 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
obj-$(CONFIG_MTD_PCI) += pci.o
obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o
-obj-$(CONFIG_MTD_LASAT) += lasat.o
obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
obj-$(CONFIG_MTD_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_IMPA7) += impa7.o
diff --git a/drivers/mtd/maps/lasat.c b/drivers/mtd/maps/lasat.c
deleted file mode 100644
index e34376321050..000000000000
--- a/drivers/mtd/maps/lasat.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Flash device on Lasat 100 and 200 boards
- *
- * (C) 2002 Brian Murphy <brian@murphy.dk>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * $Id: lasat.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/lasat/lasat.h>
-
-static struct mtd_info *lasat_mtd;
-
-static struct mtd_partition partition_info[LASAT_MTD_LAST];
-static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
-
-static void lasat_set_vpp(struct map_info *map, int vpp)
-{
- if (vpp)
- *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
- else
- *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit);
-}
-
-static struct map_info lasat_map = {
- .name = "LASAT flash",
- .bankwidth = 4,
- .set_vpp = lasat_set_vpp
-};
-
-static int __init init_lasat(void)
-{
- int i;
- /* since we use AMD chips and set_vpp is not implimented
- * for these (yet) we still have to permanently enable flash write */
- printk(KERN_NOTICE "Unprotecting flash\n");
- ENABLE_VPP((&lasat_map));
-
- lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
- lasat_map.virt = ioremap_nocache(
- lasat_map.phys, lasat_board_info.li_flash_size);
- lasat_map.size = lasat_board_info.li_flash_size;
-
- simple_map_init(&lasat_map);
-
- for (i=0; i < LASAT_MTD_LAST; i++)
- partition_info[i].name = lasat_mtd_partnames[i];
-
- lasat_mtd = do_map_probe("cfi_probe", &lasat_map);
-
- if (!lasat_mtd)
- lasat_mtd = do_map_probe("jedec_probe", &lasat_map);
-
- if (lasat_mtd) {
- u32 size, offset = 0;
-
- lasat_mtd->owner = THIS_MODULE;
-
- for (i=0; i < LASAT_MTD_LAST; i++) {
- size = lasat_flash_partition_size(i);
- partition_info[i].size = size;
- partition_info[i].offset = offset;
- offset += size;
- }
-
- add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST );
- return 0;
- }
-
- iounmap(lasat_map.virt);
- return -ENXIO;
-}
-
-static void __exit cleanup_lasat(void)
-{
- if (lasat_mtd) {
- del_mtd_partitions(lasat_mtd);
- map_destroy(lasat_mtd);
- }
- if (lasat_map.virt) {
- iounmap(lasat_map.virt);
- lasat_map.virt = 0;
- }
-}
-
-module_init(init_lasat);
-module_exit(cleanup_lasat);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");
-MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver");
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 595208f965a5..17c868034aad 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -59,7 +59,7 @@ static unsigned long __initdata doc_locations[] = {
#elif defined(CONFIG_MOMENCO_OCELOT)
0x2f000000,
0xff000000,
-#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
+#elif defined(CONFIG_MOMENCO_OCELOT_G)
0xff000000,
#else
#warning Unknown architecture for DiskOnChip. No default probe locations defined
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index f26ca331615e..6deb20fc7a08 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -324,7 +324,7 @@ static struct vortex_chip_info {
{"3c980C Python-T",
PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
{"3cSOHO100-TX Hurricane",
- PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+ PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
{"3c555 Laptop Hurricane",
PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
{"3c556 Laptop Tornado",
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 414de5bd228f..04ddec0f4c61 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -73,6 +73,9 @@ struct ei_device {
u32 *reg_offset; /* Register mapping table */
spinlock_t page_lock; /* Page register locks */
unsigned long priv; /* Private field to store bus IDs etc. */
+#ifdef AX88796_PLATFORM
+ unsigned char rxcr_base; /* default value for RXCR */
+#endif
};
/* The maximum number of 8390 interrupt service routines called per IRQ. */
@@ -86,11 +89,19 @@ struct ei_device {
/* Some generic ethernet register configurations. */
#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
#define E8390_RX_IRQ_MASK 0x5
+
+#ifdef AX88796_PLATFORM
+#define E8390_RXCONFIG (ei_status.rxcr_base | 0x04)
+#define E8390_RXOFF (ei_status.rxcr_base | 0x20)
+#else
#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
+#endif
+
#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
+
/* Register accessed at EN_CMD, the 8390 base addr. */
#define E8390_STOP 0x01 /* Stop and reset the chip */
#define E8390_START 0x02 /* Start the chip, clear reset */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5cc3d517e39b..b941c74a06c4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -197,6 +197,15 @@ config MACB
source "drivers/net/arm/Kconfig"
+config AX88796
+ tristate "ASIX AX88796 NE2000 clone support"
+ depends on ARM || MIPS
+ select CRC32
+ select MII
+ help
+ AX88796 driver, using platform bus to provide
+ chip detection and resources
+
config MACE
tristate "MACE (Power Mac ethernet) support"
depends on PPC_PMAC && PPC32
@@ -2105,7 +2114,7 @@ config SKGE
with better performance and more complete ethtool support.
It does not support the link failover and network management
- features that "portable" vendor supplied sk98lin driver does.
+ features available in the hardware.
This driver supports adapters based on the original Yukon chipset:
Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
@@ -2118,7 +2127,7 @@ config SKGE
will be called skge. This is recommended.
config SKY2
- tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
+ tristate "SysKonnect Yukon2 support"
depends on PCI
select CRC32
---help---
@@ -2133,92 +2142,15 @@ config SKY2
To compile this driver as a module, choose M here: the module
will be called sky2. This is recommended.
-config SK98LIN
- tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
- depends on PCI
- ---help---
- Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
- compliant Gigabit Ethernet Adapter.
-
- This driver supports the original Yukon chipset. This driver is
- deprecated and will be removed from the kernel in the near future,
- it has been replaced by the skge driver. skge is cleaner and
- seems to work better.
+config SKY2_DEBUG
+ bool "Debugging interface"
+ depends on SKY2 && DEBUG_FS
+ help
+ This option adds the ability to dump driver state for debugging.
+ The file debugfs/sky2/ethX displays the state of the internal
+ transmit and receive rings.
- This driver does not support the newer Yukon2 chipset. A separate
- driver, sky2, is provided to support Yukon2-based adapters.
-
- The following adapters are supported by this driver:
- - 3Com 3C940 Gigabit LOM Ethernet Adapter
- - 3Com 3C941 Gigabit LOM Ethernet Adapter
- - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
- - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
- - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
- - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
- - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
- - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
- - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
- - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
- - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
- - EG1032 v2 Instant Gigabit Network Adapter
- - EG1064 v2 Instant Gigabit Network Adapter
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
- - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
- - Marvell RDK-8001 Adapter
- - Marvell RDK-8002 Adapter
- - Marvell RDK-8003 Adapter
- - Marvell RDK-8004 Adapter
- - Marvell RDK-8006 Adapter
- - Marvell RDK-8007 Adapter
- - Marvell RDK-8008 Adapter
- - Marvell RDK-8009 Adapter
- - Marvell RDK-8010 Adapter
- - Marvell RDK-8011 Adapter
- - Marvell RDK-8012 Adapter
- - Marvell RDK-8052 Adapter
- - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
- - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
- - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
- - SK-9521 10/100/1000Base-T Adapter
- - SK-9521 V2.0 10/100/1000Base-T Adapter
- - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
- - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
- - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
- - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
- - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
- - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
- - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
- - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
- - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
- - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
- - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
- - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
- - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
- - SMC EZ Card 1000 (SMC9452TXV.2)
-
- The adapters support Jumbo Frames.
- The dual link adapters support link-failover and dual port features.
- Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support
- the scatter-gather functionality with sendfile(). Please refer to
- <file:Documentation/networking/sk98lin.txt> for more information about
- optional driver parameters.
- Questions concerning this driver may be addressed to:
- <linux@syskonnect.de>
-
- If you want to compile this driver as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/kbuild/modules.txt>. The module will
- be called sk98lin. This is recommended.
+ If unsure, say N.
config VIA_VELOCITY
tristate "VIA Velocity support"
@@ -2268,6 +2200,16 @@ config TSI108_ETH
To compile this driver as a module, choose M here: the module
will be called tsi108_eth.
+config GELIC_NET
+ tristate "PS3 Gigabit Ethernet driver"
+ depends on PPC_PS3
+ help
+ This driver supports the network device on the PS3 game
+ console. This driver has built-in support for Ethernet.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ps3_gelic.
+
config GIANFAR
tristate "Gianfar Ethernet"
depends on 85xx || 83xx || PPC_86xx
@@ -2307,7 +2249,7 @@ config UGETH_TX_ON_DEMAND
config MV643XX_ETH
tristate "MV-643XX Ethernet support"
- depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
+ depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32)
select MII
help
This driver supports the gigabit Ethernet on the Marvell MV643XX
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index eb62fb48e4b7..1bbcbedad04a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -60,10 +60,11 @@ obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BNX2) += bnx2.o
spidernet-y += spider_net.o spider_net_ethtool.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
+obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
+ps3_gelic-objs += ps3_gelic_net.o
obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SKY2) += sky2.o
-obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
@@ -107,6 +108,7 @@ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
obj-$(CONFIG_B44) += b44.o
obj-$(CONFIG_FORCEDETH) += forcedeth.o
obj-$(CONFIG_NE_H8300) += ne-h8300.o
+obj-$(CONFIG_AX88796) += ax88796.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 54714409a09b..f7356374a2e7 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -295,10 +295,7 @@ int if_up = 0;
/* Setup the DMA counter */
static void
-setup_dma (address, rw_flag, num_blocks)
- void *address;
- unsigned rw_flag;
- int num_blocks;
+setup_dma (void *address, unsigned rw_flag, int num_blocks)
{
WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI |
A1);
@@ -317,9 +314,7 @@ setup_dma (address, rw_flag, num_blocks)
/* Send the first byte of an command block */
static int
-send_first (target, byte)
- int target;
- unsigned char byte;
+send_first (int target, unsigned char byte)
{
rw = READ;
acsi_delay_end(COMMAND_DELAY);
@@ -338,10 +333,7 @@ send_first (target, byte)
/* Send the rest of an command block */
static int
-send_1_5 (lun, command, dma)
- int lun;
- unsigned char *command;
- int dma;
+send_1_5 (int lun, unsigned char *command, int dma)
{
int i, j;
@@ -371,8 +363,7 @@ get_status (void)
/* Calculate the number of received bytes */
static int
-calc_received (start_address)
- void *start_address;
+calc_received (void *start_address)
{
return (int)(
(((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
@@ -384,8 +375,7 @@ calc_received (start_address)
/* start() starts the PAM's DMA adaptor */
static void
-start (target)
- int target;
+start (int target)
{
send_first(target, START);
}
@@ -393,8 +383,7 @@ start (target)
/* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
static int
-stop (target)
- int target;
+stop (int target)
{
int ret = -1;
unsigned char cmd_buffer[5];
@@ -415,8 +404,7 @@ bad:
/* testpkt() returns the number of received packets waiting in the queue */
static int
-testpkt(target)
- int target;
+testpkt(int target)
{
int ret = -1;
@@ -431,9 +419,7 @@ bad:
/* Please note: The buffer is for internal use only but must be defined! */
static int
-inquiry (target, buffer)
- int target;
- unsigned char *buffer;
+inquiry (int target, unsigned char *buffer)
{
int ret = -1;
unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
@@ -468,9 +454,7 @@ bad:
*/
static HADDR
-*read_hw_addr(target, buffer)
- int target;
- unsigned char *buffer;
+*read_hw_addr(int target, unsigned char *buffer)
{
HADDR *ret = 0;
unsigned char cmd_buffer[5];
@@ -491,9 +475,7 @@ bad:
}
static irqreturn_t
-pamsnet_intr(irq, data, fp)
- int irq;
- void *data;
+pamsnet_intr(int irq, void *data)
{
return IRQ_HANDLED;
}
@@ -501,9 +483,7 @@ pamsnet_intr(irq, data, fp)
/* receivepkt() loads a packet to a given buffer and returns its length */
static int
-receivepkt (target, buffer)
- int target;
- unsigned char *buffer;
+receivepkt (int target, unsigned char *buffer)
{
int ret = -1;
unsigned char cmd_buffer[5];
@@ -526,10 +506,7 @@ bad:
successfully */
static int
-sendpkt (target, buffer, length)
- int target;
- unsigned char *buffer;
- int length;
+sendpkt (int target, unsigned char *buffer, int length)
{
int ret = -1;
unsigned char cmd_buffer[5];
@@ -665,7 +642,8 @@ struct net_device * __init pamsnet_probe (int unit)
there is non-reboot way to recover if something goes wrong.
*/
static int
-pamsnet_open(struct net_device *dev) {
+pamsnet_open(struct net_device *dev)
+{
struct net_local *lp = netdev_priv(dev);
if (pamsnet_debug > 0)
@@ -694,7 +672,8 @@ pamsnet_open(struct net_device *dev) {
}
static int
-pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
+pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
struct net_local *lp = netdev_priv(dev);
unsigned long flags;
@@ -741,7 +720,8 @@ pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
/* We have a good packet(s), get it/them out of the buffers.
*/
static void
-pamsnet_poll_rx(struct net_device *dev) {
+pamsnet_poll_rx(struct net_device *dev)
+{
struct net_local *lp = netdev_priv(dev);
int boguscount;
int pkt_len;
@@ -816,7 +796,8 @@ pamsnet_poll_rx(struct net_device *dev) {
* passes them to the higher layers and restarts the timer.
*/
static void
-pamsnet_tick(unsigned long data) {
+pamsnet_tick(unsigned long data)
+{
struct net_device *dev = (struct net_device *)data;
struct net_local *lp = netdev_priv(dev);
@@ -832,7 +813,8 @@ pamsnet_tick(unsigned long data) {
/* The inverse routine to pamsnet_open().
*/
static int
-pamsnet_close(struct net_device *dev) {
+pamsnet_close(struct net_device *dev)
+{
struct net_local *lp = netdev_priv(dev);
if (pamsnet_debug > 0)
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 6862c11ff864..3bb40dd4a410 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -634,14 +634,13 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
struct atl1_buffer *buffer_info;
u16 sw_tpd_next_to_clean;
u16 cmb_tpd_next_to_clean;
- u8 update = 0;
sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
struct tx_packet_desc *tpd;
- update = 1;
+
tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
if (buffer_info->dma) {
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
new file mode 100644
index 000000000000..d19874bf0706
--- /dev/null
+++ b/drivers/net/ax88796.c
@@ -0,0 +1,952 @@
+/* drivers/net/ax88796.c
+ *
+ * Copyright 2005,2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Asix AX88796 10/100 Ethernet controller support
+ * Based on ne.c, by Donald Becker, et-al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/isapnp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <net/ax88796.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+static int phy_debug = 0;
+
+/* Rename the lib8390.c functions to show that they are in this driver */
+#define __ei_open ax_ei_open
+#define __ei_close ax_ei_close
+#define __ei_poll ax_ei_poll
+#define __ei_tx_timeout ax_ei_tx_timeout
+#define __ei_interrupt ax_ei_interrupt
+#define ____alloc_ei_netdev ax__alloc_ei_netdev
+#define __NS8390_init ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a) readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a) ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+#define DRV_NAME "ax88796"
+#define DRV_VERSION "1.00"
+
+/* from ne.c */
+#define NE_CMD EI_SHIFT(0x00)
+#define NE_RESET EI_SHIFT(0x1f)
+#define NE_DATAPORT EI_SHIFT(0x10)
+
+#define NE1SM_START_PG 0x20 /* First page of TX buffer */
+#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
+#define NESM_START_PG 0x40 /* First page of TX buffer */
+#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
+
+/* device private data */
+
+struct ax_device {
+ struct timer_list mii_timer;
+ spinlock_t mii_lock;
+ struct mii_if_info mii;
+
+ u32 msg_enable;
+ void __iomem *map2;
+ struct platform_device *dev;
+ struct resource *mem;
+ struct resource *mem2;
+ struct ax_plat_data *plat;
+
+ unsigned char running;
+ unsigned char resume_open;
+
+ u32 reg_offsets[0x20];
+};
+
+static inline struct ax_device *to_ax_dev(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ return (struct ax_device *)(ei_local+1);
+}
+
+/* ax_initial_check
+ *
+ * do an initial probe for the card to check wether it exists
+ * and is functional
+ */
+
+static int ax_initial_check(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *ioaddr = ei_local->mem;
+ int reg0;
+ int regd;
+
+ reg0 = ei_inb(ioaddr);
+ if (reg0 == 0xFF)
+ return -ENODEV;
+
+ ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+ regd = ei_inb(ioaddr + 0x0d);
+ ei_outb(0xff, ioaddr + 0x0d);
+ ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
+ ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
+ if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
+ ei_outb(reg0, ioaddr);
+ ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/* Hard reset the card. This used to pause for the same period that a
+ 8390 reset command required, but that shouldn't be necessary. */
+
+static void ax_reset_8390(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ unsigned long reset_start_time = jiffies;
+ void __iomem *addr = (void __iomem *)dev->base_addr;
+
+ if (ei_debug > 1)
+ printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
+
+ ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+ ei_status.txing = 0;
+ ei_status.dmaing = 0;
+
+ /* This check _should_not_ be necessary, omit eventually. */
+ while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
+ if (jiffies - reset_start_time > 2*HZ/100) {
+ printk(KERN_WARNING "%s: %s did not complete.\n",
+ __FUNCTION__, dev->name);
+ break;
+ }
+ }
+
+ ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */
+}
+
+
+static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
+ int ring_page)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *nic_base = ei_local->mem;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
+ dev->name, __FUNCTION__,
+ ei_status.dmaing, ei_status.irqlock);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+ ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+ ei_outb(0, nic_base + EN0_RCNTHI);
+ ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */
+ ei_outb(ring_page, nic_base + EN0_RSARHI);
+ ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ if (ei_status.word16)
+ readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+ else
+ readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
+
+ ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+
+ le16_to_cpus(&hdr->count);
+}
+
+
+/* Block input and output, similar to the Crynwr packet driver. If you
+ are porting to a new ethercard, look at the packet driver source for hints.
+ The NEx000 doesn't share the on-board packet memory -- you have to put
+ the packet out through the "remote DMA" dataport using ei_outb. */
+
+static void ax_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *nic_base = ei_local->mem;
+ char *buf = skb->data;
+
+ if (ei_status.dmaing) {
+ printk(KERN_EMERG "%s: DMAing conflict in ax_block_input "
+ "[DMAstat:%d][irqlock:%d].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+
+ ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+ ei_outb(count >> 8, nic_base + EN0_RCNTHI);
+ ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
+ ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
+ ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ if (ei_status.word16) {
+ readsw(nic_base + NE_DATAPORT, buf, count >> 1);
+ if (count & 0x01)
+ buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
+
+ } else {
+ readsb(nic_base + NE_DATAPORT, buf, count);
+ }
+
+ ei_status.dmaing &= ~1;
+}
+
+static void ax_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, const int start_page)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *nic_base = ei_local->mem;
+ unsigned long dma_start;
+
+ /* Round the count up for word writes. Do we need to do this?
+ What effect will an odd byte count have on the 8390?
+ I should check someday. */
+
+ if (ei_status.word16 && (count & 0x01))
+ count++;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk(KERN_EMERG "%s: DMAing conflict in %s."
+ "[DMAstat:%d][irqlock:%d]\n",
+ dev->name, __FUNCTION__,
+ ei_status.dmaing, ei_status.irqlock);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+ /* We should already be in page 0, but to be safe... */
+ ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+ ei_outb(ENISR_RDC, nic_base + EN0_ISR);
+
+ /* Now the normal output. */
+ ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+ ei_outb(count >> 8, nic_base + EN0_RCNTHI);
+ ei_outb(0x00, nic_base + EN0_RSARLO);
+ ei_outb(start_page, nic_base + EN0_RSARHI);
+
+ ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+ if (ei_status.word16) {
+ writesw(nic_base + NE_DATAPORT, buf, count>>1);
+ } else {
+ writesb(nic_base + NE_DATAPORT, buf, count);
+ }
+
+ dma_start = jiffies;
+
+ while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
+ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
+ printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+ ax_reset_8390(dev);
+ ax_NS8390_init(dev,1);
+ break;
+ }
+ }
+
+ ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+ return;
+}
+
+/* definitions for accessing MII/EEPROM interface */
+
+#define AX_MEMR EI_SHIFT(0x14)
+#define AX_MEMR_MDC (1<<0)
+#define AX_MEMR_MDIR (1<<1)
+#define AX_MEMR_MDI (1<<2)
+#define AX_MEMR_MDO (1<<3)
+#define AX_MEMR_EECS (1<<4)
+#define AX_MEMR_EEI (1<<5)
+#define AX_MEMR_EEO (1<<6)
+#define AX_MEMR_EECLK (1<<7)
+
+/* ax_mii_ei_outbits
+ *
+ * write the specified set of bits to the phy
+*/
+
+static void
+ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
+{
+ struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
+ unsigned int memr;
+
+ /* clock low, data to output mode */
+ memr = ei_inb(memr_addr);
+ memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
+ ei_outb(memr, memr_addr);
+
+ for (len--; len >= 0; len--) {
+ if (bits & (1 << len))
+ memr |= AX_MEMR_MDO;
+ else
+ memr &= ~AX_MEMR_MDO;
+
+ ei_outb(memr, memr_addr);
+
+ /* clock high */
+
+ ei_outb(memr | AX_MEMR_MDC, memr_addr);
+ udelay(1);
+
+ /* clock low */
+ ei_outb(memr, memr_addr);
+ }
+
+ /* leaves the clock line low, mdir input */
+ memr |= AX_MEMR_MDIR;
+ ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
+}
+
+/* ax_phy_ei_inbits
+ *
+ * read a specified number of bits from the phy
+*/
+
+static unsigned int
+ax_phy_ei_inbits(struct net_device *dev, int no)
+{
+ struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
+ unsigned int memr;
+ unsigned int result = 0;
+
+ /* clock low, data to input mode */
+ memr = ei_inb(memr_addr);
+ memr &= ~AX_MEMR_MDC;
+ memr |= AX_MEMR_MDIR;
+ ei_outb(memr, memr_addr);
+
+ for (no--; no >= 0; no--) {
+ ei_outb(memr | AX_MEMR_MDC, memr_addr);
+
+ udelay(1);
+
+ if (ei_inb(memr_addr) & AX_MEMR_MDI)
+ result |= (1<<no);
+
+ ei_outb(memr, memr_addr);
+ }
+
+ return result;
+}
+
+/* ax_phy_issueaddr
+ *
+ * use the low level bit shifting routines to send the address
+ * and command to the specified phy
+*/
+
+static void
+ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
+{
+ if (phy_debug)
+ pr_debug("%s: dev %p, %04x, %04x, %d\n",
+ __FUNCTION__, dev, phy_addr, reg, opc);
+
+ ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
+ ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
+ ax_mii_ei_outbits(dev, opc, 2); /* op code */
+ ax_mii_ei_outbits(dev, phy_addr, 5); /* phy address */
+ ax_mii_ei_outbits(dev, reg, 5); /* reg address */
+}
+
+static int
+ax_phy_read(struct net_device *dev, int phy_addr, int reg)
+{
+ struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ unsigned long flags;
+ unsigned int result;
+
+ spin_lock_irqsave(&ei_local->page_lock, flags);
+
+ ax_phy_issueaddr(dev, phy_addr, reg, 2);
+
+ result = ax_phy_ei_inbits(dev, 17);
+ result &= ~(3<<16);
+
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
+
+ if (phy_debug)
+ pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+ phy_addr, reg, result);
+
+ return result;
+}
+
+static void
+ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
+{
+ struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
+ unsigned long flags;
+
+ printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n",
+ __FUNCTION__, dev, phy_addr, reg, value);
+
+ spin_lock_irqsave(&ei->page_lock, flags);
+
+ ax_phy_issueaddr(dev, phy_addr, reg, 1);
+ ax_mii_ei_outbits(dev, 2, 2); /* send TA */
+ ax_mii_ei_outbits(dev, value, 16);
+
+ spin_unlock_irqrestore(&ei->page_lock, flags);
+}
+
+static void ax_mii_expiry(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct ax_device *ax = to_ax_dev(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ax->mii_lock, flags);
+ mii_check_media(&ax->mii, netif_msg_link(ax), 0);
+ spin_unlock_irqrestore(&ax->mii_lock, flags);
+
+ if (ax->running) {
+ ax->mii_timer.expires = jiffies + HZ*2;
+ add_timer(&ax->mii_timer);
+ }
+}
+
+static int ax_open(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
+ int ret;
+
+ dev_dbg(ax->dev, "%s: open\n", dev->name);
+
+ ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+ if (ret)
+ return ret;
+
+ ret = ax_ei_open(dev);
+ if (ret)
+ return ret;
+
+ /* turn the phy on (if turned off) */
+
+ ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
+ ax->running = 1;
+
+ /* start the MII timer */
+
+ init_timer(&ax->mii_timer);
+
+ ax->mii_timer.expires = jiffies+1;
+ ax->mii_timer.data = (unsigned long) dev;
+ ax->mii_timer.function = ax_mii_expiry;
+
+ add_timer(&ax->mii_timer);
+
+ return 0;
+}
+
+static int ax_close(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ dev_dbg(ax->dev, "%s: close\n", dev->name);
+
+ /* turn the phy off */
+
+ ei_outb(ax->plat->gpoc_val | (1<<6),
+ ei_local->mem + EI_SHIFT(0x17));
+
+ ax->running = 0;
+ wmb();
+
+ del_timer_sync(&ax->mii_timer);
+ ax_ei_close(dev);
+
+ free_irq(dev->irq, dev);
+ return 0;
+}
+
+static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ unsigned long flags;
+ int rc;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ spin_lock_irqsave(&ax->mii_lock, flags);
+ rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
+ spin_unlock_irqrestore(&ax->mii_lock, flags);
+
+ return rc;
+}
+
+/* ethtool ops */
+
+static void ax_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+
+ strcpy(info->driver, DRV_NAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->bus_info, ax->dev->name);
+}
+
+static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ax->mii_lock, flags);
+ mii_ethtool_gset(&ax->mii, cmd);
+ spin_lock_irqsave(&ax->mii_lock, flags);
+
+ return 0;
+}
+
+static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&ax->mii_lock, flags);
+ rc = mii_ethtool_sset(&ax->mii, cmd);
+ spin_lock_irqsave(&ax->mii_lock, flags);
+
+ return rc;
+}
+
+static int ax_nway_reset(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ return mii_nway_restart(&ax->mii);
+}
+
+static u32 ax_get_link(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ return mii_link_ok(&ax->mii);
+}
+
+static const struct ethtool_ops ax_ethtool_ops = {
+ .get_drvinfo = ax_get_drvinfo,
+ .get_settings = ax_get_settings,
+ .set_settings = ax_set_settings,
+ .nway_reset = ax_nway_reset,
+ .get_link = ax_get_link,
+ .get_perm_addr = ethtool_op_get_perm_addr,
+};
+
+/* setup code */
+
+static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
+{
+ void __iomem *ioaddr = ei_local->mem;
+ struct ax_device *ax = to_ax_dev(dev);
+
+ /* Select page 0*/
+ ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD);
+
+ /* set to byte access */
+ ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
+ ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
+}
+
+/* ax_init_dev
+ *
+ * initialise the specified device, taking care to note the MAC
+ * address it may already have (if configured), ensure
+ * the device is ready to be used by lib8390.c and registerd with
+ * the network layer.
+ */
+
+static int ax_init_dev(struct net_device *dev, int first_init)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ struct ax_device *ax = to_ax_dev(dev);
+ void __iomem *ioaddr = ei_local->mem;
+ unsigned int start_page;
+ unsigned int stop_page;
+ int ret;
+ int i;
+
+ ret = ax_initial_check(dev);
+ if (ret)
+ goto err_out;
+
+ /* setup goes here */
+
+ ax_initial_setup(dev, ei_local);
+
+ /* read the mac from the card prom if we need it */
+
+ if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) {
+ unsigned char SA_prom[32];
+
+ for(i = 0; i < sizeof(SA_prom); i+=2) {
+ SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
+ SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT);
+ }
+
+ if (ax->plat->wordlength == 2)
+ for (i = 0; i < 16; i++)
+ SA_prom[i] = SA_prom[i+i];
+
+ memcpy(dev->dev_addr, SA_prom, 6);
+ }
+
+ if (ax->plat->wordlength == 2) {
+ /* We must set the 8390 for word mode. */
+ ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
+ start_page = NESM_START_PG;
+ stop_page = NESM_STOP_PG;
+ } else {
+ start_page = NE1SM_START_PG;
+ stop_page = NE1SM_STOP_PG;
+ }
+
+ /* load the mac-address from the device if this is the
+ * first time we've initialised */
+
+ if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
+ ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+ ei_local->mem + E8390_CMD); /* 0x61 */
+
+ for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
+ dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+ }
+
+ ax_reset_8390(dev);
+
+ ei_status.name = "AX88796";
+ ei_status.tx_start_page = start_page;
+ ei_status.stop_page = stop_page;
+ ei_status.word16 = (ax->plat->wordlength == 2);
+ ei_status.rx_start_page = start_page + TX_PAGES;
+
+#ifdef PACKETBUF_MEMSIZE
+ /* Allow the packet buffer size to be overridden by know-it-alls. */
+ ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+ ei_status.reset_8390 = &ax_reset_8390;
+ ei_status.block_input = &ax_block_input;
+ ei_status.block_output = &ax_block_output;
+ ei_status.get_8390_hdr = &ax_get_8390_hdr;
+ ei_status.priv = 0;
+
+ dev->open = ax_open;
+ dev->stop = ax_close;
+ dev->do_ioctl = ax_ioctl;
+ dev->ethtool_ops = &ax_ethtool_ops;
+
+ ax->msg_enable = NETIF_MSG_LINK;
+ ax->mii.phy_id_mask = 0x1f;
+ ax->mii.reg_num_mask = 0x1f;
+ ax->mii.phy_id = 0x10; /* onboard phy */
+ ax->mii.force_media = 0;
+ ax->mii.full_duplex = 0;
+ ax->mii.mdio_read = ax_phy_read;
+ ax->mii.mdio_write = ax_phy_write;
+ ax->mii.dev = dev;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = ax_ei_poll;
+#endif
+ ax_NS8390_init(dev, 0);
+
+ if (first_init) {
+ printk("AX88796: %dbit, irq %d, %lx, MAC: ",
+ ei_status.word16 ? 16:8, dev->irq, dev->base_addr);
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ printk("%2.2x%c", dev->dev_addr[i],
+ (i < (ETHER_ADDR_LEN-1) ? ':' : ' '));
+
+ printk("\n");
+ }
+
+ ret = register_netdev(dev);
+ if (ret)
+ goto out_irq;
+
+ return 0;
+
+ out_irq:
+ /* cleanup irq */
+ free_irq(dev->irq, dev);
+ err_out:
+ return ret;
+}
+
+static int ax_remove(struct platform_device *_dev)
+{
+ struct net_device *dev = platform_get_drvdata(_dev);
+ struct ax_device *ax;
+
+ ax = to_ax_dev(dev);
+
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+
+ iounmap(ei_status.mem);
+ release_resource(ax->mem);
+ kfree(ax->mem);
+
+ if (ax->map2) {
+ iounmap(ax->map2);
+ release_resource(ax->mem2);
+ kfree(ax->mem2);
+ }
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+/* ax_probe
+ *
+ * This is the entry point when the platform device system uses to
+ * notify us of a new device to attach to. Allocate memory, find
+ * the resources and information passed, and map the necessary registers.
+*/
+
+static int ax_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct ax_device *ax;
+ struct resource *res;
+ size_t size;
+ int ret;
+
+ dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
+ if (dev == NULL)
+ return -ENOMEM;
+
+ /* ok, let's setup our device */
+ ax = to_ax_dev(dev);
+
+ memset(ax, 0, sizeof(struct ax_device));
+
+ spin_lock_init(&ax->mii_lock);
+
+ ax->dev = pdev;
+ ax->plat = pdev->dev.platform_data;
+ platform_set_drvdata(pdev, dev);
+
+ ei_status.rxcr_base = ax->plat->rcr_val;
+
+ /* find the platform resources */
+
+ dev->irq = platform_get_irq(pdev, 0);
+ if (dev->irq < 0) {
+ dev_err(&pdev->dev, "no IRQ specified\n");
+ ret = -ENXIO;
+ goto exit_mem;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no MEM specified\n");
+ ret = -ENXIO;
+ goto exit_mem;
+ }
+
+ size = (res->end - res->start) + 1;
+
+ /* setup the register offsets from either the platform data
+ * or by using the size of the resource provided */
+
+ if (ax->plat->reg_offsets)
+ ei_status.reg_offset = ax->plat->reg_offsets;
+ else {
+ ei_status.reg_offset = ax->reg_offsets;
+ for (ret = 0; ret < 0x18; ret++)
+ ax->reg_offsets[ret] = (size / 0x18) * ret;
+ }
+
+ ax->mem = request_mem_region(res->start, size, pdev->name);
+ if (ax->mem == NULL) {
+ dev_err(&pdev->dev, "cannot reserve registers\n");
+ ret = -ENXIO;
+ goto exit_mem;
+ }
+
+ ei_status.mem = ioremap(res->start, size);
+ dev->base_addr = (long)ei_status.mem;
+
+ if (ei_status.mem == NULL) {
+ dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
+ res->start, res->end);
+
+ ret = -ENXIO;
+ goto exit_req;
+ }
+
+ /* look for reset area */
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res == NULL) {
+ if (!ax->plat->reg_offsets) {
+ for (ret = 0; ret < 0x20; ret++)
+ ax->reg_offsets[ret] = (size / 0x20) * ret;
+ }
+
+ ax->map2 = NULL;
+ } else {
+ size = (res->end - res->start) + 1;
+
+ ax->mem2 = request_mem_region(res->start, size, pdev->name);
+ if (ax->mem == NULL) {
+ dev_err(&pdev->dev, "cannot reserve registers\n");
+ ret = -ENXIO;
+ goto exit_mem1;
+ }
+
+ ax->map2 = ioremap(res->start, size);
+ if (ax->map2 == NULL) {
+ dev_err(&pdev->dev, "cannot map reset register");
+ ret = -ENXIO;
+ goto exit_mem2;
+ }
+
+ ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
+ }
+
+ /* got resources, now initialise and register device */
+
+ ret = ax_init_dev(dev, 1);
+ if (!ret)
+ return 0;
+
+ if (ax->map2 == NULL)
+ goto exit_mem1;
+
+ iounmap(ax->map2);
+
+ exit_mem2:
+ release_resource(ax->mem2);
+ kfree(ax->mem2);
+
+ exit_mem1:
+ iounmap(ei_status.mem);
+
+ exit_req:
+ release_resource(ax->mem);
+ kfree(ax->mem);
+
+ exit_mem:
+ free_netdev(dev);
+
+ return ret;
+}
+
+/* suspend and resume */
+
+#ifdef CONFIG_PM
+static int ax_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+ struct ax_device *ax = to_ax_dev(ndev);
+
+ ax->resume_open = ax->running;
+
+ netif_device_detach(ndev);
+ ax_close(ndev);
+
+ return 0;
+}
+
+static int ax_resume(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ax_device *ax = to_ax_dev(ndev);
+
+ ax_initial_setup(ndev, netdev_priv(ndev));
+ ax_NS8390_init(ndev, ax->resume_open);
+ netif_device_attach(ndev);
+
+ if (ax->resume_open)
+ ax_open(ndev);
+
+ return 0;
+}
+
+#else
+#define ax_suspend NULL
+#define ax_resume NULL
+#endif
+
+static struct platform_driver axdrv = {
+ .driver = {
+ .name = "ax88796",
+ .owner = THIS_MODULE,
+ },
+ .probe = ax_probe,
+ .remove = ax_remove,
+ .suspend = ax_suspend,
+ .resume = ax_resume,
+};
+
+static int __init axdrv_init(void)
+{
+ return platform_driver_register(&axdrv);
+}
+
+static void __exit axdrv_exit(void)
+{
+ platform_driver_unregister(&axdrv);
+}
+
+module_init(axdrv_init);
+module_exit(axdrv_exit);
+
+MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6287ffbda7f7..cb9cb3013f42 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -187,7 +187,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond);
/*---------------------------- General routines -----------------------------*/
-const char *bond_mode_name(int mode)
+static const char *bond_mode_name(int mode)
{
switch (mode) {
case BOND_MODE_ROUNDROBIN :
@@ -1224,7 +1224,8 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
/*---------------------------------- IOCTL ----------------------------------*/
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_sethwaddr(struct net_device *bond_dev,
+ struct net_device *slave_dev)
{
dprintk("bond_dev=%p\n", bond_dev);
dprintk("slave_dev=%p\n", slave_dev);
@@ -1390,6 +1391,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
goto err_free;
}
+ res = netdev_set_master(slave_dev, bond_dev);
+ if (res) {
+ dprintk("Error %d calling netdev_set_master\n", res);
+ goto err_close;
+ }
/* open the slave since the application closed it */
res = dev_open(slave_dev);
if (res) {
@@ -1397,12 +1403,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
goto err_restore_mac;
}
- res = netdev_set_master(slave_dev, bond_dev);
- if (res) {
- dprintk("Error %d calling netdev_set_master\n", res);
- goto err_close;
- }
-
new_slave->dev = slave_dev;
slave_dev->priv_flags |= IFF_BONDING;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index a89102116ccb..6dcbd25e3ef0 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -301,13 +301,11 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
void bond_mii_monitor(struct net_device *bond_dev);
void bond_loadbalance_arp_mon(struct net_device *bond_dev);
void bond_activebackup_arp_mon(struct net_device *bond_dev);
void bond_set_mode_ops(struct bonding *bond, int mode);
int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
-const char *bond_mode_name(int mode);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
void bond_register_arp(struct bonding *);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 15defe4c4f05..6fd1e5241833 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -43,6 +43,7 @@
#include <linux/proc_fs.h>
#include <linux/rtnetlink.h>
#include <linux/firmware.h>
+#include <linux/log2.h>
#include <asm/uaccess.h>
#include "common.h"
@@ -1818,8 +1819,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
return -EBUSY;
if (copy_from_user(&m, useraddr, sizeof(m)))
return -EFAULT;
- if (!m.rx_pg_sz || (m.rx_pg_sz & (m.rx_pg_sz - 1)) ||
- !m.tx_pg_sz || (m.tx_pg_sz & (m.tx_pg_sz - 1)))
+ if (!is_power_of_2(m.rx_pg_sz) ||
+ !is_power_of_2(m.tx_pg_sz))
return -EINVAL; /* not power of 2 */
if (!(m.rx_pg_sz & 0x14000))
return -EINVAL; /* not 16KB or 64KB */
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 763810c7f33a..74ea6373c7cd 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -159,7 +159,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.17-k4"DRV_EXT
+#define DRV_VERSION "3.5.23-k4"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -1024,10 +1024,16 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
config->mwi_enable = 0x1; /* 1=enable, 0=disable */
config->standard_tcb = 0x0; /* 1=standard, 0=extended */
config->rx_long_ok = 0x1; /* 1=VLANs ok, 0=standard */
- if(nic->mac >= mac_82559_D101M)
+ if (nic->mac >= mac_82559_D101M) {
config->tno_intr = 0x1; /* TCO stats enable */
- else
+ /* Enable TCO in extended config */
+ if (nic->mac >= mac_82551_10) {
+ config->byte_count = 0x20; /* extended bytes */
+ config->rx_d102_mode = 0x1; /* GMRC for TCO */
+ }
+ } else {
config->standard_stat_counter = 0x0;
+ }
}
DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index abaf3ac94936..f03f070451de 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,13 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0065"
+#define DRV_VERSION "EHEA_0067"
+
+/* EHEA capability flags */
+#define DLPAR_PORT_ADD_REM 1
+#define DLPAR_MEM_ADD 2
+#define DLPAR_MEM_REM 4
+#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index bdb52419dbf5..383144db4d18 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2923,6 +2923,15 @@ static int check_module_parm(void)
return ret;
}
+static ssize_t ehea_show_capabilities(struct device_driver *drv,
+ char *buf)
+{
+ return sprintf(buf, "%d", EHEA_CAPABILITIES);
+}
+
+static DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH,
+ ehea_show_capabilities, NULL);
+
int __init ehea_module_init(void)
{
int ret;
@@ -2934,8 +2943,19 @@ int __init ehea_module_init(void)
if (ret)
goto out;
ret = ibmebus_register_driver(&ehea_driver);
- if (ret)
+ if (ret) {
ehea_error("failed registering eHEA device driver on ebus");
+ goto out;
+ }
+
+ ret = driver_create_file(&ehea_driver.driver,
+ &driver_attr_capabilities);
+ if (ret) {
+ ehea_error("failed to register capabilities attribute, ret=%d",
+ ret);
+ ibmebus_unregister_driver(&ehea_driver);
+ goto out;
+ }
out:
return ret;
@@ -2943,6 +2963,7 @@ out:
static void __exit ehea_module_exit(void)
{
+ driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
}
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index f749e07c6425..3ca1e8ece548 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -352,13 +352,12 @@ static u64 nic_find(struct ioc3 *ioc3, int *last)
static int nic_init(struct ioc3 *ioc3)
{
- const char *type;
+ const char *unknown = "unknown";
+ const char *type = unknown;
u8 crc;
u8 serial[6];
int save = 0, i;
- type = "unknown";
-
while (1) {
u64 reg;
reg = nic_find(ioc3, &save);
@@ -392,7 +391,7 @@ static int nic_init(struct ioc3 *ioc3)
}
printk("Found %s NIC", type);
- if (type != "unknown") {
+ if (type != unknown) {
printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x,"
" CRC %02x", serial[0], serial[1], serial[2],
serial[3], serial[4], serial[5], crc);
@@ -1103,20 +1102,28 @@ static int ioc3_close(struct net_device *dev)
* MiniDINs; all other subdevices are left swinging in the wind, leave
* them disabled.
*/
-static inline int ioc3_is_menet(struct pci_dev *pdev)
+
+static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot)
+{
+ struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0));
+ int ret = 0;
+
+ if (dev) {
+ if (dev->vendor == PCI_VENDOR_ID_SGI &&
+ dev->device == PCI_DEVICE_ID_SGI_IOC3)
+ ret = 1;
+ pci_dev_put(dev);
+ }
+
+ return ret;
+}
+
+static int ioc3_is_menet(struct pci_dev *pdev)
{
- struct pci_dev *dev;
-
- return pdev->bus->parent == NULL
- && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(0, 0)))
- && dev->vendor == PCI_VENDOR_ID_SGI
- && dev->device == PCI_DEVICE_ID_SGI_IOC3
- && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(1, 0)))
- && dev->vendor == PCI_VENDOR_ID_SGI
- && dev->device == PCI_DEVICE_ID_SGI_IOC3
- && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(2, 0)))
- && dev->vendor == PCI_VENDOR_ID_SGI
- && dev->device == PCI_DEVICE_ID_SGI_IOC3;
+ return pdev->bus->parent == NULL &&
+ ioc3_adjacent_is_ioc3(pdev, 0) &&
+ ioc3_adjacent_is_ioc3(pdev, 1) &&
+ ioc3_adjacent_is_ioc3(pdev, 2);
}
#ifdef CONFIG_SERIAL_8250
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index fef3193121f9..9a343b965975 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -577,7 +577,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
struct mace_data *mp = netdev_priv(dev);
volatile struct mace *mb = mp->mace;
int intr, fs;
- unsigned int flags;
+ unsigned long flags;
/* don't want the dma interrupt handler to fire */
local_irq_save(flags);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index d0cc122fa3f0..e1732c164a40 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -60,6 +60,7 @@
#include <linux/crc32.h>
#include <linux/moduleparam.h>
#include <linux/io.h>
+#include <linux/log2.h>
#include <net/checksum.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -1804,7 +1805,7 @@ static int myri10ge_open(struct net_device *dev)
*/
big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) {
- while ((big_pow2 & (big_pow2 - 1)) != 0)
+ while (!is_power_of_2(big_pow2))
big_pow2++;
mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
} else {
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 619503742b7d..325269d8ae38 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1097,109 +1097,6 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
int netxen_nic_set_mac(struct net_device *netdev, void *p);
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
-{
- uint32_t mask = 0x7ff;
- int retries = 32;
-
- DPRINTK(1, INFO, "Entered ISR Disable \n");
-
- switch (adapter->portnum) {
- case 0:
- writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
- break;
- case 1:
- writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
- break;
- case 2:
- writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
- break;
- case 3:
- writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
- break;
- }
-
- if (adapter->intr_scheme != -1 &&
- adapter->intr_scheme != INTR_SCHEME_PERPORT) {
- writel(mask,
- (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
- }
-
- /* Window = 0 or 1 */
- if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- do {
- writel(0xffffffff, (void *)
- (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)));
- mask = readl((void *)
- (pci_base_offset(adapter, ISR_INT_VECTOR)));
- if (!(mask & 0x80))
- break;
- udelay(10);
- } while (--retries);
-
- if (!retries) {
- printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
- netxen_nic_driver_name);
- }
- }
-
- DPRINTK(1, INFO, "Done with Disable Int\n");
-
- return;
-}
-
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
-{
- u32 mask;
-
- DPRINTK(1, INFO, "Entered ISR Enable \n");
-
- if (adapter->intr_scheme != -1 &&
- adapter->intr_scheme != INTR_SCHEME_PERPORT) {
- switch (adapter->ahw.board_type) {
- case NETXEN_NIC_GBE:
- mask = 0x77b;
- break;
- case NETXEN_NIC_XGBE:
- mask = 0x77f;
- break;
- default:
- mask = 0x7ff;
- break;
- }
-
- writel(mask,
- (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
- }
- switch (adapter->portnum) {
- case 0:
- writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
- break;
- case 1:
- writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
- break;
- case 2:
- writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
- break;
- case 3:
- writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
- break;
- }
-
- if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- mask = 0xbff;
- if (adapter->intr_scheme != -1 &&
- adapter->intr_scheme != INTR_SCHEME_PERPORT) {
- writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
- }
- writel(mask,
- (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)));
- }
-
- DPRINTK(1, INFO, "Done with enable Int\n");
-
- return;
-}
/*
* NetXen Board information
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index a66ff58366cf..56f8197b953b 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -156,6 +156,103 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter
#define ADAPTER_LIST_SIZE 12
int netxen_cards_found;
+static void netxen_nic_disable_int(struct netxen_adapter *adapter)
+{
+ uint32_t mask = 0x7ff;
+ int retries = 32;
+
+ DPRINTK(1, INFO, "Entered ISR Disable \n");
+
+ switch (adapter->portnum) {
+ case 0:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+ break;
+ case 1:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+ break;
+ case 2:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+ break;
+ case 3:
+ writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+ break;
+ }
+
+ if (adapter->intr_scheme != -1 &&
+ adapter->intr_scheme != INTR_SCHEME_PERPORT)
+ writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+
+ /* Window = 0 or 1 */
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ do {
+ writel(0xffffffff,
+ PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS));
+ mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
+ if (!(mask & 0x80))
+ break;
+ udelay(10);
+ } while (--retries);
+
+ if (!retries) {
+ printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
+ netxen_nic_driver_name);
+ }
+ }
+
+ DPRINTK(1, INFO, "Done with Disable Int\n");
+}
+
+static void netxen_nic_enable_int(struct netxen_adapter *adapter)
+{
+ u32 mask;
+
+ DPRINTK(1, INFO, "Entered ISR Enable \n");
+
+ if (adapter->intr_scheme != -1 &&
+ adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+ switch (adapter->ahw.board_type) {
+ case NETXEN_NIC_GBE:
+ mask = 0x77b;
+ break;
+ case NETXEN_NIC_XGBE:
+ mask = 0x77f;
+ break;
+ default:
+ mask = 0x7ff;
+ break;
+ }
+
+ writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+ }
+
+ switch (adapter->portnum) {
+ case 0:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+ break;
+ case 1:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+ break;
+ case 2:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+ break;
+ case 3:
+ writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+ break;
+ }
+
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ mask = 0xbff;
+ if (adapter->intr_scheme != -1 &&
+ adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+ writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ }
+ writel(mask,
+ PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK));
+ }
+
+ DPRINTK(1, INFO, "Done with enable Int\n");
+}
+
/*
* netxen_nic_probe()
*
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index f2613c29b008..63de89e93b70 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1581,6 +1581,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
+ PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e),
PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
PCMCIA_DEVICE_PROD_ID123("CNet ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b),
PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e),
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index fbe1104e9a07..d2ede5ff9fff 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -254,77 +254,84 @@ static int m88e1145_config_init(struct phy_device *phydev)
return 0;
}
-static struct phy_driver m88e1101_driver = {
- .phy_id = 0x01410c60,
- .phy_id_mask = 0xfffffff0,
- .name = "Marvell 88E1101",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_INTERRUPT,
- .config_aneg = &marvell_config_aneg,
- .read_status = &genphy_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .driver = {.owner = THIS_MODULE,},
-};
-
-static struct phy_driver m88e1111_driver = {
- .phy_id = 0x01410cc0,
- .phy_id_mask = 0xfffffff0,
- .name = "Marvell 88E1111",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_INTERRUPT,
- .config_aneg = &marvell_config_aneg,
- .read_status = &genphy_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .config_init = &m88e1111_config_init,
- .driver = {.owner = THIS_MODULE,},
-};
-
-static struct phy_driver m88e1145_driver = {
- .phy_id = 0x01410cd0,
- .phy_id_mask = 0xfffffff0,
- .name = "Marvell 88E1145",
- .features = PHY_GBIT_FEATURES,
- .flags = PHY_HAS_INTERRUPT,
- .config_init = &m88e1145_config_init,
- .config_aneg = &marvell_config_aneg,
- .read_status = &genphy_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .driver = {.owner = THIS_MODULE,},
+static struct phy_driver marvell_drivers[] = {
+ {
+ .phy_id = 0x01410c60,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Marvell 88E1101",
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_aneg = &marvell_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .driver = {.owner = THIS_MODULE,},
+ },
+ {
+ .phy_id = 0x01410c90,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Marvell 88E1112",
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &m88e1111_config_init,
+ .config_aneg = &marvell_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .driver = {.owner = THIS_MODULE,},
+ },
+ {
+ .phy_id = 0x01410cc0,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Marvell 88E1111",
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &m88e1111_config_init,
+ .config_aneg = &marvell_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .driver = {.owner = THIS_MODULE,},
+ },
+ {
+ .phy_id = 0x01410cd0,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Marvell 88E1145",
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &m88e1145_config_init,
+ .config_aneg = &marvell_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .driver = {.owner = THIS_MODULE,},
+ }
};
static int __init marvell_init(void)
{
int ret;
+ int i;
- ret = phy_driver_register(&m88e1101_driver);
- if (ret)
- return ret;
+ for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
+ ret = phy_driver_register(&marvell_drivers[i]);
- ret = phy_driver_register(&m88e1111_driver);
- if (ret)
- goto err1111;
-
- ret = phy_driver_register(&m88e1145_driver);
- if (ret)
- goto err1145;
+ if (ret) {
+ while (i-- > 0)
+ phy_driver_unregister(&marvell_drivers[i]);
+ return ret;
+ }
+ }
return 0;
-
-err1145:
- phy_driver_unregister(&m88e1111_driver);
-err1111:
- phy_driver_unregister(&m88e1101_driver);
- return ret;
}
static void __exit marvell_exit(void)
{
- phy_driver_unregister(&m88e1101_driver);
- phy_driver_unregister(&m88e1111_driver);
- phy_driver_unregister(&m88e1145_driver);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
+ phy_driver_unregister(&marvell_drivers[i]);
}
module_init(marvell_init);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
new file mode 100644
index 000000000000..08d25066f051
--- /dev/null
+++ b/drivers/net/ps3_gelic_net.c
@@ -0,0 +1,1576 @@
+/*
+ * PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * This file is based on: spider_net.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ * Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+
+#include <linux/dma-mapping.h>
+#include <net/checksum.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#include "ps3_gelic_net.h"
+
+#define DRV_NAME "Gelic Network Driver"
+#define DRV_VERSION "1.0"
+
+MODULE_AUTHOR("SCE Inc.");
+MODULE_DESCRIPTION("Gelic Network driver");
+MODULE_LICENSE("GPL");
+
+static inline struct device *ctodev(struct gelic_net_card *card)
+{
+ return &card->dev->core;
+}
+static inline unsigned int bus_id(struct gelic_net_card *card)
+{
+ return card->dev->bus_id;
+}
+static inline unsigned int dev_id(struct gelic_net_card *card)
+{
+ return card->dev->dev_id;
+}
+
+/* set irq_mask */
+static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
+{
+ int status;
+
+ status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card),
+ mask, 0);
+ if (status)
+ dev_info(ctodev(card),
+ "lv1_net_set_interrupt_mask failed %d\n", status);
+ return status;
+}
+static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
+{
+ gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
+}
+static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
+{
+ gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
+}
+/**
+ * gelic_net_get_descr_status -- returns the status of a descriptor
+ * @descr: descriptor to look at
+ *
+ * returns the status as in the dmac_cmd_status field of the descriptor
+ */
+static enum gelic_net_descr_status
+gelic_net_get_descr_status(struct gelic_net_descr *descr)
+{
+ u32 cmd_status;
+
+ cmd_status = descr->dmac_cmd_status;
+ cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
+ return cmd_status;
+}
+
+/**
+ * gelic_net_set_descr_status -- sets the status of a descriptor
+ * @descr: descriptor to change
+ * @status: status to set in the descriptor
+ *
+ * changes the status to the specified value. Doesn't change other bits
+ * in the status
+ */
+static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
+ enum gelic_net_descr_status status)
+{
+ u32 cmd_status;
+
+ /* read the status */
+ cmd_status = descr->dmac_cmd_status;
+ /* clean the upper 4 bits */
+ cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
+ /* add the status to it */
+ cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
+ /* and write it back */
+ descr->dmac_cmd_status = cmd_status;
+ /*
+ * dma_cmd_status field is used to indicate whether the descriptor
+ * is valid or not.
+ * Usually caller of this function wants to inform that to the
+ * hardware, so we assure here the hardware sees the change.
+ */
+ wmb();
+}
+
+/**
+ * gelic_net_free_chain - free descriptor chain
+ * @card: card structure
+ * @descr_in: address of desc
+ */
+static void gelic_net_free_chain(struct gelic_net_card *card,
+ struct gelic_net_descr *descr_in)
+{
+ struct gelic_net_descr *descr;
+
+ for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
+ dma_unmap_single(ctodev(card), descr->bus_addr,
+ GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
+ descr->bus_addr = 0;
+ }
+}
+
+/**
+ * gelic_net_init_chain - links descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ * @no: number of descriptors
+ *
+ * we manage a circular list that mirrors the hardware structure,
+ * except that the hardware uses bus addresses.
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_init_chain(struct gelic_net_card *card,
+ struct gelic_net_descr_chain *chain,
+ struct gelic_net_descr *start_descr, int no)
+{
+ int i;
+ struct gelic_net_descr *descr;
+
+ descr = start_descr;
+ memset(descr, 0, sizeof(*descr) * no);
+
+ /* set up the hardware pointers in each descriptor */
+ for (i = 0; i < no; i++, descr++) {
+ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ descr->bus_addr =
+ dma_map_single(ctodev(card), descr,
+ GELIC_NET_DESCR_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ if (!descr->bus_addr)
+ goto iommu_error;
+
+ descr->next = descr + 1;
+ descr->prev = descr - 1;
+ }
+ /* make them as ring */
+ (descr - 1)->next = start_descr;
+ start_descr->prev = (descr - 1);
+
+ /* chain bus addr of hw descriptor */
+ descr = start_descr;
+ for (i = 0; i < no; i++, descr++) {
+ descr->next_descr_addr = descr->next->bus_addr;
+ }
+
+ chain->head = start_descr;
+ chain->tail = start_descr;
+
+ /* do not chain last hw descriptor */
+ (descr - 1)->next_descr_addr = 0;
+
+ return 0;
+
+iommu_error:
+ for (i--, descr--; 0 <= i; i--, descr--)
+ if (descr->bus_addr)
+ dma_unmap_single(ctodev(card), descr->bus_addr,
+ GELIC_NET_DESCR_SIZE,
+ DMA_BIDIRECTIONAL);
+ return -ENOMEM;
+}
+
+/**
+ * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * @card: card structure
+ * @descr: descriptor to re-init
+ *
+ * return 0 on succes, <0 on failure
+ *
+ * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
+ * Activate the descriptor state-wise
+ */
+static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
+ struct gelic_net_descr *descr)
+{
+ int offset;
+ unsigned int bufsize;
+
+ if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) {
+ dev_info(ctodev(card), "%s: ERROR status \n", __func__);
+ }
+ /* we need to round up the buffer size to a multiple of 128 */
+ bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
+
+ /* and we need to have it 128 byte aligned, therefore we allocate a
+ * bit more */
+ descr->skb = netdev_alloc_skb(card->netdev,
+ bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+ if (!descr->skb) {
+ descr->buf_addr = 0; /* tell DMAC don't touch memory */
+ dev_info(ctodev(card),
+ "%s:allocate skb failed !!\n", __func__);
+ return -ENOMEM;
+ }
+ descr->buf_size = bufsize;
+ descr->dmac_cmd_status = 0;
+ descr->result_size = 0;
+ descr->valid_size = 0;
+ descr->data_error = 0;
+
+ offset = ((unsigned long)descr->skb->data) &
+ (GELIC_NET_RXBUF_ALIGN - 1);
+ if (offset)
+ skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
+ /* io-mmu-map the skb */
+ descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
+ GELIC_NET_MAX_MTU,
+ DMA_FROM_DEVICE);
+ if (!descr->buf_addr) {
+ dev_kfree_skb_any(descr->skb);
+ descr->skb = NULL;
+ dev_info(ctodev(card),
+ "%s:Could not iommu-map rx buffer\n", __func__);
+ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ return -ENOMEM;
+ } else {
+ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+ return 0;
+ }
+}
+
+/**
+ * gelic_net_release_rx_chain - free all skb of rx descr
+ * @card: card structure
+ *
+ */
+static void gelic_net_release_rx_chain(struct gelic_net_card *card)
+{
+ struct gelic_net_descr *descr = card->rx_chain.head;
+
+ do {
+ if (descr->skb) {
+ dma_unmap_single(ctodev(card),
+ descr->buf_addr,
+ descr->skb->len,
+ DMA_FROM_DEVICE);
+ descr->buf_addr = 0;
+ dev_kfree_skb_any(descr->skb);
+ descr->skb = NULL;
+ descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE;
+ }
+ descr = descr->next;
+ } while (descr != card->rx_chain.head);
+}
+
+/**
+ * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
+ * @card: card structure
+ *
+ * fills all descriptors in the rx chain: allocates skbs
+ * and iommu-maps them.
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
+{
+ struct gelic_net_descr *descr = card->rx_chain.head;
+ int ret;
+
+ do {
+ if (!descr->skb) {
+ ret = gelic_net_prepare_rx_descr(card, descr);
+ if (ret)
+ goto rewind;
+ }
+ descr = descr->next;
+ } while (descr != card->rx_chain.head);
+
+ return 0;
+rewind:
+ gelic_net_release_rx_chain(card);
+ return ret;
+}
+
+/**
+ * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * @card: card structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+{
+ struct gelic_net_descr_chain *chain;
+ int ret;
+ chain = &card->rx_chain;
+ ret = gelic_net_fill_rx_chain(card);
+ chain->head = card->rx_top->prev; /* point to the last */
+ return ret;
+}
+
+/**
+ * gelic_net_release_tx_descr - processes a used tx descriptor
+ * @card: card structure
+ * @descr: descriptor to release
+ *
+ * releases a used tx descriptor (unmapping, freeing of skb)
+ */
+static void gelic_net_release_tx_descr(struct gelic_net_card *card,
+ struct gelic_net_descr *descr)
+{
+ struct sk_buff *skb;
+
+
+ if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) {
+ /* 2nd descriptor */
+ skb = descr->skb;
+ dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
+ DMA_TO_DEVICE);
+ dev_kfree_skb_any(skb);
+ } else {
+ dma_unmap_single(ctodev(card), descr->buf_addr,
+ descr->buf_size, DMA_TO_DEVICE);
+ }
+
+ descr->buf_addr = 0;
+ descr->buf_size = 0;
+ descr->next_descr_addr = 0;
+ descr->result_size = 0;
+ descr->valid_size = 0;
+ descr->data_status = 0;
+ descr->data_error = 0;
+ descr->skb = NULL;
+
+ /* set descr status */
+ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+}
+
+/**
+ * gelic_net_release_tx_chain - processes sent tx descriptors
+ * @card: adapter structure
+ * @stop: net_stop sequence
+ *
+ * releases the tx descriptors that gelic has finished with
+ */
+static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+{
+ struct gelic_net_descr_chain *tx_chain;
+ enum gelic_net_descr_status status;
+ int release = 0;
+
+ for (tx_chain = &card->tx_chain;
+ tx_chain->head != tx_chain->tail && tx_chain->tail;
+ tx_chain->tail = tx_chain->tail->next) {
+ status = gelic_net_get_descr_status(tx_chain->tail);
+ switch (status) {
+ case GELIC_NET_DESCR_RESPONSE_ERROR:
+ case GELIC_NET_DESCR_PROTECTION_ERROR:
+ case GELIC_NET_DESCR_FORCE_END:
+ if (printk_ratelimit())
+ dev_info(ctodev(card),
+ "%s: forcing end of tx descriptor " \
+ "with status %x\n",
+ __func__, status);
+ card->netdev_stats.tx_dropped++;
+ break;
+
+ case GELIC_NET_DESCR_COMPLETE:
+ card->netdev_stats.tx_packets++;
+ card->netdev_stats.tx_bytes +=
+ tx_chain->tail->skb->len;
+ break;
+
+ case GELIC_NET_DESCR_CARDOWNED:
+ /* pending tx request */
+ default:
+ /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+ goto out;
+ }
+ gelic_net_release_tx_descr(card, tx_chain->tail);
+ release = 1;
+ }
+out:
+ if (!stop && release)
+ netif_wake_queue(card->netdev);
+}
+
+/**
+ * gelic_net_set_multi - sets multicast addresses and promisc flags
+ * @netdev: interface device structure
+ *
+ * gelic_net_set_multi configures multicast addresses as needed for the
+ * netdev interface. It also sets up multicast, allmulti and promisc
+ * flags appropriately
+ */
+static void gelic_net_set_multi(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+ struct dev_mc_list *mc;
+ unsigned int i;
+ uint8_t *p;
+ u64 addr;
+ int status;
+
+ /* clear all multicast address */
+ status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card),
+ 0, 1);
+ if (status)
+ dev_err(ctodev(card),
+ "lv1_net_remove_multicast_address failed %d\n",
+ status);
+ /* set broadcast address */
+ status = lv1_net_add_multicast_address(bus_id(card), dev_id(card),
+ GELIC_NET_BROADCAST_ADDR, 0);
+ if (status)
+ dev_err(ctodev(card),
+ "lv1_net_add_multicast_address failed, %d\n",
+ status);
+
+ if (netdev->flags & IFF_ALLMULTI
+ || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+ status = lv1_net_add_multicast_address(bus_id(card),
+ dev_id(card),
+ 0, 1);
+ if (status)
+ dev_err(ctodev(card),
+ "lv1_net_add_multicast_address failed, %d\n",
+ status);
+ return;
+ }
+
+ /* set multicast address */
+ for (mc = netdev->mc_list; mc; mc = mc->next) {
+ addr = 0;
+ p = mc->dmi_addr;
+ for (i = 0; i < ETH_ALEN; i++) {
+ addr <<= 8;
+ addr |= *p++;
+ }
+ status = lv1_net_add_multicast_address(bus_id(card),
+ dev_id(card),
+ addr, 0);
+ if (status)
+ dev_err(ctodev(card),
+ "lv1_net_add_multicast_address failed, %d\n",
+ status);
+ }
+}
+
+/**
+ * gelic_net_enable_rxdmac - enables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * in the GDADMACCNTR register
+ */
+static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
+{
+ int status;
+
+ status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
+ card->rx_chain.tail->bus_addr, 0);
+ if (status)
+ dev_info(ctodev(card),
+ "lv1_net_start_rx_dma failed, status=%d\n", status);
+}
+
+/**
+ * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
+{
+ int status;
+
+ /* this hvc blocks until the DMA in progress really stopped */
+ status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0);
+ if (status)
+ dev_err(ctodev(card),
+ "lv1_net_stop_rx_dma faild, %d\n", status);
+}
+
+/**
+ * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
+{
+ int status;
+
+ /* this hvc blocks until the DMA in progress really stopped */
+ status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0);
+ if (status)
+ dev_err(ctodev(card),
+ "lv1_net_stop_tx_dma faild, status=%d\n", status);
+}
+
+/**
+ * gelic_net_stop - called upon ifconfig down
+ * @netdev: interface device structure
+ *
+ * always returns 0
+ */
+static int gelic_net_stop(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+
+ netif_poll_disable(netdev);
+ netif_stop_queue(netdev);
+
+ /* turn off DMA, force end */
+ gelic_net_disable_rxdmac(card);
+ gelic_net_disable_txdmac(card);
+
+ gelic_net_set_irq_mask(card, 0);
+
+ /* disconnect event port */
+ free_irq(card->netdev->irq, card->netdev);
+ ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
+ card->netdev->irq = NO_IRQ;
+
+ netif_carrier_off(netdev);
+
+ /* release chains */
+ gelic_net_release_tx_chain(card, 1);
+ gelic_net_release_rx_chain(card);
+
+ gelic_net_free_chain(card, card->tx_top);
+ gelic_net_free_chain(card, card->rx_top);
+
+ return 0;
+}
+
+/**
+ * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * @card: device structure to get descriptor from
+ *
+ * returns the address of the next descriptor, or NULL if not available.
+ */
+static struct gelic_net_descr *
+gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+{
+ if (!card->tx_chain.head)
+ return NULL;
+ /* see if we can two consecutive free descrs */
+ if (card->tx_chain.tail != card->tx_chain.head->next &&
+ gelic_net_get_descr_status(card->tx_chain.head) ==
+ GELIC_NET_DESCR_NOT_IN_USE &&
+ card->tx_chain.tail != card->tx_chain.head->next->next &&
+ gelic_net_get_descr_status(card->tx_chain.head->next) ==
+ GELIC_NET_DESCR_NOT_IN_USE )
+ return card->tx_chain.head;
+ else
+ return NULL;
+
+}
+
+/**
+ * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
+ * @descr: descriptor structure to fill out
+ * @skb: packet to consider
+ * @middle: middle of frame
+ *
+ * fills out the command and status field of the descriptor structure,
+ * depending on hardware checksum settings. This function assumes a wmb()
+ * has executed before.
+ */
+static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
+ struct sk_buff *skb, int middle)
+{
+ u32 eofr;
+
+ if (middle)
+ eofr = 0;
+ else
+ eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
+ else {
+ /* is packet ip?
+ * if yes: tcp? udp? */
+ if (skb->protocol == htons(ETH_P_IP)) {
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+ descr->dmac_cmd_status =
+ GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr;
+ else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
+ descr->dmac_cmd_status =
+ GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr;
+ else /*
+ * the stack should checksum non-tcp and non-udp
+ * packets on his own: NETIF_F_IP_CSUM
+ */
+ descr->dmac_cmd_status =
+ GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
+ }
+ }
+}
+
+/**
+ * gelic_net_prepare_tx_descr_v - get dma address of skb_data
+ * @card: card structure
+ * @descr: descriptor structure
+ * @skb: packet to use
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
+ struct gelic_net_descr *descr,
+ struct sk_buff *skb)
+{
+ dma_addr_t buf[2];
+ unsigned int vlan_len;
+
+ if (skb->len < GELIC_NET_VLAN_POS)
+ return -EINVAL;
+
+ memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS);
+ if (card->vlan_index != -1) {
+ descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
+ descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
+ vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
+ } else
+ vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+
+ /* first descr */
+ buf[0] = dma_map_single(ctodev(card), &descr->vlan,
+ vlan_len, DMA_TO_DEVICE);
+
+ if (!buf[0]) {
+ dev_err(ctodev(card),
+ "dma map 1 failed (%p, %i). Dropping packet\n",
+ skb->data, vlan_len);
+ return -ENOMEM;
+ }
+
+ descr->buf_addr = buf[0];
+ descr->buf_size = vlan_len;
+ descr->skb = skb; /* not used */
+ descr->data_status = 0;
+ gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
+
+ /* second descr */
+ card->tx_chain.head = card->tx_chain.head->next;
+ descr->next_descr_addr = descr->next->bus_addr;
+ descr = descr->next;
+ if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE)
+ /* XXX will be removed */
+ dev_err(ctodev(card), "descr is not free!\n");
+
+ buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS,
+ skb->len - GELIC_NET_VLAN_POS,
+ DMA_TO_DEVICE);
+
+ if (!buf[1]) {
+ dev_err(ctodev(card),
+ "dma map 2 failed (%p, %i). Dropping packet\n",
+ skb->data + GELIC_NET_VLAN_POS,
+ skb->len - GELIC_NET_VLAN_POS);
+ dma_unmap_single(ctodev(card), buf[0], vlan_len,
+ DMA_TO_DEVICE);
+ return -ENOMEM;
+ }
+
+ descr->buf_addr = buf[1];
+ descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+ descr->skb = skb;
+ descr->data_status = 0;
+ descr->next_descr_addr = 0; /* terminate hw descr */
+ gelic_net_set_txdescr_cmdstat(descr, skb, 0);
+
+ return 0;
+}
+
+/**
+ * gelic_net_kick_txdma - enables TX DMA processing
+ * @card: card structure
+ * @descr: descriptor address to enable TX processing at
+ *
+ */
+static int gelic_net_kick_txdma(struct gelic_net_card *card,
+ struct gelic_net_descr *descr)
+{
+ int status = -ENXIO;
+ int count = 10;
+
+ if (card->tx_dma_progress)
+ return 0;
+
+ if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+ card->tx_dma_progress = 1;
+ /* sometimes we need retry here */
+ while (count--) {
+ status = lv1_net_start_tx_dma(bus_id(card),
+ dev_id(card),
+ descr->bus_addr, 0);
+ if (!status)
+ break;
+ }
+ if (!count)
+ dev_info(ctodev(card), "lv1_net_start_txdma failed," \
+ "status=%d %#lx\n",
+ status, card->irq_status);
+ }
+ return status;
+}
+
+/**
+ * gelic_net_xmit - transmits a frame over the device
+ * @skb: packet to send out
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_net_descr *descr = NULL;
+ int result;
+ unsigned long flags;
+
+ spin_lock_irqsave(&card->tx_dma_lock, flags);
+
+ gelic_net_release_tx_chain(card, 0);
+ if (!skb)
+ goto kick;
+ descr = gelic_net_get_next_tx_descr(card);
+ if (!descr) {
+ netif_stop_queue(netdev);
+ spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+ result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+
+ if (result)
+ goto error;
+
+ card->tx_chain.head = card->tx_chain.head->next;
+
+ if (descr->prev)
+ descr->prev->next_descr_addr = descr->bus_addr;
+kick:
+ /*
+ * as hardware descriptor is modified in the above lines,
+ * ensure that the hardware sees it
+ */
+ wmb();
+ if (gelic_net_kick_txdma(card, card->tx_chain.tail))
+ goto error;
+
+ netdev->trans_start = jiffies;
+ spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ return NETDEV_TX_OK;
+
+error:
+ card->netdev_stats.tx_dropped++;
+ spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ return NETDEV_TX_LOCKED;
+}
+
+/**
+ * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
+ * @descr: descriptor to process
+ * @card: card structure
+ *
+ * iommu-unmaps the skb, fills out skb structure and passes the data to the
+ * stack. The descriptor state is not changed.
+ */
+static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
+ struct gelic_net_card *card)
+{
+ struct sk_buff *skb;
+ struct net_device *netdev;
+ u32 data_status, data_error;
+
+ data_status = descr->data_status;
+ data_error = descr->data_error;
+ netdev = card->netdev;
+ /* unmap skb buffer */
+ skb = descr->skb;
+ dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
+ DMA_FROM_DEVICE);
+
+ skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
+ if (!descr->valid_size)
+ dev_info(ctodev(card), "buffer full %x %x %x\n",
+ descr->result_size, descr->buf_size,
+ descr->dmac_cmd_status);
+
+ descr->skb = NULL;
+ /*
+ * the card put 2 bytes vlan tag in front
+ * of the ethernet frame
+ */
+ skb_pull(skb, 2);
+ skb->protocol = eth_type_trans(skb, netdev);
+
+ /* checksum offload */
+ if (card->rx_csum) {
+ if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
+ (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+ } else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ /* update netdevice statistics */
+ card->netdev_stats.rx_packets++;
+ card->netdev_stats.rx_bytes += skb->len;
+
+ /* pass skb up to stack */
+ netif_receive_skb(skb);
+}
+
+/**
+ * gelic_net_decode_one_descr - processes an rx descriptor
+ * @card: card structure
+ *
+ * returns 1 if a packet has been sent to the stack, otherwise 0
+ *
+ * processes an rx descriptor by iommu-unmapping the data buffer and passing
+ * the packet up to the stack
+ */
+static int gelic_net_decode_one_descr(struct gelic_net_card *card)
+{
+ enum gelic_net_descr_status status;
+ struct gelic_net_descr_chain *chain = &card->rx_chain;
+ struct gelic_net_descr *descr = chain->tail;
+ int dmac_chain_ended;
+
+ status = gelic_net_get_descr_status(descr);
+ /* is this descriptor terminated with next_descr == NULL? */
+ dmac_chain_ended =
+ descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
+
+ if (status == GELIC_NET_DESCR_CARDOWNED)
+ return 0;
+
+ if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+ dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
+ return 0;
+ }
+
+ if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
+ (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
+ (status == GELIC_NET_DESCR_FORCE_END)) {
+ dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
+ status);
+ card->netdev_stats.rx_dropped++;
+ goto refill;
+ }
+
+ if ((status != GELIC_NET_DESCR_COMPLETE) &&
+ (status != GELIC_NET_DESCR_FRAME_END)) {
+ dev_dbg(ctodev(card), "RX descriptor with state %x\n",
+ status);
+ goto refill;
+ }
+
+ /* ok, we've got a packet in descr */
+ gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
+
+refill:
+ descr->next_descr_addr = 0; /* unlink the descr */
+
+ /* change the descriptor state: */
+ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+
+ /* refill one desc
+ * FIXME: this can fail, but for now, just leave this
+ * descriptor without skb
+ */
+ gelic_net_prepare_rx_descr(card, descr);
+ chain->head = descr;
+ chain->tail = descr->next;
+ descr->prev->next_descr_addr = descr->bus_addr;
+
+ if (dmac_chain_ended) {
+ gelic_net_enable_rxdmac(card);
+ dev_dbg(ctodev(card), "reenable rx dma\n");
+ }
+
+ return 1;
+}
+
+/**
+ * gelic_net_poll - NAPI poll function called by the stack to return packets
+ * @netdev: interface device structure
+ * @budget: number of packets we can pass to the stack at most
+ *
+ * returns 0 if no more packets available to the driver/stack. Returns 1,
+ * if the quota is exceeded, but the driver has still packets.
+ *
+ */
+static int gelic_net_poll(struct net_device *netdev, int *budget)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+ int packets_to_do, packets_done = 0;
+ int no_more_packets = 0;
+
+ packets_to_do = min(*budget, netdev->quota);
+
+ while (packets_to_do) {
+ if (gelic_net_decode_one_descr(card)) {
+ packets_done++;
+ packets_to_do--;
+ } else {
+ /* no more packets for the stack */
+ no_more_packets = 1;
+ break;
+ }
+ }
+ netdev->quota -= packets_done;
+ *budget -= packets_done;
+ if (no_more_packets) {
+ netif_rx_complete(netdev);
+ gelic_net_rx_irq_on(card);
+ return 0;
+ } else
+ return 1;
+}
+
+/**
+ * gelic_net_get_stats - get interface statistics
+ * @netdev: interface device structure
+ *
+ * returns the interface statistics residing in the gelic_net_card struct
+ */
+static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+
+ return &card->netdev_stats;
+}
+
+/**
+ * gelic_net_change_mtu - changes the MTU of an interface
+ * @netdev: interface device structure
+ * @new_mtu: new MTU value
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ /* no need to re-alloc skbs or so -- the max mtu is about 2.3k
+ * and mtu is outbound only anyway */
+ if ((new_mtu < GELIC_NET_MIN_MTU) ||
+ (new_mtu > GELIC_NET_MAX_MTU)) {
+ return -EINVAL;
+ }
+ netdev->mtu = new_mtu;
+ return 0;
+}
+
+/**
+ * gelic_net_interrupt - event handler for gelic_net
+ */
+static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
+{
+ unsigned long flags;
+ struct net_device *netdev = ptr;
+ struct gelic_net_card *card = netdev_priv(netdev);
+ u64 status;
+
+ status = card->irq_status;
+
+ if (!status)
+ return IRQ_NONE;
+
+ if (status & GELIC_NET_RXINT) {
+ gelic_net_rx_irq_off(card);
+ netif_rx_schedule(netdev);
+ }
+
+ if (status & GELIC_NET_TXINT) {
+ spin_lock_irqsave(&card->tx_dma_lock, flags);
+ card->tx_dma_progress = 0;
+ spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ /* start pending DMA */
+ gelic_net_xmit(NULL, netdev);
+ }
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * gelic_net_poll_controller - artificial interrupt for netconsole etc.
+ * @netdev: interface device structure
+ *
+ * see Documentation/networking/netconsole.txt
+ */
+static void gelic_net_poll_controller(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+
+ gelic_net_set_irq_mask(card, 0);
+ gelic_net_interrupt(netdev->irq, netdev);
+ gelic_net_set_irq_mask(card, card->ghiintmask);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+/**
+ * gelic_net_open_device - open device and map dma region
+ * @card: card structure
+ */
+static int gelic_net_open_device(struct gelic_net_card *card)
+{
+ int result;
+
+ result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY,
+ &card->netdev->irq);
+
+ if (result) {
+ dev_info(ctodev(card),
+ "%s:%d: gelic_net_open_device failed (%d)\n",
+ __func__, __LINE__, result);
+ result = -EPERM;
+ goto fail_alloc_irq;
+ }
+
+ result = request_irq(card->netdev->irq, gelic_net_interrupt,
+ IRQF_DISABLED, "gelic network", card->netdev);
+
+ if (result) {
+ dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
+ __func__, __LINE__, result);
+ goto fail_request_irq;
+ }
+
+ return 0;
+
+fail_request_irq:
+ ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
+ card->netdev->irq = NO_IRQ;
+fail_alloc_irq:
+ return result;
+}
+
+
+/**
+ * gelic_net_open - called upon ifonfig up
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * gelic_net_open allocates all the descriptors and memory needed for
+ * operation, sets up multicast list and enables interrupts
+ */
+static int gelic_net_open(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+
+ dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__);
+
+ gelic_net_open_device(card);
+
+ if (gelic_net_init_chain(card, &card->tx_chain,
+ card->descr, GELIC_NET_TX_DESCRIPTORS))
+ goto alloc_tx_failed;
+ if (gelic_net_init_chain(card, &card->rx_chain,
+ card->descr + GELIC_NET_RX_DESCRIPTORS,
+ GELIC_NET_RX_DESCRIPTORS))
+ goto alloc_rx_failed;
+
+ /* head of chain */
+ card->tx_top = card->tx_chain.head;
+ card->rx_top = card->rx_chain.head;
+ dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
+ card->rx_top, card->tx_top, sizeof(struct gelic_net_descr),
+ GELIC_NET_RX_DESCRIPTORS);
+ /* allocate rx skbs */
+ if (gelic_net_alloc_rx_skbs(card))
+ goto alloc_skbs_failed;
+
+ card->tx_dma_progress = 0;
+ card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+
+ gelic_net_set_irq_mask(card, card->ghiintmask);
+ gelic_net_enable_rxdmac(card);
+
+ netif_start_queue(netdev);
+ netif_carrier_on(netdev);
+ netif_poll_enable(netdev);
+
+ return 0;
+
+alloc_skbs_failed:
+ gelic_net_free_chain(card, card->rx_top);
+alloc_rx_failed:
+ gelic_net_free_chain(card, card->tx_top);
+alloc_tx_failed:
+ return -ENOMEM;
+}
+
+#ifdef GELIC_NET_ETHTOOL
+static void gelic_net_get_drvinfo (struct net_device *netdev,
+ struct ethtool_drvinfo *info)
+{
+ strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
+ strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
+}
+
+static int gelic_net_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *cmd)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+ int status;
+ u64 v1, v2;
+ int speed, duplex;
+
+ speed = duplex = -1;
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+ &v1, &v2);
+ if (status) {
+ /* link down */
+ } else {
+ if (v1 & GELIC_NET_FULL_DUPLEX) {
+ duplex = DUPLEX_FULL;
+ } else {
+ duplex = DUPLEX_HALF;
+ }
+
+ if (v1 & GELIC_NET_SPEED_10 ) {
+ speed = SPEED_10;
+ } else if (v1 & GELIC_NET_SPEED_100) {
+ speed = SPEED_100;
+ } else if (v1 & GELIC_NET_SPEED_1000) {
+ speed = SPEED_1000;
+ }
+ }
+ cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
+ SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+ cmd->advertising = cmd->supported;
+ cmd->speed = speed;
+ cmd->duplex = duplex;
+ cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
+ cmd->port = PORT_TP;
+
+ return 0;
+}
+
+static u32 gelic_net_get_link(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+ int status;
+ u64 v1, v2;
+ int link;
+
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+ &v1, &v2);
+ if (status)
+ return 0; /* link down */
+
+ if (v1 & GELIC_NET_LINK_UP)
+ link = 1;
+ else
+ link = 0;
+
+ return link;
+}
+
+static int gelic_net_nway_reset(struct net_device *netdev)
+{
+ if (netif_running(netdev)) {
+ gelic_net_stop(netdev);
+ gelic_net_open(netdev);
+ }
+ return 0;
+}
+
+static u32 gelic_net_get_tx_csum(struct net_device *netdev)
+{
+ return (netdev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data)
+{
+ if (data)
+ netdev->features |= NETIF_F_IP_CSUM;
+ else
+ netdev->features &= ~NETIF_F_IP_CSUM;
+
+ return 0;
+}
+
+static u32 gelic_net_get_rx_csum(struct net_device *netdev)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+
+ return card->rx_csum;
+}
+
+static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
+{
+ struct gelic_net_card *card = netdev_priv(netdev);
+
+ card->rx_csum = data;
+ return 0;
+}
+
+static struct ethtool_ops gelic_net_ethtool_ops = {
+ .get_drvinfo = gelic_net_get_drvinfo,
+ .get_settings = gelic_net_get_settings,
+ .get_link = gelic_net_get_link,
+ .nway_reset = gelic_net_nway_reset,
+ .get_tx_csum = gelic_net_get_tx_csum,
+ .set_tx_csum = gelic_net_set_tx_csum,
+ .get_rx_csum = gelic_net_get_rx_csum,
+ .set_rx_csum = gelic_net_set_rx_csum,
+};
+#endif
+
+/**
+ * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
+ * function (to be called not under interrupt status)
+ * @work: work is context of tx timout task
+ *
+ * called as task when tx hangs, resets interface (if interface is up)
+ */
+static void gelic_net_tx_timeout_task(struct work_struct *work)
+{
+ struct gelic_net_card *card =
+ container_of(work, struct gelic_net_card, tx_timeout_task);
+ struct net_device *netdev = card->netdev;
+
+ dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
+
+ if (!(netdev->flags & IFF_UP))
+ goto out;
+
+ netif_device_detach(netdev);
+ gelic_net_stop(netdev);
+
+ gelic_net_open(netdev);
+ netif_device_attach(netdev);
+
+out:
+ atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
+ * @netdev: interface device structure
+ *
+ * called, if tx hangs. Schedules a task that resets the interface
+ */
+static void gelic_net_tx_timeout(struct net_device *netdev)
+{
+ struct gelic_net_card *card;
+
+ card = netdev_priv(netdev);
+ atomic_inc(&card->tx_timeout_task_counter);
+ if (netdev->flags & IFF_UP)
+ schedule_work(&card->tx_timeout_task);
+ else
+ atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * @netdev: net_device structure
+ *
+ * fills out function pointers in the net_device structure
+ */
+static void gelic_net_setup_netdev_ops(struct net_device *netdev)
+{
+ netdev->open = &gelic_net_open;
+ netdev->stop = &gelic_net_stop;
+ netdev->hard_start_xmit = &gelic_net_xmit;
+ netdev->get_stats = &gelic_net_get_stats;
+ netdev->set_multicast_list = &gelic_net_set_multi;
+ netdev->change_mtu = &gelic_net_change_mtu;
+ /* tx watchdog */
+ netdev->tx_timeout = &gelic_net_tx_timeout;
+ netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+ /* NAPI */
+ netdev->poll = &gelic_net_poll;
+ netdev->weight = GELIC_NET_NAPI_WEIGHT;
+#ifdef GELIC_NET_ETHTOOL
+ netdev->ethtool_ops = &gelic_net_ethtool_ops;
+#endif
+}
+
+/**
+ * gelic_net_setup_netdev - initialization of net_device
+ * @card: card structure
+ *
+ * Returns 0 on success or <0 on failure
+ *
+ * gelic_net_setup_netdev initializes the net_device structure
+ **/
+static int gelic_net_setup_netdev(struct gelic_net_card *card)
+{
+ struct net_device *netdev = card->netdev;
+ struct sockaddr addr;
+ unsigned int i;
+ int status;
+ u64 v1, v2;
+
+ SET_MODULE_OWNER(netdev);
+ SET_NETDEV_DEV(netdev, &card->dev->core);
+ spin_lock_init(&card->tx_dma_lock);
+
+ card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
+
+ gelic_net_setup_netdev_ops(netdev);
+
+ netdev->features = NETIF_F_IP_CSUM;
+
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_NET_GET_MAC_ADDRESS,
+ 0, 0, 0, &v1, &v2);
+ if (status || !is_valid_ether_addr((u8 *)&v1)) {
+ dev_info(ctodev(card),
+ "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
+ __func__, status);
+ return -EINVAL;
+ }
+ v1 <<= 16;
+ memcpy(addr.sa_data, &v1, ETH_ALEN);
+ memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
+ dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+ netdev->dev_addr[0], netdev->dev_addr[1],
+ netdev->dev_addr[2], netdev->dev_addr[3],
+ netdev->dev_addr[4], netdev->dev_addr[5]);
+
+ card->vlan_index = -1; /* no vlan */
+ for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
+ status = lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_NET_GET_VLAN_ID,
+ i + 1, /* index; one based */
+ 0, 0, &v1, &v2);
+ if (status == GELIC_NET_VLAN_NO_ENTRY) {
+ dev_dbg(ctodev(card),
+ "GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
+ status);
+ card->vlan_id[i] = 0;
+ } else if (status) {
+ dev_dbg(ctodev(card),
+ "%s:GELIC_NET_VLAN_ID faild, status=%d\n",
+ __func__, status);
+ card->vlan_id[i] = 0;
+ } else {
+ card->vlan_id[i] = (u32)v1;
+ dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
+ }
+ }
+ if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1])
+ card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+
+ status = register_netdev(netdev);
+ if (status) {
+ dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
+ __func__, status);
+ return status;
+ }
+
+ return 0;
+}
+
+/**
+ * gelic_net_alloc_card - allocates net_device and card structure
+ *
+ * returns the card structure or NULL in case of errors
+ *
+ * the card and net_device structures are linked to each other
+ */
+static struct gelic_net_card *gelic_net_alloc_card(void)
+{
+ struct net_device *netdev;
+ struct gelic_net_card *card;
+ size_t alloc_size;
+
+ alloc_size = sizeof (*card) +
+ sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS +
+ sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS;
+ /*
+ * we assume private data is allocated 32 bytes (or more) aligned
+ * so that gelic_net_descr should be 32 bytes aligned.
+ * Current alloc_etherdev() does do it because NETDEV_ALIGN
+ * is 32.
+ * check this assumption here.
+ */
+ BUILD_BUG_ON(NETDEV_ALIGN < 32);
+ BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8);
+ BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32);
+
+ netdev = alloc_etherdev(alloc_size);
+ if (!netdev)
+ return NULL;
+
+ card = netdev_priv(netdev);
+ card->netdev = netdev;
+ INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
+ init_waitqueue_head(&card->waitq);
+ atomic_set(&card->tx_timeout_task_counter, 0);
+
+ return card;
+}
+
+/**
+ * ps3_gelic_driver_probe - add a device to the control of this driver
+ */
+static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+{
+ struct gelic_net_card *card = gelic_net_alloc_card();
+ int result;
+
+ if (!card) {
+ dev_info(&dev->core, "gelic_net_alloc_card failed\n");
+ result = -ENOMEM;
+ goto fail_alloc_card;
+ }
+
+ ps3_system_bus_set_driver_data(dev, card);
+ card->dev = dev;
+
+ result = ps3_open_hv_device(dev);
+
+ if (result) {
+ dev_dbg(&dev->core, "ps3_open_hv_device failed\n");
+ goto fail_open;
+ }
+
+ result = ps3_dma_region_create(dev->d_region);
+
+ if (result) {
+ dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n",
+ result);
+ BUG_ON("check region type");
+ goto fail_dma_region;
+ }
+
+ result = lv1_net_set_interrupt_status_indicator(bus_id(card),
+ dev_id(card),
+ ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
+ 0);
+
+ if (result) {
+ dev_dbg(&dev->core,
+ "lv1_net_set_interrupt_status_indicator failed: %s\n",
+ ps3_result(result));
+ result = -EIO;
+ goto fail_status_indicator;
+ }
+
+ result = gelic_net_setup_netdev(card);
+
+ if (result) {
+ dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+ "(%d)\n", __func__, __LINE__, result);
+ goto fail_setup_netdev;
+ }
+
+ return 0;
+
+fail_setup_netdev:
+ lv1_net_set_interrupt_status_indicator(bus_id(card),
+ bus_id(card),
+ 0 , 0);
+fail_status_indicator:
+ ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+ ps3_close_hv_device(dev);
+fail_open:
+ ps3_system_bus_set_driver_data(dev, NULL);
+ free_netdev(card->netdev);
+fail_alloc_card:
+ return result;
+}
+
+/**
+ * ps3_gelic_driver_remove - remove a device from the control of this driver
+ */
+
+static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+{
+ struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev);
+
+ wait_event(card->waitq,
+ atomic_read(&card->tx_timeout_task_counter) == 0);
+
+ lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
+ 0 , 0);
+
+ unregister_netdev(card->netdev);
+ free_netdev(card->netdev);
+
+ ps3_system_bus_set_driver_data(dev, NULL);
+
+ ps3_dma_region_free(dev->d_region);
+
+ ps3_close_hv_device(dev);
+
+ return 0;
+}
+
+static struct ps3_system_bus_driver ps3_gelic_driver = {
+ .match_id = PS3_MATCH_ID_GELIC,
+ .probe = ps3_gelic_driver_probe,
+ .remove = ps3_gelic_driver_remove,
+ .shutdown = ps3_gelic_driver_remove,
+ .core.name = "ps3_gelic_driver",
+ .core.owner = THIS_MODULE,
+};
+
+static int __init ps3_gelic_driver_init (void)
+{
+ return firmware_has_feature(FW_FEATURE_PS3_LV1)
+ ? ps3_system_bus_driver_register(&ps3_gelic_driver)
+ : -ENODEV;
+}
+
+static void __exit ps3_gelic_driver_exit (void)
+{
+ ps3_system_bus_driver_unregister(&ps3_gelic_driver);
+}
+
+module_init (ps3_gelic_driver_init);
+module_exit (ps3_gelic_driver_exit);
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);
+
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
new file mode 100644
index 000000000000..5e1c28654e16
--- /dev/null
+++ b/drivers/net/ps3_gelic_net.h
@@ -0,0 +1,239 @@
+/*
+ * PS3 Platfom gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation.
+ *
+ * This file is based on: spider_net.h
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ * Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _GELIC_NET_H
+#define _GELIC_NET_H
+
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
+
+#define GELIC_NET_ETHTOOL /* use ethtool */
+
+/* ioctl */
+#define GELIC_NET_GET_MODE (SIOCDEVPRIVATE + 0)
+#define GELIC_NET_SET_MODE (SIOCDEVPRIVATE + 1)
+
+/* descriptors */
+#define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */
+#define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */
+
+#define GELIC_NET_MAX_MTU 2308
+#define GELIC_NET_MIN_MTU 64
+#define GELIC_NET_RXBUF_ALIGN 128
+#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */
+#define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ
+#define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS)
+#define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL
+#define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2)
+#define GELIC_NET_VLAN_MAX 4
+#define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */
+
+enum gelic_net_int0_status {
+ GELIC_NET_GDTDCEINT = 24,
+ GELIC_NET_GRFANMINT = 28,
+};
+
+/* GHIINT1STS bits */
+enum gelic_net_int1_status {
+ GELIC_NET_GDADCEINT = 14,
+};
+
+/* interrupt mask */
+#define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32))
+
+#define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32))
+#define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT)
+#define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+
+ /* RX descriptor data_status bits */
+#define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */
+#define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */
+#define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */
+#define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */
+#define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */
+#define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */
+#define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */
+#define GELIC_NET_RXSESPAH 0x01000000 /*
+ * IPsec ESP protocol auth
+ * performed
+ */
+
+#define GELIC_NET_RXWTPKT 0x00C00000 /*
+ * wakeup trigger packet
+ * 01: Magic Packet (TM)
+ * 10: ARP packet
+ * 11: Multicast MAC addr
+ */
+#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */
+/* bit 20..16 reserved */
+#define GELIC_NET_RXRECNUM 0x0000ff00 /* reception receipt number */
+/* bit 7..0 reserved */
+
+#define GELIC_NET_TXDESC_TAIL 0
+#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK)
+
+/* RX descriptor data_error bits */
+/* bit 31 reserved */
+#define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */
+#define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */
+#define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */
+#define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */
+#define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */
+#define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */
+#define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */
+#define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */
+#define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol
+ * processing */
+#define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol
+ * processing */
+#define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */
+#define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */
+/* bit 18 reserved */
+#define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */
+#define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length
+ * error */
+#define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */
+#define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */
+/* bit 13..0 reserved */
+#define GELIC_NET_DATA_ERROR_CHK_MASK \
+ (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR)
+
+
+/* tx descriptor command and status */
+#define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */
+#define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000
+#define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000
+#define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */
+
+#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end
+ * interrupt status */
+
+#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */
+#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
+#define GELIC_NET_DESCR_IND_PROC_SHIFT 28
+#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff
+
+
+enum gelic_net_descr_status {
+ GELIC_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */
+ GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */
+ GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */
+ GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */
+ GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */
+ GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */
+ GELIC_NET_DESCR_NOT_IN_USE /* any other value */
+};
+/* for lv1_net_control */
+#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001
+#define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002
+#define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003
+#define GELIC_NET_GET_VLAN_ID 0x0000000000000004
+
+#define GELIC_NET_LINK_UP 0x0000000000000001
+#define GELIC_NET_FULL_DUPLEX 0x0000000000000002
+#define GELIC_NET_AUTO_NEG 0x0000000000000004
+#define GELIC_NET_SPEED_10 0x0000000000000010
+#define GELIC_NET_SPEED_100 0x0000000000000020
+#define GELIC_NET_SPEED_1000 0x0000000000000040
+
+#define GELIC_NET_VLAN_ALL 0x0000000000000001
+#define GELIC_NET_VLAN_WIRED 0x0000000000000002
+#define GELIC_NET_VLAN_WIRELESS 0x0000000000000003
+#define GELIC_NET_VLAN_PSP 0x0000000000000004
+#define GELIC_NET_VLAN_PORT0 0x0000000000000010
+#define GELIC_NET_VLAN_PORT1 0x0000000000000011
+#define GELIC_NET_VLAN_PORT2 0x0000000000000012
+#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013
+#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014
+#define GELIC_NET_VLAN_NO_ENTRY -6
+
+#define GELIC_NET_PORT 2 /* for port status */
+
+/* size of hardware part of gelic descriptor */
+#define GELIC_NET_DESCR_SIZE (32)
+struct gelic_net_descr {
+ /* as defined by the hardware */
+ u32 buf_addr;
+ u32 buf_size;
+ u32 next_descr_addr;
+ u32 dmac_cmd_status;
+ u32 result_size;
+ u32 valid_size; /* all zeroes for tx */
+ u32 data_status;
+ u32 data_error; /* all zeroes for tx */
+
+ /* used in the driver */
+ struct sk_buff *skb;
+ dma_addr_t bus_addr;
+ struct gelic_net_descr *next;
+ struct gelic_net_descr *prev;
+ struct vlan_ethhdr vlan;
+} __attribute__((aligned(32)));
+
+struct gelic_net_descr_chain {
+ /* we walk from tail to head */
+ struct gelic_net_descr *head;
+ struct gelic_net_descr *tail;
+};
+
+struct gelic_net_card {
+ struct net_device *netdev;
+ /*
+ * hypervisor requires irq_status should be
+ * 8 bytes aligned, but u64 member is
+ * always disposed in that manner
+ */
+ u64 irq_status;
+ u64 ghiintmask;
+
+ struct ps3_system_bus_device *dev;
+ u32 vlan_id[GELIC_NET_VLAN_MAX];
+ int vlan_index;
+
+ struct gelic_net_descr_chain tx_chain;
+ struct gelic_net_descr_chain rx_chain;
+ /* gurad dmac descriptor chain*/
+ spinlock_t chain_lock;
+
+ struct net_device_stats netdev_stats;
+ int rx_csum;
+ /* guard tx_dma_progress */
+ spinlock_t tx_dma_lock;
+ int tx_dma_progress;
+
+ struct work_struct tx_timeout_task;
+ atomic_t tx_timeout_task_counter;
+ wait_queue_head_t waitq;
+
+ struct gelic_net_descr *tx_top, *rx_top;
+ struct gelic_net_descr descr[0];
+};
+
+
+extern unsigned long p_to_lp(long pa);
+
+#endif /* _GELIC_NET_H */
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 25c73d47daad..5c2e41fac6d2 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -516,7 +516,7 @@ static unsigned int write_eeprom(struct rr_private *rrpriv,
}
-static int __init rr_init(struct net_device *dev)
+static int __devinit rr_init(struct net_device *dev)
{
struct rr_private *rrpriv;
struct rr_regs __iomem *regs;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2d826fff7e2e..7d549355815a 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -796,12 +796,14 @@ static void free_shared_mem(struct s2io_nic *nic)
struct mac_info *mac_control;
struct config_param *config;
int lst_size, lst_per_page;
- struct net_device *dev = nic->dev;
+ struct net_device *dev;
int page_num = 0;
if (!nic)
return;
+ dev = nic->dev;
+
mac_control = &nic->mac_control;
config = &nic->config;
@@ -8036,7 +8038,7 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
/**
* s2io_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
- * @state: The current pci conneection state
+ * @state: The current pci connection state
*
* This function is called after a PCI bus error affecting
* this device has been detected.
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 2cb2e156c758..7c6e4808399a 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -573,7 +573,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
* return error if it failed to found.
*/
-static int __init sis900_mii_probe(struct net_device * net_dev)
+static int __devinit sis900_mii_probe(struct net_device * net_dev)
{
struct sis900_private * sis_priv = net_dev->priv;
const char *dev_name = pci_name(sis_priv->pci_dev);
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
deleted file mode 100644
index afd900d5d730..000000000000
--- a/drivers/net/sk98lin/Makefile
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# Makefile for the SysKonnect SK-98xx device driver.
-#
-
-
-#
-# Standalone driver params
-# SKPARAM += -DSK_KERNEL_24
-# SKPARAM += -DSK_KERNEL_24_26
-# SKPARAM += -DSK_KERNEL_26
-# SKPARAM += -DSK_KERNEL_22_24
-
-obj-$(CONFIG_SK98LIN) += sk98lin.o
-sk98lin-objs := \
- skge.o \
- skethtool.o \
- skdim.o \
- skaddr.o \
- skgehwt.o \
- skgeinit.o \
- skgepnmi.o \
- skgesirq.o \
- ski2c.o \
- sklm80.o \
- skqueue.o \
- skrlmt.o \
- sktimer.o \
- skvpd.o \
- skxmac2.o
-
-# DBGDEF = \
-# -DDEBUG
-
-ifdef DEBUG
-DBGDEF += \
--DSK_DEBUG_CHKMOD=0x00000000L \
--DSK_DEBUG_CHKCAT=0x00000000L
-endif
-
-
-# **** possible debug modules for SK_DEBUG_CHKMOD *****************
-# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
-# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
-# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
-# SK_DBGMOD_VPD 0x00000008L /* VPD module */
-# SK_DBGMOD_I2C 0x00000010L /* I2C module */
-# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
-# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
-# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
-# SK_DBGMOD_DRV 0x00010000L /* DRV module */
-
-# **** possible debug categories for SK_DEBUG_CHKCAT **************
-# *** common modules ***
-# SK_DBGCAT_INIT 0x00000001L module/driver initialization
-# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
-# SK_DBGCAT_ERR 0x00000004L error handling paths
-# SK_DBGCAT_TX 0x00000008L transmit path
-# SK_DBGCAT_RX 0x00000010L receive path
-# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
-# SK_DBGCAT_QUEUE 0x00000040L any queue management
-# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
-# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
-
-# *** driver (file skge.c) ***
-# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
-# SK_DBGCAT_DRV_??? 0x00020000 not used
-# SK_DBGCAT_DRV_MCA 0x00040000 multicast
-# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
-# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
-# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
-# SK_DBGCAT_DRV_??? 0x00400000 not used
-# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
-# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
-# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
-# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
-# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
-
-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
-
-clean:
- rm -f core *.o *.a *.s
-
-
-
-
-
-
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
deleted file mode 100644
index 4e2dbbf78000..000000000000
--- a/drivers/net/sk98lin/h/lm80.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/******************************************************************************
- *
- * Name: lm80.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.6 $
- * Date: $Date: 2003/05/13 17:26:52 $
- * Purpose: Contains all defines for the LM80 Chip
- * (National Semiconductor).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_LM80_H
-#define __INC_LM80_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/*
- * LM80 register definition
- *
- * All registers are 8 bit wide
- */
-#define LM80_CFG 0x00 /* Configuration Register */
-#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
-#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
-#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
-#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
-#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
-#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
- /* 0x07 - 0x1f reserved */
- /* current values */
-#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
-#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
-#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
-#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
-#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
-#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
-#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
-#define LM80_TEMP_IN 0x27 /* current Temperature value */
-#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
-#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
- /* limit values */
-#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
-#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
-#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
-#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
-#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
-#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
-#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
-#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
-#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
-#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
-#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
-#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
-#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
-#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
-#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
-#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
-#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
-#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
-#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
-#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
- /* 0x3e - 0x3f reserved */
-
-/*
- * LM80 bit definitions
- */
-
-/* LM80_CFG Configuration Register */
-#define LM80_CFG_START (1<<0) /* start monitoring operation */
-#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
-#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
-#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
-#define LM80_CFG_RESET (1<<4) /* signals a reset */
-#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
-#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
-#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
-
-/* LM80_ISRC_1 Interrupt Status Register 1 */
-/* LM80_IMSK_1 Interrupt Mask Register 1 */
-#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
-#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
-#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
-#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
-#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
-#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
-#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
-#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
-
-/* LM80_ISRC_2 Interrupt Status Register 2 */
-/* LM80_IMSK_2 Interrupt Mask Register 2 */
-#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
-#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
-#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
-#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
-#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
-#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
- /* bit 6 and 7 are reserved in LM80_ISRC_2 */
-#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
-#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
-
-/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
-#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
-#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
-#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
-#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
-#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
-#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
-
-/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
-#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
-#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
-#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
-#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
-#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
-#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
-
- /* 0x07 - 0x1f reserved */
-/* LM80_VT0_IN current Voltage 0 value */
-/* LM80_VT1_IN current Voltage 1 value */
-/* LM80_VT2_IN current Voltage 2 value */
-/* LM80_VT3_IN current Voltage 3 value */
-/* LM80_VT4_IN current Voltage 4 value */
-/* LM80_VT5_IN current Voltage 5 value */
-/* LM80_VT6_IN current Voltage 6 value */
-/* LM80_TEMP_IN current temperature value */
-/* LM80_FAN1_IN current Fan 1 count */
-/* LM80_FAN2_IN current Fan 2 count */
-/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
-/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
-/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
-/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
-/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
-/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
-/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
-/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
-/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
-/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
-/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
-/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
-/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
-/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
-/* LM80_THOT_LIM_UP hot temperature limit (high) */
-/* LM80_THOT_LIM_LO hot temperature limit (low) */
-/* LM80_TOS_LIM_UP OS temperature limit (high) */
-/* LM80_TOS_LIM_LO OS temperature limit (low) */
-/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
-/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
- /* 0x3e - 0x3f reserved */
-
-#define LM80_ADDR 0x28 /* LM80 default addr */
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
deleted file mode 100644
index 423ad063d09b..000000000000
--- a/drivers/net/sk98lin/h/skaddr.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/******************************************************************************
- *
- * Name: skaddr.h
- * Project: Gigabit Ethernet Adapters, ADDR-Modul
- * Version: $Revision: 1.29 $
- * Date: $Date: 2003/05/13 16:57:24 $
- * Purpose: Header file for Address Management (MC, UC, Prom).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage multicast addresses and promiscuous mode
- * on GEnesis adapters.
- *
- * Include File Hierarchy:
- *
- * "skdrv1st.h"
- * ...
- * "sktypes.h"
- * "skqueue.h"
- * "skaddr.h"
- * ...
- * "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKADDR_H
-#define __INC_SKADDR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-/* defines ********************************************************************/
-
-#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
-#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
-
-/* ----- Common return values ----- */
-
-#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
-#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
-#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
-
-/* ----- Clear/Add flag bits ----- */
-
-#define SK_ADDR_PERMANENT 1 /* RLMT Address */
-
-/* ----- Additional Clear flag bits ----- */
-
-#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
-
-/* ----- Override flag bits ----- */
-
-#define SK_ADDR_LOGICAL_ADDRESS 0
-#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
-#define SK_ADDR_PHYSICAL_ADDRESS 1
-#define SK_ADDR_CLEAR_LOGICAL 2
-#define SK_ADDR_SET_LOGICAL 4
-
-/* ----- Override return values ----- */
-
-#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS)
-#define SK_ADDR_DUPLICATE_ADDRESS 1
-#define SK_ADDR_MULTICAST_ADDRESS 2
-
-/* ----- Partitioning of excact match table ----- */
-
-#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
-
-#define SK_ADDR_FIRST_MATCH_RLMT 1
-#define SK_ADDR_LAST_MATCH_RLMT 2
-#define SK_ADDR_FIRST_MATCH_DRV 3
-#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1)
-
-/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
-
-#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
-#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
-
-/* ----- Additional SkAddrMcAdd return values ----- */
-
-#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
-#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
-#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
-
-/* Promiscuous mode bits ----- */
-
-#define SK_PROM_MODE_NONE 0 /* Normal receive. */
-#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
-#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
-/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
-
-/* Macros */
-
-#ifdef OLD_STUFF
-#ifndef SK_ADDR_EQUAL
-/*
- * "&" instead of "&&" allows better optimization on IA-64.
- * The replacement is safe here, as all bytes exist.
- */
-#ifndef SK_ADDR_DWORD_COMPARE
-#define SK_ADDR_EQUAL(A1,A2) ( \
- (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
- (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
- (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
- (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
- (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
- (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
-#else /* SK_ADDR_DWORD_COMPARE */
-#define SK_ADDR_EQUAL(A1,A2) ( \
- (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
- (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
-#endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
-#endif /* 0 */
-
-#ifndef SK_ADDR_EQUAL
-#ifndef SK_ADDR_DWORD_COMPARE
-#define SK_ADDR_EQUAL(A1,A2) ( \
- (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
- (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
- (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
- (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
- (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
- (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
-#else /* SK_ADDR_DWORD_COMPARE */
-#define SK_ADDR_EQUAL(A1,A2) ( \
- (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
- *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
- (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
- *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
-#endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
-
-/* typedefs *******************************************************************/
-
-typedef struct s_MacAddr {
- SK_U8 a[SK_MAC_ADDR_LEN];
-} SK_MAC_ADDR;
-
-
-/* SK_FILTER is used to ensure alignment of the filter. */
-typedef union s_InexactFilter {
- SK_U8 Bytes[8];
- SK_U64 Val; /* Dummy entry for alignment only. */
-} SK_FILTER64;
-
-
-typedef struct s_AddrNet SK_ADDR_NET;
-
-
-typedef struct s_AddrPort {
-
-/* ----- Public part (read-only) ----- */
-
- SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
- SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
- int PromMode; /* Promiscuous Mode. */
-
-/* ----- Private part ----- */
-
- SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
- SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
- SK_U8 Align01;
-
- SK_U32 FirstExactMatchRlmt;
- SK_U32 NextExactMatchRlmt;
- SK_U32 FirstExactMatchDrv;
- SK_U32 NextExactMatchDrv;
- SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
- SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
- SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */
- SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */
-} SK_ADDR_PORT;
-
-
-struct s_AddrNet {
-/* ----- Public part (read-only) ----- */
-
- SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
- SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
-
-/* ----- Private part ----- */
-
- SK_U32 ActivePort; /* View of module ADDR. */
- SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
- SK_U8 Align01;
- SK_U16 Align02;
-};
-
-
-typedef struct s_Addr {
-
-/* ----- Public part (read-only) ----- */
-
- SK_ADDR_NET Net[SK_MAX_NETS];
- SK_ADDR_PORT Port[SK_MAX_MACS];
-
-/* ----- Private part ----- */
-} SK_ADDR;
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_KR_PROTO
-
-/* Functions provided by SkAddr */
-
-/* ANSI/C++ compliant function prototypes */
-
-extern int SkAddrInit(
- SK_AC *pAC,
- SK_IOC IoC,
- int Level);
-
-extern int SkAddrMcClear(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 PortNumber,
- int Flags);
-
-extern int SkAddrMcAdd(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 PortNumber,
- SK_MAC_ADDR *pMc,
- int Flags);
-
-extern int SkAddrMcUpdate(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 PortNumber);
-
-extern int SkAddrOverride(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 PortNumber,
- SK_MAC_ADDR SK_FAR *pNewAddr,
- int Flags);
-
-extern int SkAddrPromiscuousChange(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 PortNumber,
- int NewPromMode);
-
-#ifndef SK_SLIM
-extern int SkAddrSwap(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 FromPortNumber,
- SK_U32 ToPortNumber);
-#endif
-
-#else /* defined(SK_KR_PROTO)) */
-
-/* Non-ANSI/C++ compliant function prototypes */
-
-#error KR-style prototypes are not yet provided.
-
-#endif /* defined(SK_KR_PROTO)) */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
deleted file mode 100644
index 6e256bd9a28c..000000000000
--- a/drivers/net/sk98lin/h/skcsum.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/******************************************************************************
- *
- * Name: skcsum.h
- * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
- * Version: $Revision: 1.10 $
- * Date: $Date: 2003/08/20 13:59:57 $
- * Purpose: Store/verify Internet checksum in send/receive packets.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2001 SysKonnect GmbH.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * Public header file for the "GEnesis" common module "CSUM".
- *
- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
- * and is the code name of this SysKonnect project.
- *
- * Compilation Options:
- *
- * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
- * empty module.
- *
- * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
- * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
- * external.
- *
- * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
- * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
- * external.
- *
- * Include File Hierarchy:
- *
- * "h/skcsum.h"
- * "h/sktypes.h"
- * "h/skqueue.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKCSUM_H
-#define __INC_SKCSUM_H
-
-#include "h/sktypes.h"
-#include "h/skqueue.h"
-
-/* defines ********************************************************************/
-
-/*
- * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user
- * overwrite.
- */
-#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */
-#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */
-#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */
-#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */
-
-/* Indices for protocol statistics. */
-#define SKCS_PROTO_STATS_IP 0
-#define SKCS_PROTO_STATS_UDP 1
-#define SKCS_PROTO_STATS_TCP 2
-#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */
-#endif /* !SKCS_OVERWRITE_PROTO */
-
-/*
- * Define the default SKCS_STATUS type and values if no user overwrite.
- *
- * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
- * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
- * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
- * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
- * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
- * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
- * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
- * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
- * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
- * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
- * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
- */
-#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
-#define SKCS_STATUS int /* Define status type. */
-
-#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
-#define SKCS_STATUS_IP_CSUM_ERROR 2
-#define SKCS_STATUS_IP_FRAGMENT 3
-#define SKCS_STATUS_IP_CSUM_OK 4
-#define SKCS_STATUS_TCP_CSUM_ERROR 5
-#define SKCS_STATUS_UDP_CSUM_ERROR 6
-#define SKCS_STATUS_TCP_CSUM_OK 7
-#define SKCS_STATUS_UDP_CSUM_OK 8
-/* needed for Microsoft */
-#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
-#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
-/* UDP checksum may be omitted */
-#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
-#endif /* !SKCS_OVERWRITE_STATUS */
-
-/* Clear protocol statistics event. */
-#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1
-
-/*
- * Add two values in one's complement.
- *
- * Note: One of the two input values may be "longer" than 16-bit, but then the
- * resulting sum may be 17 bits long. In this case, add zero to the result using
- * SKCS_OC_ADD() again.
- *
- * Result = Value1 + Value2
- */
-#define SKCS_OC_ADD(Result, Value1, Value2) { \
- unsigned long Sum; \
- \
- Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \
- /* Add-in any carry. */ \
- (Result) = (Sum & 0xffff) + (Sum >> 16); \
-}
-
-/*
- * Subtract two values in one's complement.
- *
- * Result = Value1 - Value2
- */
-#define SKCS_OC_SUB(Result, Value1, Value2) \
- SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
-
-/* typedefs *******************************************************************/
-
-/*
- * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
- *
- * There is one instance of this structure for each protocol supported.
- */
-typedef struct s_CsProtocolStatistics {
- SK_U64 RxOkCts; /* Receive checksum ok. */
- SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
- SK_U64 RxErrCts; /* Receive checksum error. */
- SK_U64 TxOkCts; /* Transmit checksum ok. */
- SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
-} SKCS_PROTO_STATS;
-
-/*
- * s_Csum - The CSUM module context structure.
- */
-typedef struct s_Csum {
- /* Enabled receive SK_PROTO_XXX bit flags. */
- unsigned ReceiveFlags[SK_MAX_NETS];
-#ifdef TX_CSUM
- unsigned TransmitFlags[SK_MAX_NETS];
-#endif /* TX_CSUM */
-
- /* The protocol statistics structure; one per supported protocol. */
- SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
-} SK_CSUM;
-
-/*
- * SKCS_PACKET_INFO - The packet information structure.
- */
-typedef struct s_CsPacketInfo {
- /* Bit field specifiying the desired/found protocols. */
- unsigned ProtocolFlags;
-
- /* Length of complete IP header, including any option fields. */
- unsigned IpHeaderLength;
-
- /* IP header checksum. */
- unsigned IpHeaderChecksum;
-
- /* TCP/UDP pseudo header checksum. */
- unsigned PseudoHeaderChecksum;
-} SKCS_PACKET_INFO;
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_CS_CALCULATE_CHECKSUM
-extern unsigned SkCsCalculateChecksum(
- void *pData,
- unsigned Length);
-#endif /* SK_CS_CALCULATE_CHECKSUM */
-
-extern int SkCsEvent(
- SK_AC *pAc,
- SK_IOC Ioc,
- SK_U32 Event,
- SK_EVPARA Param);
-
-extern SKCS_STATUS SkCsGetReceiveInfo(
- SK_AC *pAc,
- void *pIpHeader,
- unsigned Checksum1,
- unsigned Checksum2,
- int NetNumber);
-
-extern void SkCsSetReceiveFlags(
- SK_AC *pAc,
- unsigned ReceiveFlags,
- unsigned *pChecksum1Offset,
- unsigned *pChecksum2Offset,
- int NetNumber);
-
-#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
deleted file mode 100644
index 3cba171d74b2..000000000000
--- a/drivers/net/sk98lin/h/skdebug.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/******************************************************************************
- *
- * Name: skdebug.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.14 $
- * Date: $Date: 2003/05/13 17:26:00 $
- * Purpose: SK specific DEBUG support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDEBUG_H
-#define __INC_SKDEBUG_H
-
-#ifdef DEBUG
-#ifndef SK_DBG_MSG
-#define SK_DBG_MSG(pAC,comp,cat,arg) \
- if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
- ((cat) & SK_DBG_CHKCAT(pAC)) ) { \
- SK_DBG_PRINTF arg ; \
- }
-#endif
-#else
-#define SK_DBG_MSG(pAC,comp,lev,arg)
-#endif
-
-/* PLS NOTE:
- * =========
- * Due to any restrictions of kernel printf routines do not use other
- * format identifiers as: %x %d %c %s .
- * Never use any combined format identifiers such as: %lx %ld in your
- * printf - argument (arg) because some OS specific kernel printfs may
- * only support some basic identifiers.
- */
-
-/* Debug modules */
-
-#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
-#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
-#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
-#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
-#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
-#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
-#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
-#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
-#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
-#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
-
-/* Debug events */
-
-#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
-#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
-#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
-#define SK_DBGCAT_TX 0x00000008L /* transmit path */
-#define SK_DBGCAT_RX 0x00000010L /* receive path */
-#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
-#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
-#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
-#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
-
-#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
deleted file mode 100644
index 91b8d4f45904..000000000000
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/******************************************************************************
- *
- * Name: skdrv1st.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.4 $
- * Date: $Date: 2003/11/12 14:28:14 $
- * Purpose: First header file for driver and all other modules
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the first include file of the driver, which includes all
- * neccessary system header files and some of the GEnesis header files.
- * It also defines some basic items.
- *
- * Include File Hierarchy:
- *
- * see skge.c
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDRV1ST_H
-#define __INC_SKDRV1ST_H
-
-typedef struct s_AC SK_AC;
-
-/* Set card versions */
-#define SK_FAR
-
-/* override some default functions with optimized linux functions */
-
-#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2)
-#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4)
-#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8)
-#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2)
-#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4)
-#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8)
-
-#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6))
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <net/checksum.h>
-
-#define SK_CS_CALCULATE_CHECKSUM
-#ifndef CONFIG_X86_64
-#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff)
-#else
-#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff)
-#endif
-
-#include "h/sktypes.h"
-#include "h/skerror.h"
-#include "h/skdebug.h"
-#include "h/lm80.h"
-#include "h/xmac_ii.h"
-
-#ifdef __LITTLE_ENDIAN
-#define SK_LITTLE_ENDIAN
-#else
-#define SK_BIG_ENDIAN
-#endif
-
-#define SK_NET_DEVICE net_device
-
-
-/* we use gethrtime(), return unit: nanoseconds */
-#define SK_TICKS_PER_SEC 100
-
-#define SK_MEM_MAPPED_IO
-
-// #define SK_RLMT_SLOW_LOOKAHEAD
-
-#define SK_MAX_MACS 2
-#define SK_MAX_NETS 2
-
-#define SK_IOC char __iomem *
-
-typedef struct s_DrvRlmtMbuf SK_MBUF;
-
-#define SK_CONST64 INT64_C
-#define SK_CONSTU64 UINT64_C
-
-#define SK_MEMCPY(dest,src,size) memcpy(dest,src,size)
-#define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size)
-#define SK_MEMSET(dest,val,size) memset(dest,val,size)
-#define SK_STRLEN(pStr) strlen((char*)(pStr))
-#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size)
-#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2))
-
-/* macros to access the adapter */
-#define SK_OUT8(b,a,v) writeb((v), ((b)+(a)))
-#define SK_OUT16(b,a,v) writew((v), ((b)+(a)))
-#define SK_OUT32(b,a,v) writel((v), ((b)+(a)))
-#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a)))
-#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a)))
-#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a)))
-
-#define int8_t char
-#define int16_t short
-#define int32_t long
-#define int64_t long long
-#define uint8_t u_char
-#define uint16_t u_short
-#define uint32_t u_long
-#define uint64_t unsigned long long
-#define t_scalar_t int
-#define t_uscalar_t unsigned int
-#define uintptr_t unsigned long
-
-#define __CONCAT__(A,B) A##B
-
-#define INT32_C(a) __CONCAT__(a,L)
-#define INT64_C(a) __CONCAT__(a,LL)
-#define UINT32_C(a) __CONCAT__(a,UL)
-#define UINT64_C(a) __CONCAT__(a,ULL)
-
-#ifdef DEBUG
-#define SK_DBG_PRINTF printk
-#ifndef SK_DEBUG_CHKMOD
-#define SK_DEBUG_CHKMOD 0
-#endif
-#ifndef SK_DEBUG_CHKCAT
-#define SK_DEBUG_CHKCAT 0
-#endif
-/* those come from the makefile */
-#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
-#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
-
-extern void SkDbgPrintf(const char *format,...);
-
-#define SK_DBGMOD_DRV 0x00010000
-
-/**** possible driver debug categories ********************************/
-#define SK_DBGCAT_DRV_ENTRY 0x00010000
-#define SK_DBGCAT_DRV_SAP 0x00020000
-#define SK_DBGCAT_DRV_MCA 0x00040000
-#define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000
-#define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000
-#define SK_DBGCAT_DRV_PROGRESS 0x00200000
-#define SK_DBGCAT_DRV_MSG 0x00400000
-#define SK_DBGCAT_DRV_PROM 0x00800000
-#define SK_DBGCAT_DRV_TX_FRAME 0x01000000
-#define SK_DBGCAT_DRV_ERROR 0x02000000
-#define SK_DBGCAT_DRV_INT_SRC 0x04000000
-#define SK_DBGCAT_DRV_EVENT 0x08000000
-
-#endif
-
-#define SK_ERR_LOG SkErrorLog
-
-extern void SkErrorLog(SK_AC*, int, int, char*);
-
-#endif
-
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
deleted file mode 100644
index 3fa67171e832..000000000000
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/******************************************************************************
- *
- * Name: skdrv2nd.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.10 $
- * Date: $Date: 2003/12/11 16:04:45 $
- * Purpose: Second header file for driver and all other modules
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the second include file of the driver, which includes all other
- * neccessary files and defines all structures and constants used by the
- * driver and the common modules.
- *
- * Include File Hierarchy:
- *
- * see skge.c
- *
- ******************************************************************************/
-
-#ifndef __INC_SKDRV2ND_H
-#define __INC_SKDRV2ND_H
-
-#include "h/skqueue.h"
-#include "h/skgehwt.h"
-#include "h/sktimer.h"
-#include "h/ski2c.h"
-#include "h/skgepnmi.h"
-#include "h/skvpd.h"
-#include "h/skgehw.h"
-#include "h/skgeinit.h"
-#include "h/skaddr.h"
-#include "h/skgesirq.h"
-#include "h/skcsum.h"
-#include "h/skrlmt.h"
-#include "h/skgedrv.h"
-
-
-extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
-extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
-extern SK_U64 SkOsGetTime(SK_AC*);
-extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
-extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
-extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
-extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
-extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
-
-#ifdef SK_DIAG_SUPPORT
-extern int SkDrvEnterDiagMode(SK_AC *pAc);
-extern int SkDrvLeaveDiagMode(SK_AC *pAc);
-#endif
-
-struct s_DrvRlmtMbuf {
- SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */
- SK_U8 *pData; /* Data buffer (virtually contig.). */
- unsigned Size; /* Data buffer size. */
- unsigned Length; /* Length of packet (<= Size). */
- SK_U32 PortIdx; /* Receiving/transmitting port. */
-#ifdef SK_RLMT_MBUF_PRIVATE
- SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */
-#endif /* SK_RLMT_MBUF_PRIVATE */
- struct sk_buff *pOs; /* Pointer to message block */
-};
-
-
-/*
- * Time macros
- */
-#if SK_TICKS_PER_SEC == 100
-#define SK_PNMI_HUNDREDS_SEC(t) (t)
-#else
-#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \
- (SK_TICKS_PER_SEC))
-#endif
-
-/*
- * New SkOsGetTime
- */
-#define SkOsGetTimeCurrent(pAC, pUsec) {\
- struct timeval t;\
- do_gettimeofday(&t);\
- *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
-}
-
-
-/*
- * ioctl definitions
- */
-#define SK_IOCTL_BASE (SIOCDEVPRIVATE)
-#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0)
-#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1)
-#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2)
-#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3)
-#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4)
-
-typedef struct s_IOCTL SK_GE_IOCTL;
-
-struct s_IOCTL {
- char __user * pData;
- unsigned int Len;
-};
-
-
-/*
- * define sizes of descriptor rings in bytes
- */
-
-#define TX_RING_SIZE (8*1024)
-#define RX_RING_SIZE (24*1024)
-
-/*
- * Buffer size for ethernet packets
- */
-#define ETH_BUF_SIZE 1540
-#define ETH_MAX_MTU 1514
-#define ETH_MIN_MTU 60
-#define ETH_MULTICAST_BIT 0x01
-#define SK_JUMBO_MTU 9000
-
-/*
- * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
- */
-#define TX_PRIO_LOW 0
-#define TX_PRIO_HIGH 1
-
-/*
- * alignment of rx/tx descriptors
- */
-#define DESCR_ALIGN 64
-
-/*
- * definitions for pnmi. TODO
- */
-#define SK_DRIVER_RESET(pAC, IoC) 0
-#define SK_DRIVER_SENDEVENT(pAC, IoC) 0
-#define SK_DRIVER_SELFTEST(pAC, IoC) 0
-/* For get mtu you must add an own function */
-#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0
-#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
-#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0
-
-/*
-** Interim definition of SK_DRV_TIMER placed in this file until
-** common modules have been finalized
-*/
-#define SK_DRV_TIMER 11
-#define SK_DRV_MODERATION_TIMER 1
-#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */
-#define SK_DRV_RX_CLEANUP_TIMER 2
-#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */
-
-/*
-** Definitions regarding transmitting frames
-** any calculating any checksum.
-*/
-#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
-#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6
-#define C_LEN_ETHERMAC_HEADER_LENTYPE 2
-#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
- (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \
- (C_LEN_ETHERMAC_HEADER_LENTYPE) )
-
-#define C_LEN_ETHERMTU_MINSIZE 46
-#define C_LEN_ETHERMTU_MAXSIZE_STD 1500
-#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000
-
-#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \
- (C_LEN_ETHERMTU_MINSIZE) )
-
-#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER
-#define C_OFFSET_IPHEADER_IPPROTO 9
-#define C_OFFSET_TCPHEADER_TCPCS 16
-#define C_OFFSET_UDPHEADER_UDPCS 6
-
-#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \
- (C_OFFSET_IPHEADER_IPPROTO) )
-
-#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */
-#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */
-
-/* TX and RX descriptors *****************************************************/
-
-typedef struct s_RxD RXD; /* the receive descriptor */
-
-struct s_RxD {
- volatile SK_U32 RBControl; /* Receive Buffer Control */
- SK_U32 VNextRxd; /* Next receive descriptor,low dword */
- SK_U32 VDataLow; /* Receive buffer Addr, low dword */
- SK_U32 VDataHigh; /* Receive buffer Addr, high dword */
- SK_U32 FrameStat; /* Receive Frame Status word */
- SK_U32 TimeStamp; /* Time stamp from XMAC */
- SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */
- SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */
- RXD *pNextRxd; /* Pointer to next Rxd */
- struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
-};
-
-typedef struct s_TxD TXD; /* the transmit descriptor */
-
-struct s_TxD {
- volatile SK_U32 TBControl; /* Transmit Buffer Control */
- SK_U32 VNextTxd; /* Next transmit descriptor,low dword */
- SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */
- SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */
- SK_U32 FrameStat; /* Transmit Frame Status Word */
- SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */
- SK_U16 TcpSumSt; /* TCP Sum Start */
- SK_U16 TcpSumWr; /* TCP Sum Write */
- SK_U32 TcpReserved; /* not used */
- TXD *pNextTxd; /* Pointer to next Txd */
- struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
-};
-
-/* Used interrupt bits in the interrupts source register *********************/
-
-#define DRIVER_IRQS ((IS_IRQ_SW) | \
- (IS_R1_F) |(IS_R2_F) | \
- (IS_XS1_F) |(IS_XA1_F) | \
- (IS_XS2_F) |(IS_XA2_F))
-
-#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \
- (IS_EXT_REG) |(IS_TIMINT) | \
- (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \
- (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \
- (IS_MAC1) |(IS_LNK_SYNC_M1)| \
- (IS_MAC2) |(IS_LNK_SYNC_M2)| \
- (IS_R1_C) |(IS_R2_C) | \
- (IS_XS1_C) |(IS_XA1_C) | \
- (IS_XS2_C) |(IS_XA2_C))
-
-#define IRQ_MASK ((IS_IRQ_SW) | \
- (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \
- (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \
- (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \
- (IS_HW_ERR) |(IS_I2C_READY)| \
- (IS_EXT_REG) |(IS_TIMINT) | \
- (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
- (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
- (IS_MAC1) |(IS_MAC2) | \
- (IS_R1_C) |(IS_R2_C) | \
- (IS_XS1_C) |(IS_XA1_C) | \
- (IS_XS2_C) |(IS_XA2_C))
-
-#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */
-
-typedef struct s_DevNet DEV_NET;
-
-struct s_DevNet {
- int PortNr;
- int NetNr;
- SK_AC *pAC;
-};
-
-typedef struct s_TxPort TX_PORT;
-
-struct s_TxPort {
- /* the transmit descriptor rings */
- caddr_t pTxDescrRing; /* descriptor area memory */
- SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */
- TXD *pTxdRingHead; /* Head of Tx rings */
- TXD *pTxdRingTail; /* Tail of Tx rings */
- TXD *pTxdRingPrev; /* descriptor sent previously */
- int TxdRingFree; /* # of free entrys */
- spinlock_t TxDesRingLock; /* serialize descriptor accesses */
- SK_IOC HwAddr; /* bmu registers address */
- int PortIndex; /* index number of port (0 or 1) */
-};
-
-typedef struct s_RxPort RX_PORT;
-
-struct s_RxPort {
- /* the receive descriptor rings */
- caddr_t pRxDescrRing; /* descriptor area memory */
- SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */
- RXD *pRxdRingHead; /* Head of Rx rings */
- RXD *pRxdRingTail; /* Tail of Rx rings */
- RXD *pRxdRingPrev; /* descriptor given to BMU previously */
- int RxdRingFree; /* # of free entrys */
- int RxCsum; /* use receive checksum hardware */
- spinlock_t RxDesRingLock; /* serialize descriptor accesses */
- int RxFillLimit; /* limit for buffers in ring */
- SK_IOC HwAddr; /* bmu registers address */
- int PortIndex; /* index number of port (0 or 1) */
-};
-
-/* Definitions needed for interrupt moderation *******************************/
-
-#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F))
-#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F))
-#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
-#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F))
-#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS)
-#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
-#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY))
-#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY))
-#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX))
-
-#define C_INT_MOD_NONE 1
-#define C_INT_MOD_STATIC 2
-#define C_INT_MOD_DYNAMIC 4
-
-#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */
-#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */
-
-#define C_INTS_PER_SEC_DEFAULT 2000
-#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */
-#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */
-#define C_INT_MOD_IPS_LOWER_RANGE 30
-#define C_INT_MOD_IPS_UPPER_RANGE 40000
-
-
-typedef struct s_DynIrqModInfo DIM_INFO;
-struct s_DynIrqModInfo {
- unsigned long PrevTimeVal;
- unsigned int PrevSysLoad;
- unsigned int PrevUsedTime;
- unsigned int PrevTotalTime;
- int PrevUsedDescrRatio;
- int NbrProcessedDescr;
- SK_U64 PrevPort0RxIntrCts;
- SK_U64 PrevPort1RxIntrCts;
- SK_U64 PrevPort0TxIntrCts;
- SK_U64 PrevPort1TxIntrCts;
- SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */
-
- int MaxModIntsPerSec; /* Moderation Threshold */
- int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */
- int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */
-
- long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */
- SK_BOOL DisplayStats; /* Stats yes/no */
- SK_BOOL AutoSizing; /* Resize DIM-timer on/off */
- int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */
-
- SK_TIMER ModTimer; /* just some timer */
-};
-
-typedef struct s_PerStrm PER_STRM;
-
-#define SK_ALLOC_IRQ 0x00000001
-
-#ifdef SK_DIAG_SUPPORT
-#define DIAG_ACTIVE 1
-#define DIAG_NOTACTIVE 0
-#endif
-
-/****************************************************************************
- * Per board structure / Adapter Context structure:
- * Allocated within attach(9e) and freed within detach(9e).
- * Contains all 'per device' necessary handles, flags, locks etc.:
- */
-struct s_AC {
- SK_GEINIT GIni; /* GE init struct */
- SK_PNMI Pnmi; /* PNMI data struct */
- SK_VPD vpd; /* vpd data struct */
- SK_QUEUE Event; /* Event queue */
- SK_HWT Hwt; /* Hardware Timer control struct */
- SK_TIMCTRL Tim; /* Software Timer control struct */
- SK_I2C I2c; /* I2C relevant data structure */
- SK_ADDR Addr; /* for Address module */
- SK_CSUM Csum; /* for checksum module */
- SK_RLMT Rlmt; /* for rlmt module */
- spinlock_t SlowPathLock; /* Normal IRQ lock */
- struct timer_list BlinkTimer; /* for LED blinking */
- int LedsOn;
- SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
- int RlmtMode; /* link check mode to set */
- int RlmtNets; /* Number of nets */
-
- SK_IOC IoBase; /* register set of adapter */
- int BoardLevel; /* level of active hw init (0-2) */
-
- SK_U32 AllocFlag; /* flag allocation of resources */
- struct pci_dev *PciDev; /* for access to pci config space */
- struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
-
- int RxBufSize; /* length of receive buffers */
- struct net_device_stats stats; /* linux 'netstat -i' statistics */
- int Index; /* internal board index number */
-
- /* adapter RAM sizes for queues of active port */
- int RxQueueSize; /* memory used for receive queue */
- int TxSQueueSize; /* memory used for sync. tx queue */
- int TxAQueueSize; /* memory used for async. tx queue */
-
- int PromiscCount; /* promiscuous mode counter */
- int AllMultiCount; /* allmulticast mode counter */
- int MulticCount; /* number of different MC */
- /* addresses for this board */
- /* (may be more than HW can)*/
-
- int HWRevision; /* Hardware revision */
- int ActivePort; /* the active XMAC port */
- int MaxPorts; /* number of activated ports */
- int TxDescrPerRing; /* # of descriptors per tx ring */
- int RxDescrPerRing; /* # of descriptors per rx ring */
-
- caddr_t pDescrMem; /* Pointer to the descriptor area */
- dma_addr_t pDescrMemDMA; /* PCI DMA address of area */
-
- /* the port structures with descriptor rings */
- TX_PORT TxPort[SK_MAX_MACS][2];
- RX_PORT RxPort[SK_MAX_MACS];
-
- SK_BOOL CheckQueue; /* check event queue soon */
- SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */
- DIM_INFO DynIrqModInfo; /* all data related to DIM */
-
- /* Only for tests */
- int PortDown;
- int ChipsetType; /* Chipset family type
- * 0 == Genesis family support
- * 1 == Yukon family support
- */
-#ifdef SK_DIAG_SUPPORT
- SK_U32 DiagModeActive; /* is diag active? */
- SK_BOOL DiagFlowCtrl; /* for control purposes */
- SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */
- SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while
- * DIAG is busy with NIC
- */
-#endif
-
-};
-
-
-#endif /* __INC_SKDRV2ND_H */
-
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
deleted file mode 100644
index da062f766238..000000000000
--- a/drivers/net/sk98lin/h/skerror.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/******************************************************************************
- *
- * Name: skerror.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.7 $
- * Date: $Date: 2003/05/13 17:25:13 $
- * Purpose: SK specific Error log support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _INC_SKERROR_H_
-#define _INC_SKERROR_H_
-
-/*
- * Define Error Classes
- */
-#define SK_ERRCL_OTHER (0) /* Other error */
-#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */
-#define SK_ERRCL_INIT (1L<<1) /* Initialization error */
-#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */
-#define SK_ERRCL_SW (1L<<3) /* Internal Software error */
-#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */
-#define SK_ERRCL_COMM (1L<<5) /* Communication error */
-
-
-/*
- * Define Error Code Bases
- */
-#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */
-#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */
-#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */
-#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */
-#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */
-#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */
-#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */
-#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */
-#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */
-#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */
-#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */
-
-#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
deleted file mode 100644
index 44fd4c3de818..000000000000
--- a/drivers/net/sk98lin/h/skgedrv.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/******************************************************************************
- *
- * Name: skgedrv.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.10 $
- * Date: $Date: 2003/07/04 12:25:01 $
- * Purpose: Interface with the driver
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEDRV_H_
-#define __INC_SKGEDRV_H_
-
-/* defines ********************************************************************/
-
-/*
- * Define the driver events.
- * Usually the events are defined by the destination module.
- * In case of the driver we put the definition of the events here.
- */
-#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */
-#define SK_DRV_NET_UP 2 /* The net is operational */
-#define SK_DRV_NET_DOWN 3 /* The net is down */
-#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */
-#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */
-#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */
-#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */
-#define SK_DRV_PORT_FAIL 8 /* One port fails */
-#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */
-#define SK_DRV_POWER_DOWN 10 /* Power down mode */
-#define SK_DRV_TIMER 11 /* Timer for free use */
-#ifdef SK_NO_RLMT
-#define SK_DRV_LINK_UP 12 /* Link Up event for driver */
-#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */
-#endif
-#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */
-#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
deleted file mode 100644
index f6282b7956db..000000000000
--- a/drivers/net/sk98lin/h/skgehw.h
+++ /dev/null
@@ -1,2126 +0,0 @@
-/******************************************************************************
- *
- * Name: skgehw.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.56 $
- * Date: $Date: 2003/09/23 09:01:00 $
- * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEHW_H
-#define __INC_SKGEHW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-#define BIT_31 (1UL << 31)
-#define BIT_30 (1L << 30)
-#define BIT_29 (1L << 29)
-#define BIT_28 (1L << 28)
-#define BIT_27 (1L << 27)
-#define BIT_26 (1L << 26)
-#define BIT_25 (1L << 25)
-#define BIT_24 (1L << 24)
-#define BIT_23 (1L << 23)
-#define BIT_22 (1L << 22)
-#define BIT_21 (1L << 21)
-#define BIT_20 (1L << 20)
-#define BIT_19 (1L << 19)
-#define BIT_18 (1L << 18)
-#define BIT_17 (1L << 17)
-#define BIT_16 (1L << 16)
-#define BIT_15 (1L << 15)
-#define BIT_14 (1L << 14)
-#define BIT_13 (1L << 13)
-#define BIT_12 (1L << 12)
-#define BIT_11 (1L << 11)
-#define BIT_10 (1L << 10)
-#define BIT_9 (1L << 9)
-#define BIT_8 (1L << 8)
-#define BIT_7 (1L << 7)
-#define BIT_6 (1L << 6)
-#define BIT_5 (1L << 5)
-#define BIT_4 (1L << 4)
-#define BIT_3 (1L << 3)
-#define BIT_2 (1L << 2)
-#define BIT_1 (1L << 1)
-#define BIT_0 1L
-
-#define BIT_15S (1U << 15)
-#define BIT_14S (1 << 14)
-#define BIT_13S (1 << 13)
-#define BIT_12S (1 << 12)
-#define BIT_11S (1 << 11)
-#define BIT_10S (1 << 10)
-#define BIT_9S (1 << 9)
-#define BIT_8S (1 << 8)
-#define BIT_7S (1 << 7)
-#define BIT_6S (1 << 6)
-#define BIT_5S (1 << 5)
-#define BIT_4S (1 << 4)
-#define BIT_3S (1 << 3)
-#define BIT_2S (1 << 2)
-#define BIT_1S (1 << 1)
-#define BIT_0S 1
-
-#define SHIFT31(x) ((x) << 31)
-#define SHIFT30(x) ((x) << 30)
-#define SHIFT29(x) ((x) << 29)
-#define SHIFT28(x) ((x) << 28)
-#define SHIFT27(x) ((x) << 27)
-#define SHIFT26(x) ((x) << 26)
-#define SHIFT25(x) ((x) << 25)
-#define SHIFT24(x) ((x) << 24)
-#define SHIFT23(x) ((x) << 23)
-#define SHIFT22(x) ((x) << 22)
-#define SHIFT21(x) ((x) << 21)
-#define SHIFT20(x) ((x) << 20)
-#define SHIFT19(x) ((x) << 19)
-#define SHIFT18(x) ((x) << 18)
-#define SHIFT17(x) ((x) << 17)
-#define SHIFT16(x) ((x) << 16)
-#define SHIFT15(x) ((x) << 15)
-#define SHIFT14(x) ((x) << 14)
-#define SHIFT13(x) ((x) << 13)
-#define SHIFT12(x) ((x) << 12)
-#define SHIFT11(x) ((x) << 11)
-#define SHIFT10(x) ((x) << 10)
-#define SHIFT9(x) ((x) << 9)
-#define SHIFT8(x) ((x) << 8)
-#define SHIFT7(x) ((x) << 7)
-#define SHIFT6(x) ((x) << 6)
-#define SHIFT5(x) ((x) << 5)
-#define SHIFT4(x) ((x) << 4)
-#define SHIFT3(x) ((x) << 3)
-#define SHIFT2(x) ((x) << 2)
-#define SHIFT1(x) ((x) << 1)
-#define SHIFT0(x) ((x) << 0)
-
-/*
- * Configuration Space header
- * Since this module is used for different OS', those may be
- * duplicate on some of them (e.g. Linux). But to keep the
- * common source, we have to live with this...
- */
-#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */
-#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */
-#define PCI_COMMAND 0x04 /* 16 bit Command */
-#define PCI_STATUS 0x06 /* 16 bit Status */
-#define PCI_REV_ID 0x08 /* 8 bit Revision ID */
-#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */
-#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */
-#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */
-#define PCI_HEADER_T 0x0e /* 8 bit Header Type */
-#define PCI_BIST 0x0f /* 8 bit Built-in selftest */
-#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */
-#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */
- /* Byte 0x18..0x2b: reserved */
-#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */
-#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */
-#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */
-#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */
- /* Byte 0x35..0x3b: reserved */
-#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */
-#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */
-#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */
-#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */
- /* Device Dependent Region */
-#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */
-#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */
- /* Power Management Region */
-#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */
-#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */
-#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */
-#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */
- /* Byte 0x4e: reserved */
-#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */
- /* VPD Region */
-#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */
-#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */
-#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */
-#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */
- /* Byte 0x58..0x59: reserved */
-#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */
- /* Byte 0x5c..0xff: reserved */
-
-/*
- * I2C Address (PCI Config)
- *
- * Note: The temperature and voltage sensors are relocated on a different
- * I2C bus.
- */
-#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */
-
-/*
- * Define Bits and Values of the registers
- */
-/* PCI_COMMAND 16 bit Command */
- /* Bit 15..11: reserved */
-#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */
-#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */
-#define PCI_SERREN BIT_8S /* SERR enable */
-#define PCI_ADSTEP BIT_7S /* Address Stepping */
-#define PCI_PERREN BIT_6S /* Parity Report Response enable */
-#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */
-#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */
-#define PCI_SCYCEN BIT_3S /* Special Cycle enable */
-#define PCI_BMEN BIT_2S /* Bus Master enable */
-#define PCI_MEMEN BIT_1S /* Memory Space Access enable */
-#define PCI_IOEN BIT_0S /* I/O Space Access enable */
-
-#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
- PCI_BMEN | PCI_MEMEN | PCI_IOEN)
-
-/* PCI_STATUS 16 bit Status */
-#define PCI_PERR BIT_15S /* Parity Error */
-#define PCI_SERR BIT_14S /* Signaled SERR */
-#define PCI_RMABORT BIT_13S /* Received Master Abort */
-#define PCI_RTABORT BIT_12S /* Received Target Abort */
- /* Bit 11: reserved */
-#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */
-#define PCI_DEV_FAST (0<<9) /* fast */
-#define PCI_DEV_MEDIUM (1<<9) /* medium */
-#define PCI_DEV_SLOW (2<<9) /* slow */
-#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */
-#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */
-#define PCI_UDF BIT_6S /* User Defined Features */
-#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */
-#define PCI_NEWCAP BIT_4S /* New cap. list implemented */
-#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */
- /* Bit 2.. 0: reserved */
-
-#define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
- PCI_DATAPERR)
-
-/* PCI_CLASS_CODE 24 bit Class Code */
-/* Byte 2: Base Class (02) */
-/* Byte 1: SubClass (00) */
-/* Byte 0: Programming Interface (00) */
-
-/* PCI_CACHE_LSZ 8 bit Cache Line Size */
-/* Possible values: 0,2,4,8,16,32,64,128 */
-
-/* PCI_HEADER_T 8 bit Header Type */
-#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */
-#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */
-
-/* PCI_BIST 8 bit Built-in selftest */
-/* Built-in Self test not supported (optional) */
-
-/* PCI_BASE_1ST 32 bit 1st Base address */
-#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */
-#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */
-#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */
-#define PCI_PREFEN BIT_3 /* Prefetchable */
-#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */
-#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */
-#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */
-#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */
-#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */
-
-/* PCI_BASE_2ND 32 bit 2nd Base address */
-#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */
-#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */
- /* Bit 1: reserved */
-#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */
-
-/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */
-#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */
-#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */
-#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */
- /* Bit 10.. 1: reserved */
-#define PCI_ROMEN BIT_0 /* Address Decode enable */
-
-/* Device Dependent Region */
-/* PCI_OUR_REG_1 32 bit Our Register 1 */
- /* Bit 31..29: reserved */
-#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */
-#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */
-#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */
-#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
-#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */
-#define PCI_EN_IO BIT_23 /* Mapping to I/O space */
-#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */
- /* 1 = Map Flash to memory */
- /* 0 = Disable addr. dec */
-#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */
-#define PCI_PAGE_16 (0L<<20) /* 16 k pages */
-#define PCI_PAGE_32K (1L<<20) /* 32 k pages */
-#define PCI_PAGE_64K (2L<<20) /* 64 k pages */
-#define PCI_PAGE_128K (3L<<20) /* 128 k pages */
- /* Bit 19: reserved */
-#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */
-#define PCI_NOTAR BIT_15 /* No turnaround cycle */
-#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */
-#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */
-#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */
-#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */
-#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */
-#define PCI_BURST_DIS BIT_9 /* Burst Disable */
-#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */
-#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */
-#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */
-
-
-/* PCI_OUR_REG_2 32 bit Our Register 2 */
-#define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */
-#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */
-#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */
- /* Bit 13..12: reserved */
-#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */
-#define PCI_PATCH_DIR_3 BIT_11
-#define PCI_PATCH_DIR_2 BIT_10
-#define PCI_PATCH_DIR_1 BIT_9
-#define PCI_PATCH_DIR_0 BIT_8
-#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */
-#define PCI_EXT_PATCH_3 BIT_7
-#define PCI_EXT_PATCH_2 BIT_6
-#define PCI_EXT_PATCH_1 BIT_5
-#define PCI_EXT_PATCH_0 BIT_4
-#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */
-#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */
- /* Bit 1: reserved */
-#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */
-
-
-/* Power Management Region */
-/* PCI_PM_CAP_REG 16 bit Power Management Capabilities */
-#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */
-#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */
-#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */
-#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */
-#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */
-#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */
-#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */
-#define PCI_PM_D1_SUP BIT_9S /* D1 Support */
- /* Bit 8.. 6: reserved */
-#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */
-#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */
-#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */
-#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */
-
-/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */
-#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */
-#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */
-#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */
-#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */
- /* Bit 7.. 2: reserved */
-#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */
-
-#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */
-#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */
-#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */
-#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */
-
-/* VPD Region */
-/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
-#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */
-#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */
-
-/* Control Register File (Address Map) */
-
-/*
- * Bank 0
- */
-#define B0_RAP 0x0000 /* 8 bit Register Address Port */
- /* 0x0001 - 0x0003: reserved */
-#define B0_CTST 0x0004 /* 16 bit Control/Status register */
-#define B0_LED 0x0006 /* 8 Bit LED register */
-#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */
-#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */
-#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */
-#define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */
-#define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */
-#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */
- /* 0x001c: reserved */
-
-/* B0 XMAC 1 registers (GENESIS only) */
-#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/
- /* 0x0022 - 0x0027: reserved */
-#define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */
- /* 0x002a - 0x002f: reserved */
-#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */
- /* 0x0032 - 0x0033: reserved */
-#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */
- /* 0x0036 - 0x003f: reserved */
-
-/* B0 XMAC 2 registers (GENESIS only) */
-#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/
- /* 0x0042 - 0x0047: reserved */
-#define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */
- /* 0x004a - 0x004f: reserved */
-#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */
- /* 0x0052 - 0x0053: reserved */
-#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */
- /* 0x0056 - 0x005f: reserved */
-
-/* BMU Control Status Registers */
-#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */
-#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */
-#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
-#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/
-#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
-#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/
- /* 0x0078 - 0x007f: reserved */
-
-/*
- * Bank 1
- * - completely empty (this is the RAP Block window)
- * Note: if RAP = 1 this page is reserved
- */
-
-/*
- * Bank 2
- */
-/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
-#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */
- /* 0x0106 - 0x0107: reserved */
-#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */
- /* 0x010e - 0x010f: reserved */
-#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */
- /* 0x0116 - 0x0117: reserved */
-#define B2_CONN_TYP 0x0118 /* 8 bit Connector type */
-#define B2_PMD_TYP 0x0119 /* 8 bit PMD type */
-#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */
-#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */
- /* Eprom registers are currently of no use */
-#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */
-#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */
-#define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */
-#define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */
-#define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */
-#define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */
- /* 0x0125 - 0x0127: reserved */
-#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */
-#define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */
- /* 0x012a - 0x012f: reserved */
-#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */
-#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */
-#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */
-#define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */
- /* 0x013a - 0x013f: reserved */
-#define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/
-#define B2_IRQM_VAL 0x0144 /* 32 bit IRQ Moderation Timer Value */
-#define B2_IRQM_CTRL 0x0148 /* 8 bit IRQ Moderation Timer Control */
-#define B2_IRQM_TEST 0x0149 /* 8 bit IRQ Moderation Timer Test */
-#define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */
-#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */
- /* 0x0154 - 0x0157: reserved */
-#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */
-#define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */
- /* 0x015a - 0x015b: reserved */
-#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */
-#define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */
-#define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */
-#define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */
-#define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */
-
-/* Blink Source Counter (GENESIS only) */
-#define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */
-#define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */
-#define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */
-#define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */
-#define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */
- /* 0x017c - 0x017f: reserved */
-
-/*
- * Bank 3
- */
-/* RAM Random Registers */
-#define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */
-#define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */
-#define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */
- /* 0x018c - 0x018f: reserved */
-
-/* RAM Interface Registers */
-/*
- * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
- * not usable in SW. Please notice these are NOT real timeouts, these are
- * the number of qWords transferred continuously.
- */
-#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */
-#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */
-#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */
-#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */
-#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */
-#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */
-#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */
-#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */
-#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */
-#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */
-#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/
-#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/
-#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */
- /* 0x019d - 0x019f: reserved */
-#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */
-#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */
- /* 0x01a3 - 0x01af: reserved */
-
-/* MAC Arbiter Registers (GENESIS only) */
-/* these are the no. of qWord transferred continuously and NOT real timeouts */
-#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */
-#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */
-#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */
-#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */
-#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */
-#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */
-#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */
-#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */
-#define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */
-#define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */
- /* 0x01bc - 0x01bf: reserved */
-#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */
-#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */
-#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */
-#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */
-#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */
-#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */
-#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */
-#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */
-#define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */
-#define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */
- /* 0x01cc - 0x01cf: reserved */
-
-/* Packet Arbiter Registers (GENESIS only) */
-/* these are real timeouts */
-#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */
- /* 0x01d2 - 0x01d3: reserved */
-#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */
- /* 0x01d6 - 0x01d7: reserved */
-#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */
- /* 0x01da - 0x01db: reserved */
-#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */
- /* 0x01de - 0x01df: reserved */
-#define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */
- /* 0x01e2 - 0x01e3: reserved */
-#define B3_PA_TOVAL_RX2 0x01e4 /* 16 bit Timeout Val Rx Path MAC 2 */
- /* 0x01e6 - 0x01e7: reserved */
-#define B3_PA_TOVAL_TX1 0x01e8 /* 16 bit Timeout Val Tx Path MAC 1 */
- /* 0x01ea - 0x01eb: reserved */
-#define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */
- /* 0x01ee - 0x01ef: reserved */
-#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */
-#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */
- /* 0x01f4 - 0x01ff: reserved */
-
-/*
- * Bank 4 - 5
- */
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-#define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/
-#define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */
-#define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */
-#define TXA_LIM_VAL 0x020c /* 32 bit Tx Arb Limit Counter Value */
-#define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */
-#define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */
-#define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */
- /* 0x0213 - 0x027f: reserved */
- /* 0x0280 - 0x0292: MAC 2 */
- /* 0x0213 - 0x027f: reserved */
-
-/*
- * Bank 6
- */
-/* External registers (GENESIS only) */
-#define B6_EXT_REG 0x0300
-
-/*
- * Bank 7
- */
-/* This is a copy of the Configuration register file (lower half) */
-#define B7_CFG_SPC 0x0380
-
-/*
- * Bank 8 - 15
- */
-/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
-#define B8_Q_REGS 0x0400
-
-/* Queue Register Offsets, use Q_ADDR() to access */
-#define Q_D 0x00 /* 8*32 bit Current Descriptor */
-#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */
-#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */
-#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */
-#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */
-#define Q_BC 0x30 /* 32 bit Current Byte Counter */
-#define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */
-#define Q_F 0x38 /* 32 bit Flag Register */
-#define Q_T1 0x3c /* 32 bit Test Register 1 */
-#define Q_T1_TR 0x3c /* 8 bit Test Register 1 Transfer SM */
-#define Q_T1_WR 0x3d /* 8 bit Test Register 1 Write Descriptor SM */
-#define Q_T1_RD 0x3e /* 8 bit Test Register 1 Read Descriptor SM */
-#define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */
-#define Q_T2 0x40 /* 32 bit Test Register 2 */
-#define Q_T3 0x44 /* 32 bit Test Register 3 */
- /* 0x48 - 0x7f: reserved */
-
-/*
- * Bank 16 - 23
- */
-/* RAM Buffer Registers */
-#define B16_RAM_REGS 0x0800
-
-/* RAM Buffer Register Offsets, use RB_ADDR() to access */
-#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */
-#define RB_END 0x04 /* 32 bit RAM Buffer End Address */
-#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */
-#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */
-#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */
-#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */
-#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */
-#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */
- /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
-#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */
-#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */
-#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */
-#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */
-#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */
- /* 0x2c - 0x7f: reserved */
-
-/*
- * Bank 24
- */
-/*
- * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
- * use MR_ADDR() to access
- */
-#define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */
-#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */
- /* 0x0c08 - 0x0c0b: reserved */
-#define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */
-#define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */
-#define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */
-#define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/
-#define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */
-#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */
-#define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/
-#define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */
-#define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */
- /* 0x0c1f: reserved */
-#define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */
-#define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */
-#define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */
-#define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */
- /* 0x0c2a - 0x0c2f: reserved */
-#define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */
-#define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */
-#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */
-#define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */
- /* 0x0c3a - 0x0c3b: reserved */
-#define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */
- /* 0x0c3d - 0x0c3f: reserved */
-
-/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
-#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */
-#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */
-#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */
-#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */
-#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */
- /* 0x0c54 - 0x0c5f: reserved */
-#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */
- /* 0x0c64 - 0x0c67: reserved */
-#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */
- /* 0x0c6c - 0x0c6f: reserved */
-#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */
- /* 0x0c74 - 0x0c77: reserved */
-#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */
- /* 0x0c7c - 0x0c7f: reserved */
-
-/*
- * Bank 25
- */
- /* 0x0c80 - 0x0cbf: MAC 2 */
- /* 0x0cc0 - 0x0cff: reserved */
-
-/*
- * Bank 26
- */
-/*
- * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
- * use MR_ADDR() to access
- */
-#define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */
-#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */
-#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */
-#define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */
-#define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */
-#define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */
-#define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */
-#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */
- /* 0x0c1b: reserved */
-#define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */
-#define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */
-#define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */
- /* 0x0d1f: reserved */
-#define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */
-#define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */
-#define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */
-#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */
- /* 0x0d2a - 0x0d3f: reserved */
-
-/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
-#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */
-#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
-#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */
- /* 0x0d4c - 0x0d5f: reserved */
-#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */
-#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */
-#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */
- /* 0x0d6c - 0x0d6f: reserved */
-#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */
-#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */
-#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */
- /* 0x0d7c - 0x0d7f: reserved */
-
-/*
- * Bank 27
- */
- /* 0x0d80 - 0x0dbf: MAC 2 */
- /* 0x0daa - 0x0dff: reserved */
-
-/*
- * Bank 28
- */
-/* Descriptor Poll Timer Registers */
-#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */
-#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */
-#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */
- /* 0x0e09: reserved */
-#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */
- /* 0x0e0b: reserved */
-
-/* Time Stamp Timer Registers (YUKON only) */
- /* 0x0e10: reserved */
-#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */
-#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */
- /* 0x0e19: reserved */
-#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */
- /* 0x0e1b - 0x0e7f: reserved */
-
-/*
- * Bank 29
- */
- /* 0x0e80 - 0x0efc: reserved */
-
-/*
- * Bank 30
- */
-/* GMAC and GPHY Control Registers (YUKON only) */
-#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */
-#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */
-#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */
- /* 0x0f09 - 0x0f0b: reserved */
-#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */
- /* 0x0f0d - 0x0f0f: reserved */
-#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */
- /* 0x0f14 - 0x0f1f: reserved */
-
-/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
-
-#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */
-
-#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */
-#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */
-#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */
-#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */
-#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */
-#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */
-
-/* use this macro to access above registers */
-#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs))
-
-
-/* WOL Pattern Length Registers (YUKON only) */
-
-#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */
-#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */
-
-/* WOL Pattern Counter Registers (YUKON only) */
-
-#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */
-#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */
- /* 0x0f40 - 0x0f7f: reserved */
-
-/*
- * Bank 31
- */
-/* 0x0f80 - 0x0fff: reserved */
-
-/*
- * Bank 32 - 33
- */
-#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */
-
-/*
- * Bank 0x22 - 0x3f
- */
-/* 0x1100 - 0x1fff: reserved */
-
-/*
- * Bank 0x40 - 0x4f
- */
-#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */
-
-/*
- * Bank 0x50 - 0x5f
- */
-
-#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */
-
-/*
- * Bank 0x60 - 0x6f
- */
-#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */
-
-/*
- * Bank 0x70 - 0x7f
- */
-#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */
-
-/*
- * Control Register Bit Definitions:
- */
-/* B0_RAP 8 bit Register Address Port */
- /* Bit 7: reserved */
-#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */
-
-/* B0_CTST 16 bit Control/Status register */
- /* Bit 15..14: reserved */
-#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */
-#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */
-#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */
-#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */
-#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */
-#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */
-#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */
-#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */
-#define CS_STOP_DONE BIT_5S /* Stop Master is finished */
-#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */
-#define CS_MRST_CLR BIT_3S /* Clear Master reset */
-#define CS_MRST_SET BIT_2S /* Set Master reset */
-#define CS_RST_CLR BIT_1S /* Clear Software reset */
-#define CS_RST_SET BIT_0S /* Set Software reset */
-
-/* B0_LED 8 Bit LED register */
- /* Bit 7.. 2: reserved */
-#define LED_STAT_ON BIT_1S /* Status LED on */
-#define LED_STAT_OFF BIT_0S /* Status LED off */
-
-/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */
-#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */
-#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */
-#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */
-#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */
-#define PC_VAUX_ON BIT_3 /* Switch VAUX On */
-#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */
-#define PC_VCC_ON BIT_1 /* Switch VCC On */
-#define PC_VCC_OFF BIT_0 /* Switch VCC Off */
-
-/* B0_ISRC 32 bit Interrupt Source Register */
-/* B0_IMSK 32 bit Interrupt Mask Register */
-/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */
-/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */
-#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */
-#define IS_HW_ERR BIT_31 /* Interrupt HW Error */
- /* Bit 30: reserved */
-#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */
-#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */
-#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */
-#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */
-#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */
-#define IS_IRQ_SW BIT_24 /* SW forced IRQ */
-#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */
- /* IRQ from PHY (YUKON only) */
-#define IS_TIMINT BIT_22 /* IRQ from Timer */
-#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */
-#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */
-#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */
-#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */
-/* Receive Queue 1 */
-#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */
-#define IS_R1_F BIT_16 /* Q_R1 End of Frame */
-#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */
-/* Receive Queue 2 */
-#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */
-#define IS_R2_F BIT_13 /* Q_R2 End of Frame */
-#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */
-/* Synchronous Transmit Queue 1 */
-#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */
-#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */
-#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */
-/* Asynchronous Transmit Queue 1 */
-#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */
-#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */
-#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */
-/* Synchronous Transmit Queue 2 */
-#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */
-#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */
-#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */
-/* Asynchronous Transmit Queue 2 */
-#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */
-#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */
-#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */
-
-
-/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */
-/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */
-/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
-#define IS_ERR_MSK 0x00000fffL /* All Error bits */
- /* Bit 31..14: reserved */
-#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */
-#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */
-#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */
-#define IS_IRQ_STAT BIT_10 /* IRQ status exception */
-#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */
-#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */
-#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */
-#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */
-#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */
-#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */
-#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */
-#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */
-#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */
-#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */
-
-/* B2_CONN_TYP 8 bit Connector type */
-/* B2_PMD_TYP 8 bit PMD type */
-/* Values of connector and PMD type comply to SysKonnect internal std */
-
-/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */
-#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */
- /* Bit 3.. 2: reserved */
-#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */
-#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/
-
-/* B2_CHIP_ID 8 bit Chip Identification Number */
-#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */
-#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */
-#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */
-#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */
-
-#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */
-#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */
-
-/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */
-#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */
-
-/* B2_LD_CTRL 8 bit EPROM loader control register */
-/* Bits are currently reserved */
-
-/* B2_LD_TEST 8 bit EPROM loader test register */
- /* Bit 7.. 4: reserved */
-#define LD_T_ON BIT_3S /* Loader Test mode on */
-#define LD_T_OFF BIT_2S /* Loader Test mode off */
-#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */
-#define LD_START BIT_0S /* Start loading FPROM */
-
-/*
- * Timer Section
- */
-/* B2_TI_CTRL 8 bit Timer control */
-/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
- /* Bit 7.. 3: reserved */
-#define TIM_START BIT_2S /* Start Timer */
-#define TIM_STOP BIT_1S /* Stop Timer */
-#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */
-
-/* B2_TI_TEST 8 Bit Timer Test */
-/* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */
-/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */
- /* Bit 7.. 3: reserved */
-#define TIM_T_ON BIT_2S /* Test mode on */
-#define TIM_T_OFF BIT_1S /* Test mode off */
-#define TIM_T_STEP BIT_0S /* Test step */
-
-/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
-/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
- /* Bit 31..24: reserved */
-#define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */
-
-/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
- /* Bit 7.. 2: reserved */
-#define DPT_START BIT_1S /* Start Descriptor Poll Timer */
-#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */
-
-/* B2_E_3 8 bit lower 4 bits used for HW self test result */
-#define B2_E3_RES_MASK 0x0f
-
-/* B2_TST_CTRL1 8 bit Test Control Register 1 */
-#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */
-#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */
-#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */
-#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */
-#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */
-#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */
-#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */
-#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */
-
-/* B2_TST_CTRL2 8 bit Test Control Register 2 */
- /* Bit 7.. 4: reserved */
- /* force the following error on the next master read/write */
-#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */
-#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */
-#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */
-#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */
-
-/* B2_GP_IO 32 bit General Purpose I/O Register */
- /* Bit 31..26: reserved */
-#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */
-#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */
-#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */
-#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */
-#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */
-#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */
-#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */
-#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */
-#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */
-#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */
- /* Bit 15..10: reserved */
-#define GP_IO_9 BIT_9 /* IO_9 pin */
-#define GP_IO_8 BIT_8 /* IO_8 pin */
-#define GP_IO_7 BIT_7 /* IO_7 pin */
-#define GP_IO_6 BIT_6 /* IO_6 pin */
-#define GP_IO_5 BIT_5 /* IO_5 pin */
-#define GP_IO_4 BIT_4 /* IO_4 pin */
-#define GP_IO_3 BIT_3 /* IO_3 pin */
-#define GP_IO_2 BIT_2 /* IO_2 pin */
-#define GP_IO_1 BIT_1 /* IO_1 pin */
-#define GP_IO_0 BIT_0 /* IO_0 pin */
-
-/* B2_I2C_CTRL 32 bit I2C HW Control Register */
-#define I2C_FLAG BIT_31 /* Start read/write if WR */
-#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */
-#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */
- /* Bit 8.. 5: reserved */
-#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */
-#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */
-#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */
-#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */
-#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */
-#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */
-#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */
-#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */
-#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */
-#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */
-#define I2C_STOP BIT_0 /* Interrupt I2C transfer */
-
-/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */
- /* Bit 31.. 1 reserved */
-#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */
-
-/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */
- /* Bit 7.. 3: reserved */
-#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */
-#define I2C_DATA BIT_1S /* I2C Data Port */
-#define I2C_CLK BIT_0S /* I2C Clock Port */
-
-/*
- * I2C Address
- */
-#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/
-
-
-/* B2_BSC_CTRL 8 bit Blink Source Counter Control */
- /* Bit 7.. 2: reserved */
-#define BSC_START BIT_1S /* Start Blink Source Counter */
-#define BSC_STOP BIT_0S /* Stop Blink Source Counter */
-
-/* B2_BSC_STAT 8 bit Blink Source Counter Status */
- /* Bit 7.. 1: reserved */
-#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */
-
-/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */
-#define BSC_T_ON BIT_2S /* Test mode on */
-#define BSC_T_OFF BIT_1S /* Test mode off */
-#define BSC_T_STEP BIT_0S /* Test step */
-
-
-/* B3_RAM_ADDR 32 bit RAM Address, to read or write */
- /* Bit 31..19: reserved */
-#define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */
-
-/* RAM Interface Registers */
-/* B3_RI_CTRL 16 bit RAM Iface Control Register */
- /* Bit 15..10: reserved */
-#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */
-#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/
- /* Bit 7.. 2: reserved */
-#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */
-#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */
-
-/* B3_RI_TEST 8 bit RAM Iface Test Register */
- /* Bit 15.. 4: reserved */
-#define RI_T_EV BIT_3S /* Timeout Event occured */
-#define RI_T_ON BIT_2S /* Timeout Timer Test On */
-#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */
-#define RI_T_STEP BIT_0S /* Timeout Timer Step */
-
-/* MAC Arbiter Registers */
-/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
- /* Bit 15.. 4: reserved */
-#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */
-#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */
-#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
-#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
-
-/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
- /* Bit 15.. 8: reserved */
-#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */
-#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */
-#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */
-#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */
-#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */
-#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */
-#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */
-#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */
-
-/* Packet Arbiter Registers */
-/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
- /* Bit 15..14: reserved */
-#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */
-#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */
-#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */
-#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */
-#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */
-#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */
-#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */
-#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */
-#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */
-#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */
-#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */
-#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */
-#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
-#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
-
-#define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
- PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
-
-/* Rx/Tx Path related Arbiter Test Registers */
-/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
-/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
-/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
-/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
-#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */
-#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */
-#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */
-#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */
-#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */
-#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */
-#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */
-#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */
-#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */
-#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */
-#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */
-#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */
-#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */
-#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */
-#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */
-#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */
-
-
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
-/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
-/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
-/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */
- /* Bit 31..24: reserved */
-#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */
-
-/* TXA_CTRL 8 bit Tx Arbiter Control Register */
-#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */
-#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */
-#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */
-#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */
-#define TXA_START_RC BIT_3S /* Start sync Rate Control */
-#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */
-#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */
-#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */
-
-/* TXA_TEST 8 bit Tx Arbiter Test Register */
- /* Bit 7.. 6: reserved */
-#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */
-#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */
-#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */
-#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */
-#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */
-#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */
-
-/* TXA_STAT 8 bit Tx Arbiter Status Register */
- /* Bit 7.. 1: reserved */
-#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */
-
-/* Q_BC 32 bit Current Byte Counter */
- /* Bit 31..16: reserved */
-#define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */
-
-/* BMU Control Status Registers */
-/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */
-/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */
-/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
-/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */
-/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
-/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */
-/* Q_CSR 32 bit BMU Control/Status Register */
- /* Bit 31..25: reserved */
-#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */
- /* Bit 23..22: reserved */
-#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */
-#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */
-#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */
-#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */
-#define CSR_HPI_RUN BIT_17 /* Release HPI SM */
-#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */
-#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */
-#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */
-#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */
-#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */
-#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */
-#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */
-#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */
-#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */
-#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */
-#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */
-#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */
-#define CSR_START BIT_4 /* Start Rx/Tx Queue */
-#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */
-#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */
-#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */
-#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */
-
-#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
- CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
- CSR_TRANS_RST)
-#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
- CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
- CSR_TRANS_RUN)
-
-/* Q_F 32 bit Flag Register */
- /* Bit 31..28: reserved */
-#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */
-#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
-#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
-#define F_WM_REACHED BIT_25 /* Watermark reached */
- /* reserved */
-#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */
- /* Bit 15..11: reserved */
-#define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */
-
-/* Q_T1 32 bit Test Register 1 */
-/* Holds four State Machine control Bytes */
-#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */
-#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */
-#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */
-#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */
-
-/* Q_T1_TR 8 bit Test Register 1 Transfer SM */
-/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */
-/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */
-/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */
-
-/* The control status byte of each machine looks like ... */
-#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */
-#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */
-#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */
-#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */
-#define SM_STEP BIT_0S /* Step the State Machine */
-/* The encoding of the states is not supported by the Diagnostics Tool */
-
-/* Q_T2 32 bit Test Register 2 */
- /* Bit 31.. 8: reserved */
-#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */
-#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */
-#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */
-#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */
-#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */
-#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */
-#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */
-#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */
-
-/* Q_T3 32 bit Test Register 3 */
- /* Bit 31.. 7: reserved */
-#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */
- /* Bit 3: reserved */
-#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */
-
-/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
-/* RB_START 32 bit RAM Buffer Start Address */
-/* RB_END 32 bit RAM Buffer End Address */
-/* RB_WP 32 bit RAM Buffer Write Pointer */
-/* RB_RP 32 bit RAM Buffer Read Pointer */
-/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */
-/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */
-/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */
-/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */
-/* RB_PC 32 bit RAM Buffer Packet Counter */
-/* RB_LEV 32 bit RAM Buffer Level Register */
- /* Bit 31..19: reserved */
-#define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */
-
-/* RB_TST2 8 bit RAM Buffer Test Register 2 */
- /* Bit 7.. 4: reserved */
-#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */
-#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */
-#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */
-#define RB_PC_INC BIT_0S /* Packet Counter Increm */
-
-/* RB_TST1 8 bit RAM Buffer Test Register 1 */
- /* Bit 7: reserved */
-#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */
-#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */
-#define RB_WP_INC BIT_4S /* Write Pointer Increm */
- /* Bit 3: reserved */
-#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */
-#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */
-#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */
-
-/* RB_CTRL 8 bit RAM Buffer Control Register */
- /* Bit 7.. 6: reserved */
-#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */
-#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */
-#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */
-#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */
-#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */
-#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */
-
-
-/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
-
-/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */
-/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */
-/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */
-/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */
-/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */
-/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */
-/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */
-/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */
-/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */
-/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */
-/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */
- /* Bit 31.. 6: reserved */
-#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */
-
-/* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */
- /* Bit 15..14: reserved */
-#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */
-#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */
-#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */
-#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */
-#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */
-#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */
-#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */
-#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */
-#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */
-#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */
-#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */
-#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */
-#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */
-#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */
-
-#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
-
-/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */
-#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */
- /* Bit 14: reserved */
-#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */
-#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */
-/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */
-/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */
-/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */
-/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */
-#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */
-#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */
-/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */
-/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */
-#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */
-#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */
-#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */
-#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */
-
-#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
-
-/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */
-/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */
- /* Bit 7: reserved */
-#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */
-#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */
-#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */
-#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */
-#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */
-#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */
-#define MFF_PC_INC BIT_0S /* Packet Counter Increment */
-
-/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */
-/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */
- /* Bit 7: reserved */
-#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */
-#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */
-#define MFF_WP_INC BIT_4S /* Write Pointer Increm */
- /* Bit 3: reserved */
-#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */
-#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */
-#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */
-
-/* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */
-/* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */
- /* Bit 7..4: reserved */
-#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */
-#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */
-#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */
-#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */
-
-
-/* Link LED Counter Registers (GENESIS only) */
-
-/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */
-/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */
-/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */
- /* Bit 7.. 3: reserved */
-#define LED_START BIT_2S /* Start Timer */
-#define LED_STOP BIT_1S /* Stop Timer */
-#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */
-#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */
-
-/* RX_LED_TST 8 bit Receive LED Cnt Test Register */
-/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */
-/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */
- /* Bit 7.. 3: reserved */
-#define LED_T_ON BIT_2S /* LED Counter Test mode On */
-#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */
-#define LED_T_STEP BIT_0S /* LED Counter Step */
-
-/* LNK_LED_REG 8 bit Link LED Register */
- /* Bit 7.. 6: reserved */
-#define LED_BLK_ON BIT_5S /* Link LED Blinking On */
-#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */
-#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */
-#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */
-#define LED_ON BIT_1S /* switch LED on */
-#define LED_OFF BIT_0S /* switch LED off */
-
-/* Receive and Transmit GMAC FIFO Registers (YUKON only) */
-
-/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */
-/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */
-/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */
-/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */
-/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */
-/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */
-/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */
-/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
-/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */
-/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */
-/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */
-/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */
-/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */
-/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */
-
-/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */
- /* Bits 31..15: reserved */
-#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */
-#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */
-#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */
- /* Bit 11: reserved */
-#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */
-#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */
-#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */
-#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */
-#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */
-#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */
-#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */
-#define GMF_OPER_ON BIT_3 /* Operational Mode On */
-#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */
-#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */
-#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */
-
-/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */
- /* Bits 31..19: reserved */
-#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */
-#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */
-#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */
- /* Bits 15..7: same as for RX_GMF_CTRL_T */
-#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */
-#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */
-#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */
- /* Bits 3..0: same as for RX_GMF_CTRL_T */
-
-#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON)
-#define GMF_TX_CTRL_DEF GMF_OPER_ON
-
-#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */
-
-/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
- /* Bit 7.. 3: reserved */
-#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */
-#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */
-#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */
-
-/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
- /* Bits 31.. 8: reserved */
-#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */
-#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */
-#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */
-#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */
-#define GMC_PAUSE_ON BIT_3 /* Pause On */
-#define GMC_PAUSE_OFF BIT_2 /* Pause Off */
-#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */
-#define GMC_RST_SET BIT_0 /* Set GMAC Reset */
-
-/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
- /* Bits 31..29: reserved */
-#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */
-#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */
-#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */
-#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */
-#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */
-#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */
-#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */
-#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */
-#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */
-#define GPC_ANEG_0 BIT_19 /* ANEG[0] */
-#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */
-#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */
-#define GPC_ANEG_3 BIT_16 /* ANEG[3] */
-#define GPC_ANEG_2 BIT_15 /* ANEG[2] */
-#define GPC_ANEG_1 BIT_14 /* ANEG[1] */
-#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */
-#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */
-#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */
-#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */
-#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */
-#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */
- /* Bits 7..2: reserved */
-#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */
-#define GPC_RST_SET BIT_0 /* Set GPHY Reset */
-
-#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
- GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
-
-#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \
- GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
-
-#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \
- GPC_ANEG_1 | GPC_ANEG_0)
-
-/* forced speed and duplex mode (don't mix with other ANEG bits) */
-#define GPC_FRC10MBIT_HALF 0
-#define GPC_FRC10MBIT_FULL GPC_ANEG_0
-#define GPC_FRC100MBIT_HALF GPC_ANEG_1
-#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1)
-
-/* auto-negotiation with limited advertised speeds */
-/* mix only with master/slave settings (for copper) */
-#define GPC_ADV_1000_HALF GPC_ANEG_2
-#define GPC_ADV_1000_FULL GPC_ANEG_3
-#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3)
-
-/* master/slave settings */
-/* only for copper with 1000 Mbps */
-#define GPC_FORCE_MASTER 0
-#define GPC_FORCE_SLAVE GPC_ANEG_0
-#define GPC_PREF_MASTER GPC_ANEG_1
-#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0)
-
-/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */
-/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */
-#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */
-#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */
-#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */
-#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */
-#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */
-#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */
-
-#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
- GM_IS_TX_FF_UR)
-
-/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
- /* Bits 15.. 2: reserved */
-#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */
-#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */
-
-
-/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */
-#define WOL_CTL_LINK_CHG_OCC BIT_15S
-#define WOL_CTL_MAGIC_PKT_OCC BIT_14S
-#define WOL_CTL_PATTERN_OCC BIT_13S
-
-#define WOL_CTL_CLEAR_RESULT BIT_12S
-
-#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S
-#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S
-#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S
-#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S
-#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S
-#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S
-
-#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S
-#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S
-#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S
-#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S
-#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S
-#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S
-
-#define WOL_CTL_DEFAULT \
- (WOL_CTL_DIS_PME_ON_LINK_CHG | \
- WOL_CTL_DIS_PME_ON_PATTERN | \
- WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
- WOL_CTL_DIS_LINK_CHG_UNIT | \
- WOL_CTL_DIS_PATTERN_UNIT | \
- WOL_CTL_DIS_MAGIC_PKT_UNIT)
-
-/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */
-#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x))
-
-#define SK_NUM_WOL_PATTERN 7
-#define SK_PATTERN_PER_WORD 4
-#define SK_BITMASK_PATTERN 7
-#define SK_POW_PATTERN_LENGTH 128
-
-#define WOL_LENGTH_MSK 0x7f
-#define WOL_LENGTH_SHIFT 8
-
-
-/* Receive and Transmit Descriptors ******************************************/
-
-/* Transmit Descriptor struct */
-typedef struct s_HwTxd {
- SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
- SK_U32 TxNext; /* Physical Address Pointer to the next TxD */
- SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */
- SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */
- SK_U32 TxStat; /* Transmit Frame Status Word */
-#ifndef SK_USE_REV_DESC
- SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
- SK_U16 TxRes1; /* 16 bit reserved field */
- SK_U16 TxTcpWp; /* TCP Checksum Write Position */
- SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
-#else /* SK_USE_REV_DESC */
- SK_U16 TxRes1; /* 16 bit reserved field */
- SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
- SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
- SK_U16 TxTcpWp; /* TCP Checksum Write Position */
-#endif /* SK_USE_REV_DESC */
- SK_U32 TxRes2; /* 32 bit reserved field */
-} SK_HWTXD;
-
-/* Receive Descriptor struct */
-typedef struct s_HwRxd {
- SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
- SK_U32 RxNext; /* Physical Address Pointer to the next RxD */
- SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */
- SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */
- SK_U32 RxStat; /* Receive Frame Status Word */
- SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */
-#ifndef SK_USE_REV_DESC
- SK_U16 RxTcpSum1; /* TCP Checksum 1 */
- SK_U16 RxTcpSum2; /* TCP Checksum 2 */
- SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
- SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
-#else /* SK_USE_REV_DESC */
- SK_U16 RxTcpSum2; /* TCP Checksum 2 */
- SK_U16 RxTcpSum1; /* TCP Checksum 1 */
- SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
- SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
-#endif /* SK_USE_REV_DESC */
-} SK_HWRXD;
-
-/*
- * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
- * should set the define SK_USE_REV_DESC.
- * Structures are 'normaly' not endianess dependent. But in
- * this case the SK_U16 fields are bound to bit positions inside the
- * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
- * The bit positions inside a DWord are of course endianess dependent and
- * swaps if the DWord is swapped by the hardware.
- */
-
-
-/* Descriptor Bit Definition */
-/* TxCtrl Transmit Buffer Control Field */
-/* RxCtrl Receive Buffer Control Field */
-#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */
-#define BMU_STF BIT_30 /* Start of Frame */
-#define BMU_EOF BIT_29 /* End of Frame */
-#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */
-#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */
-/* TxCtrl specific bits */
-#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */
-#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */
-#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */
-/* RxCtrl specific bits */
-#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */
-#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */
-#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */
- /* Bit 23..16: BMU Check Opcodes */
-#define BMU_CHECK (0x55L<<16) /* Default BMU check */
-#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */
-#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */
-#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */
-
-/* TxStat Transmit Frame Status Word */
-/* RxStat Receive Frame Status Word */
-/*
- *Note: TxStat is reserved for ASIC loopback mode only
- *
- * The Bits of the Status words are defined in xmac_ii.h
- * (see XMR_FS bits)
- */
-
-/* macros ********************************************************************/
-
-/* Receive and Transmit Queues */
-#define Q_R1 0x0000 /* Receive Queue 1 */
-#define Q_R2 0x0080 /* Receive Queue 2 */
-#define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */
-#define Q_XA1 0x0280 /* Asynchronous Transmit Queue 1 */
-#define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */
-#define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */
-
-/*
- * Macro Q_ADDR()
- *
- * Use this macro to access the Receive and Transmit Queue Registers.
- *
- * para:
- * Queue Queue to access.
- * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
- * Offs Queue register offset.
- * Values: Q_D, Q_DA_L ... Q_T2, Q_T3
- *
- * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
- */
-#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs))
-
-/*
- * Macro RB_ADDR()
- *
- * Use this macro to access the RAM Buffer Registers.
- *
- * para:
- * Queue Queue to access.
- * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
- * Offs Queue register offset.
- * Values: RB_START, RB_END ... RB_LEV, RB_CTRL
- *
- * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
- */
-#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs))
-
-
-/* MAC Related Registers */
-#define MAC_1 0 /* belongs to the port near the slot */
-#define MAC_2 1 /* belongs to the port far away from the slot */
-
-/*
- * Macro MR_ADDR()
- *
- * Use this macro to access a MAC Related Registers inside the ASIC.
- *
- * para:
- * Mac MAC to access.
- * Values: MAC_1, MAC_2
- * Offs MAC register offset.
- * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
- * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
- *
- * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
- */
-#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs))
-
-#ifdef SK_LITTLE_ENDIAN
-#define XM_WORD_LO 0
-#define XM_WORD_HI 1
-#else /* !SK_LITTLE_ENDIAN */
-#define XM_WORD_LO 1
-#define XM_WORD_HI 0
-#endif /* !SK_LITTLE_ENDIAN */
-
-
-/*
- * macros to access the XMAC (GENESIS only)
- *
- * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD)
- * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD)
- * XM_IN32(), to read a 32 bit register (e.g. XM_TX_EV_CNT)
- * XM_OUT32(), to write a 32 bit register (e.g. XM_TX_EV_CNT)
- * XM_INADDR(), to read a network address register (e.g. XM_SRC_CHK)
- * XM_OUTADDR(), to write a network address register (e.g. XM_SRC_CHK)
- * XM_INHASH(), to read the XM_HSM_CHK register
- * XM_OUTHASH() to write the XM_HSM_CHK register
- *
- * para:
- * Mac XMAC to access values: MAC_1 or MAC_2
- * IoC I/O context needed for SK I/O macros
- * Reg XMAC Register to read or write
- * (p)Val Value or pointer to the value which should be read or written
- *
- * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
- */
-
-#define XMA(Mac, Reg) \
- ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
-
-#define XM_IN16(IoC, Mac, Reg, pVal) \
- SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
-
-#define XM_OUT16(IoC, Mac, Reg, Val) \
- SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
-
-#define XM_IN32(IoC, Mac, Reg, pVal) { \
- SK_IN16((IoC), XMA((Mac), (Reg)), \
- (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
- SK_IN16((IoC), XMA((Mac), (Reg+2)), \
- (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
-}
-
-#define XM_OUT32(IoC, Mac, Reg, Val) { \
- SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
- SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
-}
-
-/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
-
-#define XM_INADDR(IoC, Mac, Reg, pVal) { \
- SK_U16 Word; \
- SK_U8 *pByte; \
- pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
- SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
- pByte[0] = (SK_U8)(Word & 0x00ff); \
- pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
- pByte[2] = (SK_U8)(Word & 0x00ff); \
- pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
- pByte[4] = (SK_U8)(Word & 0x00ff); \
- pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
-}
-
-#define XM_OUTADDR(IoC, Mac, Reg, pVal) { \
- SK_U8 SK_FAR *pByte; \
- pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
- SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
- (((SK_U16)(pByte[0]) & 0x00ff) | \
- (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
- SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
- (((SK_U16)(pByte[2]) & 0x00ff) | \
- (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
- SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
- (((SK_U16)(pByte[4]) & 0x00ff) | \
- (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
-}
-
-#define XM_INHASH(IoC, Mac, Reg, pVal) { \
- SK_U16 Word; \
- SK_U8 SK_FAR *pByte; \
- pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
- SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
- pByte[0] = (SK_U8)(Word & 0x00ff); \
- pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
- pByte[2] = (SK_U8)(Word & 0x00ff); \
- pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
- pByte[4] = (SK_U8)(Word & 0x00ff); \
- pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \
- pByte[6] = (SK_U8)(Word & 0x00ff); \
- pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
-}
-
-#define XM_OUTHASH(IoC, Mac, Reg, pVal) { \
- SK_U8 SK_FAR *pByte; \
- pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
- SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
- (((SK_U16)(pByte[0]) & 0x00ff)| \
- (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
- SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
- (((SK_U16)(pByte[2]) & 0x00ff)| \
- (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
- SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
- (((SK_U16)(pByte[4]) & 0x00ff)| \
- (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
- SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \
- (((SK_U16)(pByte[6]) & 0x00ff)| \
- (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
-}
-
-/*
- * macros to access the GMAC (YUKON only)
- *
- * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT)
- * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL)
- * GM_IN32(), to read a 32 bit register (e.g. GM_)
- * GM_OUT32(), to write a 32 bit register (e.g. GM_)
- * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L)
- * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L)
- * GM_INHASH(), to read the GM_MC_ADDR_H1 register
- * GM_OUTHASH() to write the GM_MC_ADDR_H1 register
- *
- * para:
- * Mac GMAC to access values: MAC_1 or MAC_2
- * IoC I/O context needed for SK I/O macros
- * Reg GMAC Register to read or write
- * (p)Val Value or pointer to the value which should be read or written
- *
- * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
- */
-
-#define GMA(Mac, Reg) \
- ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
-
-#define GM_IN16(IoC, Mac, Reg, pVal) \
- SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
-
-#define GM_OUT16(IoC, Mac, Reg, Val) \
- SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
-
-#define GM_IN32(IoC, Mac, Reg, pVal) { \
- SK_IN16((IoC), GMA((Mac), (Reg)), \
- (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
- SK_IN16((IoC), GMA((Mac), (Reg+4)), \
- (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
-}
-
-#define GM_OUT32(IoC, Mac, Reg, Val) { \
- SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
- SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
-}
-
-#define GM_INADDR(IoC, Mac, Reg, pVal) { \
- SK_U16 Word; \
- SK_U8 *pByte; \
- pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
- SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
- pByte[0] = (SK_U8)(Word & 0x00ff); \
- pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
- pByte[2] = (SK_U8)(Word & 0x00ff); \
- pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
- pByte[4] = (SK_U8)(Word & 0x00ff); \
- pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
-}
-
-#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \
- SK_U8 SK_FAR *pByte; \
- pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
- SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
- (((SK_U16)(pByte[0]) & 0x00ff) | \
- (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
- SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
- (((SK_U16)(pByte[2]) & 0x00ff) | \
- (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
- SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
- (((SK_U16)(pByte[4]) & 0x00ff) | \
- (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
-}
-
-#define GM_INHASH(IoC, Mac, Reg, pVal) { \
- SK_U16 Word; \
- SK_U8 *pByte; \
- pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
- SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
- pByte[0] = (SK_U8)(Word & 0x00ff); \
- pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
- pByte[2] = (SK_U8)(Word & 0x00ff); \
- pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
- pByte[4] = (SK_U8)(Word & 0x00ff); \
- pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
- SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \
- pByte[6] = (SK_U8)(Word & 0x00ff); \
- pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
-}
-
-#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \
- SK_U8 *pByte; \
- pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
- SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
- (((SK_U16)(pByte[0]) & 0x00ff)| \
- (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
- SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
- (((SK_U16)(pByte[2]) & 0x00ff)| \
- (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
- SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
- (((SK_U16)(pByte[4]) & 0x00ff)| \
- (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
- SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \
- (((SK_U16)(pByte[6]) & 0x00ff)| \
- (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
-}
-
-/*
- * Different MAC Types
- */
-#define SK_MAC_XMAC 0 /* Xaqti XMAC II */
-#define SK_MAC_GMAC 1 /* Marvell GMAC */
-
-/*
- * Different PHY Types
- */
-#define SK_PHY_XMAC 0 /* integrated in XMAC II */
-#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */
-#define SK_PHY_LONE 2 /* Level One LXT1000 */
-#define SK_PHY_NAT 3 /* National DP83891 */
-#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */
-#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */
-
-/*
- * PHY addresses (bits 12..8 of PHY address reg)
- */
-#define PHY_ADDR_XMAC (0<<8)
-#define PHY_ADDR_BCOM (1<<8)
-#define PHY_ADDR_LONE (3<<8)
-#define PHY_ADDR_NAT (0<<8)
-
-/* GPHY address (bits 15..11 of SMI control reg) */
-#define PHY_ADDR_MARV 0
-
-/*
- * macros to access the PHY
- *
- * PHY_READ() read a 16 bit value from the PHY
- * PHY_WRITE() write a 16 bit value to the PHY
- *
- * para:
- * IoC I/O context needed for SK I/O macros
- * pPort Pointer to port struct for PhyAddr
- * Mac XMAC to access values: MAC_1 or MAC_2
- * PhyReg PHY Register to read or write
- * (p)Val Value or pointer to the value which should be read or
- * written.
- *
- * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
- * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
- * comes back. This is checked in DEBUG mode.
- */
-#ifndef DEBUG
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
- SK_U16 Mmu; \
- \
- XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
- XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
- if ((pPort)->PhyType != SK_PHY_XMAC) { \
- do { \
- XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
- } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
- XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
- } \
-}
-#else
-#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
- SK_U16 Mmu; \
- int __i = 0; \
- \
- XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
- XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
- if ((pPort)->PhyType != SK_PHY_XMAC) { \
- do { \
- XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
- __i++; \
- if (__i > 100000) { \
- SK_DBG_PRINTF("*****************************\n"); \
- SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
- SK_DBG_PRINTF("*****************************\n"); \
- break; \
- } \
- } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
- XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
- } \
-}
-#endif /* DEBUG */
-
-#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \
- SK_U16 Mmu; \
- \
- if ((pPort)->PhyType != SK_PHY_XMAC) { \
- do { \
- XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
- } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
- } \
- XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
- XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \
- if ((pPort)->PhyType != SK_PHY_XMAC) { \
- do { \
- XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
- } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
- } \
-}
-
-/*
- * Macro PCI_C()
- *
- * Use this macro to access PCI config register from the I/O space.
- *
- * para:
- * Addr PCI configuration register to access.
- * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
- *
- * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
- */
-#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */
-
-/*
- * Macro SK_HW_ADDR(Base, Addr)
- *
- * Calculates the effective HW address
- *
- * para:
- * Base I/O or memory base address
- * Addr Address offset
- *
- * usage: May be used in SK_INxx and SK_OUTxx macros
- * #define SK_IN8(pAC, Addr, pVal) ...\
- * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
- */
-#ifdef SK_MEM_MAPPED_IO
-#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
-#else /* SK_MEM_MAPPED_IO */
-#define SK_HW_ADDR(Base, Addr) \
- ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
-#endif /* SK_MEM_MAPPED_IO */
-
-#define SZ_LONG (sizeof(SK_U32))
-
-/*
- * Macro SK_HWAC_LINK_LED()
- *
- * Use this macro to set the link LED mode.
- * para:
- * pAC Pointer to adapter context struct
- * IoC I/O context needed for SK I/O macros
- * Port Port number
- * Mode Mode to set for this LED
- */
-#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
- SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
-
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
deleted file mode 100644
index e6b0016a695c..000000000000
--- a/drivers/net/sk98lin/h/skgehwt.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/******************************************************************************
- *
- * Name: skhwt.h
- * Project: Gigabit Ethernet Adapters, Event Scheduler Module
- * Version: $Revision: 1.7 $
- * Date: $Date: 2003/09/16 12:55:08 $
- * Purpose: Defines for the hardware timer functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKGEHWT.H contains all defines and types for the timer functions
- */
-
-#ifndef _SKGEHWT_H_
-#define _SKGEHWT_H_
-
-/*
- * SK Hardware Timer
- * - needed wherever the HWT module is used
- * - use in Adapters context name pAC->Hwt
- */
-typedef struct s_Hwt {
- SK_U32 TStart; /* HWT start */
- SK_U32 TStop; /* HWT stop */
- int TActive; /* HWT: flag : active/inactive */
-} SK_HWT;
-
-extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
-extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
-extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
-extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
-extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
-#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
deleted file mode 100644
index d9b6f6d8dfe2..000000000000
--- a/drivers/net/sk98lin/h/skgei2c.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/******************************************************************************
- *
- * Name: skgei2c.h
- * Project: Gigabit Ethernet Adapters, TWSI-Module
- * Version: $Revision: 1.25 $
- * Date: $Date: 2003/10/20 09:06:05 $
- * Purpose: Special defines for TWSI
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling
- */
-
-#ifndef _INC_SKGEI2C_H_
-#define _INC_SKGEI2C_H_
-
-/*
- * Macros to access the B2_I2C_CTRL
- */
-#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
- SK_OUT32(IoC, B2_I2C_CTRL,\
- (flag ? 0x80000000UL : 0x0L) | \
- (((SK_U32)reg << 16) & I2C_ADDR) | \
- (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
- (dev_size & I2C_DEV_SIZE) | \
- ((burst << 4) & I2C_BURST_LEN))
-
-#define SK_I2C_STOP(IoC) { \
- SK_U32 I2cCtrl; \
- SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \
- SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
-}
-
-#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
-
-/*
- * Macros to access the TWSI SW Registers
- */
-#define SK_I2C_SET_BIT(IoC, SetBits) { \
- SK_U8 OrgBits; \
- SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
- SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \
-}
-
-#define SK_I2C_CLR_BIT(IoC, ClrBits) { \
- SK_U8 OrgBits; \
- SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
- SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
-}
-
-#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw)
-
-/*
- * define the possible sensor states
- */
-#define SK_SEN_IDLE 0 /* Idle: sensor not read */
-#define SK_SEN_VALUE 1 /* Value Read cycle */
-#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */
-
-/*
- * Conversion factor to convert read Voltage sensor to milli Volt
- * Conversion factor to convert read Temperature sensor to 10th degree Celsius
- */
-#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */
-#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */
-#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */
-
-/*
- * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
- * assuming: 6500rpm, 4 pulses, divisor 1
- */
-#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2))
-
-/*
- * Define sensor management data
- * Maximum is reached on Genesis copper dual port and Yukon-64
- * Board specific maximum is in pAC->I2c.MaxSens
- */
-#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */
-#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */
-
-/*
- * To watch the state machine (SM) use the timer in two ways
- * instead of one as hitherto
- */
-#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */
-#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */
-
-/*
- * Defines for the individual thresholds
- */
-
-/* Temperature sensor */
-#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */
-#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */
-#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */
-#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */
-
-/* VCC which should be 5 V */
-#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */
-#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */
-#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */
-#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */
-
-/*
- * VIO may be 5 V or 3.3 V. Initialization takes two parts:
- * 1. Initialize lowest lower limit and highest higher limit.
- * 2. After the first value is read correct the upper or the lower limit to
- * the appropriate C constant.
- *
- * Warning limits are +-5% of the exepected voltage.
- * Error limits are +-10% of the expected voltage.
- */
-
-/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
-
-#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */
-#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */
- /* 5000 mVolt */
-#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */
-#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */
-
-#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */
-
-/* correction values for the second pass */
-#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */
-#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */
- /* 3300 mVolt */
-#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */
-#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */
-
-/*
- * VDD voltage
- */
-#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */
-#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */
-#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */
-#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */
-
-/*
- * PHY PLL 3V3 voltage
- */
-#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */
-#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */
-#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */
-#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */
-
-/*
- * VAUX (YUKON only)
- */
-#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */
-#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */
-#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */
-#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */
-#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */
-#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */
-
-/*
- * PHY 2V5 voltage
- */
-#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */
-#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */
-#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */
-#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */
-
-/*
- * ASIC Core 1V5 voltage (YUKON only)
- */
-#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */
-#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */
-#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */
-#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */
-
-/*
- * FAN 1 speed
- */
-/* assuming: 6500rpm +-15%, 4 pulses,
- * warning at: 80 %
- * error at: 70 %
- * no upper limit
- */
-#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */
-#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */
-#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */
-#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */
-
-/*
- * Some Voltages need dynamic thresholds
- */
-#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */
-#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */
-#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */
-
-extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
-#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
deleted file mode 100644
index 143e635ec24d..000000000000
--- a/drivers/net/sk98lin/h/skgeinit.h
+++ /dev/null
@@ -1,797 +0,0 @@
-/******************************************************************************
- *
- * Name: skgeinit.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.83 $
- * Date: $Date: 2003/09/16 14:07:37 $
- * Purpose: Structures and prototypes for the GE Init Module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_SKGEINIT_H_
-#define __INC_SKGEINIT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-#define SK_TEST_VAL 0x11335577UL
-
-/* modifying Link LED behaviour (used with SkGeLinkLED()) */
-#define SK_LNK_OFF LED_OFF
-#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
-#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON)
-#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
-#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
-
-/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
-#define SK_LED_OFF LED_OFF
-#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
-#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
-
-/* addressing LED Registers in SkGeXmitLED() */
-#define XMIT_LED_INI 0
-#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI)
-#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI)
-#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI)
-
-/* parameter 'Mode' when calling SkGeXmitLED() */
-#define SK_LED_DIS 0
-#define SK_LED_ENA 1
-#define SK_LED_TST 2
-
-/* Counter and Timer constants, for a host clock of 62.5 MHz */
-#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */
-#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */
-
-#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */
-
-#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */
- /* 215 ms at 78.12 MHz */
-
-#define SK_FACT_62 100 /* is given in percent */
-#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */
-#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */
-
-/* Timeout values */
-#define SK_MAC_TO_53 72 /* MAC arbiter timeout */
-#define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */
-#define SK_PKT_TO_MAX 0xffff /* Maximum value */
-#define SK_RI_TO_53 36 /* RAM interface timeout */
-
-#define SK_PHY_ACC_TO 600000 /* PHY access timeout */
-
-/* RAM Buffer High Pause Threshold values */
-#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */
-#define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */
-#define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */
-
-#ifndef SK_BMU_RX_WM
-#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */
-#endif
-#ifndef SK_BMU_TX_WM
-#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */
-#endif
-
-/* XMAC II Rx High Watermark */
-#define SK_XM_RX_HI_WM 0x05aa /* 1450 */
-
-/* XMAC II Tx Threshold */
-#define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */
-#define SK_XM_THR_SL 0x01fb /* .. for single link adapters */
-#define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */
-#define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */
-
-/* values for GIPortUsage */
-#define SK_RED_LINK 1 /* redundant link usage */
-#define SK_MUL_LINK 2 /* multiple link usage */
-#define SK_JUMBO_LINK 3 /* driver uses jumbo frames */
-
-/* Minimum RAM Buffer Rx Queue Size */
-#define SK_MIN_RXQ_SIZE 16 /* 16 kB */
-
-/* Minimum RAM Buffer Tx Queue Size */
-#define SK_MIN_TXQ_SIZE 16 /* 16 kB */
-
-/* Queue Size units */
-#define QZ_UNITS 0x7
-#define QZ_STEP 8
-
-/* Percentage of queue size from whole memory */
-/* 80 % for receive */
-#define RAM_QUOTA_RX 80L
-/* 0% for sync transfer */
-#define RAM_QUOTA_SYNC 0L
-/* the rest (20%) is taken for async transfer */
-
-/* Get the rounded queue size in Bytes in 8k steps */
-#define ROUND_QUEUE_SIZE(SizeInBytes) \
- ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
- ~(QZ_STEP-1))
-
-/* Get the rounded queue size in KBytes in 8k steps */
-#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
- ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
-
-/* Types of RAM Buffer Queues */
-#define SK_RX_SRAM_Q 1 /* small receive queue */
-#define SK_RX_BRAM_Q 2 /* big receive queue */
-#define SK_TX_RAM_Q 3 /* small or big transmit queue */
-
-/* parameter 'Dir' when calling SkGeStopPort() */
-#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */
-#define SK_STOP_RX 2 /* Stops the receive path */
-#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */
-
-/* parameter 'RstMode' when calling SkGeStopPort() */
-#define SK_SOFT_RST 1 /* perform a software reset */
-#define SK_HARD_RST 2 /* perform a hardware reset */
-
-/* Init Levels */
-#define SK_INIT_DATA 0 /* Init level 0: init data structures */
-#define SK_INIT_IO 1 /* Init level 1: init with IOs */
-#define SK_INIT_RUN 2 /* Init level 2: init for run time */
-
-/* Link Mode Parameter */
-#define SK_LMODE_HALF 1 /* Half Duplex Mode */
-#define SK_LMODE_FULL 2 /* Full Duplex Mode */
-#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */
-#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */
-#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */
-#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */
-#define SK_LMODE_INDETERMINATED 7 /* indeterminated */
-
-/* Auto-negotiation timeout in 100ms granularity */
-#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */
-
-/* Auto-negotiation error codes */
-#define SK_AND_OK 0 /* no error */
-#define SK_AND_OTHER 1 /* other error than below */
-#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */
-
-
-/* Link Speed Capabilities */
-#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */
-#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */
-#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */
-#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */
-#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
-
-/* Link Speed Parameter */
-#define SK_LSPEED_AUTO 1 /* Automatic resolution */
-#define SK_LSPEED_10MBPS 2 /* 10 Mbps */
-#define SK_LSPEED_100MBPS 3 /* 100 Mbps */
-#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */
-#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */
-
-/* Link Speed Current State */
-#define SK_LSPEED_STAT_UNKNOWN 1
-#define SK_LSPEED_STAT_10MBPS 2
-#define SK_LSPEED_STAT_100MBPS 3
-#define SK_LSPEED_STAT_1000MBPS 4
-#define SK_LSPEED_STAT_INDETERMINATED 5
-
-
-/* Link Capability Parameter */
-#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */
-#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */
-#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */
-#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */
-#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
-
-/* Link Mode Current State */
-#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */
-#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */
-#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */
-#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */
-#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */
-#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
-
-/* Flow Control Mode Parameter (and capabilities) */
-#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */
-#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */
-#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */
-#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or
- * just the remote station may send PAUSE
- */
-#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */
-
-/* Flow Control Status Parameter */
-#define SK_FLOW_STAT_NONE 1 /* No Flow Control */
-#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */
-#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */
-#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */
-#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */
-
-/* Master/Slave Mode Capabilities */
-#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */
-#define SK_MS_CAP_MASTER (1<<1) /* This station is master */
-#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */
-#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */
-
-/* Set Master/Slave Mode Parameter (and capabilities) */
-#define SK_MS_MODE_AUTO 1 /* Automatic resolution */
-#define SK_MS_MODE_MASTER 2 /* This station is master */
-#define SK_MS_MODE_SLAVE 3 /* This station is slave */
-#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */
-
-/* Master/Slave Status Parameter */
-#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */
-#define SK_MS_STAT_MASTER 2 /* This station is master */
-#define SK_MS_STAT_SLAVE 3 /* This station is slave */
-#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */
-#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */
-
-/* parameter 'Mode' when calling SkXmSetRxCmd() */
-#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */
-#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */
-#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */
-#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */
-#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */
-#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */
-#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */
-#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */
-#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */
-#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */
-
-/* parameter 'Para' when calling SkMacSetRxTxEn() */
-#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */
-#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */
-#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */
-#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */
-#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */
-#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */
-
-/* States of PState */
-#define SK_PRT_RESET 0 /* the port is reset */
-#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */
-#define SK_PRT_INIT 2 /* the port is initialized */
-#define SK_PRT_RUN 3 /* the port has an active link */
-
-/* PHY power down modes */
-#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */
-#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */
-#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */
-#define PHY_PM_ENERGY_DETECT 3 /* energy detect */
-#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */
-
-/* Default receive frame limit for Workaround of XMAC Errata */
-#define SK_DEF_RX_WA_LIM SK_CONSTU64(100)
-
-/* values for GILedBlinkCtrl (LED Blink Control) */
-#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */
-#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */
-#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */
-
-/* Link Partner Status */
-#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */
-#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */
-#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */
-
-/* Maximum Restarts before restart is ignored (3Com WA) */
-#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */
-
-/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
-#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */
-
-/* structures *****************************************************************/
-
-/*
- * MAC specific functions
- */
-typedef struct s_GeMacFunc {
- int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
- int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
- SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
- int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
- int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
- SK_U16 IStatus, SK_U64 SK_FAR *pVal);
-} SK_GEMACFUNC;
-
-/*
- * Port Structure
- */
-typedef struct s_GePort {
-#ifndef SK_DIAG
- SK_TIMER PWaTimer; /* Workaround Timer */
- SK_TIMER HalfDupChkTimer;
-#endif /* SK_DIAG */
- SK_U32 PPrevShorts; /* Previous Short Counter checking */
- SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */
- SK_U64 PPrevRx; /* Previous RxOk Counter checking */
- SK_U64 PRxLim; /* Previous RxOk Counter checking */
- SK_U64 LastOctets; /* For half duplex hang check */
- int PLinkResCt; /* Link Restart Counter */
- int PAutoNegTimeOut;/* Auto-negotiation timeout current value */
- int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */
- int PRxQSize; /* Port Rx Queue Size in kB */
- int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
- int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */
- SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */
- SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
- SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */
- SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
- SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */
- SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
- SK_U32 PRxOverCnt; /* Receive Overflow Counter */
- int PRxQOff; /* Rx Queue Address Offset */
- int PXsQOff; /* Synchronous Tx Queue Address Offset */
- int PXaQOff; /* Asynchronous Tx Queue Address Offset */
- int PhyType; /* PHY used on this port */
- int PState; /* Port status (reset, stop, init, run) */
- SK_U16 PhyId1; /* PHY Id1 on this port */
- SK_U16 PhyAddr; /* MDIO/MDC PHY address */
- SK_U16 PIsave; /* Saved Interrupt status word */
- SK_U16 PSsave; /* Saved PHY status word */
- SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */
- SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */
- SK_BOOL PLinkBroken; /* Is Link broken ? */
- SK_BOOL PCheckPar; /* Do we check for parity errors ? */
- SK_BOOL HalfDupTimerActive;
- SK_U8 PLinkCap; /* Link Capabilities */
- SK_U8 PLinkModeConf; /* Link Mode configured */
- SK_U8 PLinkMode; /* Link Mode currently used */
- SK_U8 PLinkModeStatus;/* Link Mode Status */
- SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */
- SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */
- SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
- SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */
- SK_U8 PFlowCtrlMode; /* Flow Control Mode */
- SK_U8 PFlowCtrlStatus;/* Flow Control Status */
- SK_U8 PMSCap; /* Master/Slave Capabilities */
- SK_U8 PMSMode; /* Master/Slave Mode */
- SK_U8 PMSStatus; /* Master/Slave Status */
- SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */
- SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */
- SK_U8 PCableLen; /* Cable Length */
- SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */
- SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
- SK_U8 PPhyPowerState; /* PHY current power state */
- int PMacColThres; /* MAC Collision Threshold */
- int PMacJamLen; /* MAC Jam length */
- int PMacJamIpgVal; /* MAC Jam IPG */
- int PMacJamIpgData; /* MAC IPG Jam to Data */
- int PMacIpgData; /* MAC Data IPG */
- SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */
-} SK_GEPORT;
-
-/*
- * Gigabit Ethernet Initialization Struct
- * (has to be included in the adapter context)
- */
-typedef struct s_GeInit {
- int GIChipId; /* Chip Identification Number */
- int GIChipRev; /* Chip Revision Number */
- SK_U8 GIPciHwRev; /* PCI HW Revision Number */
- SK_BOOL GIGenesis; /* Genesis adapter ? */
- SK_BOOL GIYukon; /* YUKON-A1/Bx chip */
- SK_BOOL GIYukonLite; /* YUKON-Lite chip */
- SK_BOOL GICopperType; /* Copper Type adapter ? */
- SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */
- SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */
- SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */
- SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */
- SK_U16 GILedBlinkCtrl; /* LED Blink Control */
- int GIMacsFound; /* Number of MACs found on this adapter */
- int GIMacType; /* MAC Type used on this adapter */
- int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
- int GIPortUsage; /* Driver Port Usage */
- int GILevel; /* Initialization Level completed */
- int GIRamSize; /* The RAM size of the adapter in kB */
- int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */
- SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
- SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
- SK_U32 GIValIrqMask; /* Value for Interrupt Mask */
- SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
- SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */
- SK_GEMACFUNC GIFunc; /* MAC depedent functions */
-} SK_GEINIT;
-
-/*
- * Error numbers and messages for skxmac2.c and skgeinit.c
- */
-#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT)
-#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters"
-#define SKERR_HWI_E002 (SKERR_HWI_E001+1)
-#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing"
-#define SKERR_HWI_E003 (SKERR_HWI_E002+1)
-#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level"
-#define SKERR_HWI_E004 (SKERR_HWI_E003+1)
-#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured"
-#define SKERR_HWI_E005 (SKERR_HWI_E004+1)
-#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports"
-#define SKERR_HWI_E006 (SKERR_HWI_E005+1)
-#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state"
-#define SKERR_HWI_E007 (SKERR_HWI_E006+1)
-#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode"
-#define SKERR_HWI_E008 (SKERR_HWI_E007+1)
-#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode"
-#define SKERR_HWI_E009 (SKERR_HWI_E008+1)
-#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero"
-#define SKERR_HWI_E010 (SKERR_HWI_E009+1)
-#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters"
-#define SKERR_HWI_E011 (SKERR_HWI_E010+1)
-#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small"
-#define SKERR_HWI_E012 (SKERR_HWI_E011+1)
-#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified"
-#define SKERR_HWI_E013 (SKERR_HWI_E012+1)
-#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue"
-#define SKERR_HWI_E014 (SKERR_HWI_E013+1)
-#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified"
-#define SKERR_HWI_E015 (SKERR_HWI_E014+1)
-#define SKERR_HWI_E015MSG "Illegal Link mode parameter"
-#define SKERR_HWI_E016 (SKERR_HWI_E015+1)
-#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter"
-#define SKERR_HWI_E017 (SKERR_HWI_E016+1)
-#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal"
-#define SKERR_HWI_E018 (SKERR_HWI_E017+1)
-#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)"
-#define SKERR_HWI_E019 (SKERR_HWI_E018+1)
-#define SKERR_HWI_E019MSG "Illegal Speed parameter"
-#define SKERR_HWI_E020 (SKERR_HWI_E019+1)
-#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter"
-#define SKERR_HWI_E021 (SKERR_HWI_E020+1)
-#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter"
-#define SKERR_HWI_E022 (SKERR_HWI_E021+1)
-#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address"
-#define SKERR_HWI_E023 (SKERR_HWI_E022+1)
-#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small"
-#define SKERR_HWI_E024 (SKERR_HWI_E023+1)
-#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)"
-#define SKERR_HWI_E025 (SKERR_HWI_E024+1)
-#define SKERR_HWI_E025MSG ""
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_KR_PROTO
-
-/*
- * public functions in skgeinit.c
- */
-extern void SkGePollTxD(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL PollTxD);
-
-extern void SkGeYellowLED(
- SK_AC *pAC,
- SK_IOC IoC,
- int State);
-
-extern int SkGeCfgSync(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_U32 IntTime,
- SK_U32 LimCount,
- int SyncMode);
-
-extern void SkGeLoadLnkSyncCnt(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_U32 CntVal);
-
-extern void SkGeStopPort(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Dir,
- int RstMode);
-
-extern int SkGeInit(
- SK_AC *pAC,
- SK_IOC IoC,
- int Level);
-
-extern void SkGeDeInit(
- SK_AC *pAC,
- SK_IOC IoC);
-
-extern int SkGeInitPort(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkGeXmitLED(
- SK_AC *pAC,
- SK_IOC IoC,
- int Led,
- int Mode);
-
-extern int SkGeInitAssignRamToQueues(
- SK_AC *pAC,
- int ActivePort,
- SK_BOOL DualNet);
-
-/*
- * public functions in skxmac2.c
- */
-extern void SkMacRxTxDisable(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacSoftRst(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacHardRst(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkXmInitMac(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkGmInitMac(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacInitPhy(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL DoLoop);
-
-extern void SkMacIrqDisable(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacFlushTxFifo(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacIrq(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern int SkMacAutoNegDone(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacAutoNegLipaPhy(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_U16 IStatus);
-
-extern int SkMacRxTxEnable(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port);
-
-extern void SkMacPromiscMode(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL Enable);
-
-extern void SkMacHashing(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL Enable);
-
-extern void SkXmPhyRead(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Addr,
- SK_U16 SK_FAR *pVal);
-
-extern void SkXmPhyWrite(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Addr,
- SK_U16 Val);
-
-extern void SkGmPhyRead(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Addr,
- SK_U16 SK_FAR *pVal);
-
-extern void SkGmPhyWrite(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Addr,
- SK_U16 Val);
-
-extern void SkXmClrExactAddr(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int StartNum,
- int StopNum);
-
-extern void SkXmAutoNegLipaXmac(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_U16 IStatus);
-
-extern int SkXmUpdateStats(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port);
-
-extern int SkGmUpdateStats(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port);
-
-extern int SkXmMacStatistic(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port,
- SK_U16 StatAddr,
- SK_U32 SK_FAR *pVal);
-
-extern int SkGmMacStatistic(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port,
- SK_U16 StatAddr,
- SK_U32 SK_FAR *pVal);
-
-extern int SkXmResetCounter(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port);
-
-extern int SkGmResetCounter(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port);
-
-extern int SkXmOverflowStatus(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port,
- SK_U16 IStatus,
- SK_U64 SK_FAR *pStatus);
-
-extern int SkGmOverflowStatus(
- SK_AC *pAC,
- SK_IOC IoC,
- unsigned int Port,
- SK_U16 MacStatus,
- SK_U64 SK_FAR *pStatus);
-
-extern int SkGmCableDiagStatus(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL StartTest);
-
-#ifdef SK_DIAG
-extern void SkGePhyRead(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Addr,
- SK_U16 *pVal);
-
-extern void SkGePhyWrite(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Addr,
- SK_U16 Val);
-
-extern void SkMacSetRxCmd(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- int Mode);
-extern void SkMacCrcGener(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL Enable);
-extern void SkMacTimeStamp(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL Enable);
-extern void SkXmSendCont(
- SK_AC *pAC,
- SK_IOC IoC,
- int Port,
- SK_BOOL Enable);
-#endif /* SK_DIAG */
-
-#else /* SK_KR_PROTO */
-
-/*
- * public functions in skgeinit.c
- */
-extern void SkGePollTxD();
-extern void SkGeYellowLED();
-extern int SkGeCfgSync();
-extern void SkGeLoadLnkSyncCnt();
-extern void SkGeStopPort();
-extern int SkGeInit();
-extern void SkGeDeInit();
-extern int SkGeInitPort();
-extern void SkGeXmitLED();
-extern int SkGeInitAssignRamToQueues();
-
-/*
- * public functions in skxmac2.c
- */
-extern void SkMacRxTxDisable();
-extern void SkMacSoftRst();
-extern void SkMacHardRst();
-extern void SkMacInitPhy();
-extern int SkMacRxTxEnable();
-extern void SkMacPromiscMode();
-extern void SkMacHashing();
-extern void SkMacIrqDisable();
-extern void SkMacFlushTxFifo();
-extern void SkMacIrq();
-extern int SkMacAutoNegDone();
-extern void SkMacAutoNegLipaPhy();
-extern void SkXmInitMac();
-extern void SkXmPhyRead();
-extern void SkXmPhyWrite();
-extern void SkGmInitMac();
-extern void SkGmPhyRead();
-extern void SkGmPhyWrite();
-extern void SkXmClrExactAddr();
-extern void SkXmAutoNegLipaXmac();
-extern int SkXmUpdateStats();
-extern int SkGmUpdateStats();
-extern int SkXmMacStatistic();
-extern int SkGmMacStatistic();
-extern int SkXmResetCounter();
-extern int SkGmResetCounter();
-extern int SkXmOverflowStatus();
-extern int SkGmOverflowStatus();
-extern int SkGmCableDiagStatus();
-
-#ifdef SK_DIAG
-extern void SkGePhyRead();
-extern void SkGePhyWrite();
-extern void SkMacSetRxCmd();
-extern void SkMacCrcGener();
-extern void SkMacTimeStamp();
-extern void SkXmSendCont();
-#endif /* SK_DIAG */
-
-#endif /* SK_KR_PROTO */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
deleted file mode 100644
index ddd304f1a48b..000000000000
--- a/drivers/net/sk98lin/h/skgepnm2.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/*****************************************************************************
- *
- * Name: skgepnm2.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.36 $
- * Date: $Date: 2003/05/23 12:45:13 $
- * Purpose: Defines for Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _SKGEPNM2_H_
-#define _SKGEPNM2_H_
-
-/*
- * General definitions
- */
-#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */
-#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */
-
-#define SK_PNMI_BUS_PCI 1 /* PCI bus*/
-
-/*
- * Actions
- */
-#define SK_PNMI_ACT_IDLE 1
-#define SK_PNMI_ACT_RESET 2
-#define SK_PNMI_ACT_SELFTEST 3
-#define SK_PNMI_ACT_RESETCNT 4
-
-/*
- * VPD releated defines
- */
-
-#define SK_PNMI_VPD_RW 1
-#define SK_PNMI_VPD_RO 2
-
-#define SK_PNMI_VPD_OK 0
-#define SK_PNMI_VPD_NOTFOUND 1
-#define SK_PNMI_VPD_CUT 2
-#define SK_PNMI_VPD_TIMEOUT 3
-#define SK_PNMI_VPD_FULL 4
-#define SK_PNMI_VPD_NOWRITE 5
-#define SK_PNMI_VPD_FATAL 6
-
-#define SK_PNMI_VPD_IGNORE 0
-#define SK_PNMI_VPD_CREATE 1
-#define SK_PNMI_VPD_DELETE 2
-
-
-/*
- * RLMT related defines
- */
-#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */
-
-
-/*
- * VCT internal status values
- */
-#define SK_PNMI_VCT_PENDING 32
-#define SK_PNMI_VCT_TEST_DONE 64
-#define SK_PNMI_VCT_LINK 128
-
-/*
- * Internal table definitions
- */
-#define SK_PNMI_GET 0
-#define SK_PNMI_PRESET 1
-#define SK_PNMI_SET 2
-
-#define SK_PNMI_RO 0
-#define SK_PNMI_RW 1
-#define SK_PNMI_WO 2
-
-typedef struct s_OidTabEntry {
- SK_U32 Id;
- SK_U32 InstanceNo;
- unsigned int StructSize;
- unsigned int Offset;
- int Access;
- int (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
- SK_U32 Id, char* pBuf, unsigned int* pLen,
- SK_U32 Instance, unsigned int TableIndex,
- SK_U32 NetNumber);
- SK_U16 Param;
-} SK_PNMI_TAB_ENTRY;
-
-
-/*
- * Trap lengths
- */
-#define SK_PNMI_TRAP_SIMPLE_LEN 17
-#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46
-#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23
-#define SK_PNMI_TRAP_RLMT_PORT_LEN 23
-
-/*
- * Number of MAC types supported
- */
-#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1)
-
-/*
- * MAC statistic data list (overall set for MAC types used)
- */
-enum SK_MACSTATS {
- SK_PNMI_HTX = 0,
- SK_PNMI_HTX_OCTET,
- SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET,
- SK_PNMI_HTX_OCTETLOW,
- SK_PNMI_HTX_BROADCAST,
- SK_PNMI_HTX_MULTICAST,
- SK_PNMI_HTX_UNICAST,
- SK_PNMI_HTX_BURST,
- SK_PNMI_HTX_PMACC,
- SK_PNMI_HTX_MACC,
- SK_PNMI_HTX_COL,
- SK_PNMI_HTX_SINGLE_COL,
- SK_PNMI_HTX_MULTI_COL,
- SK_PNMI_HTX_EXCESS_COL,
- SK_PNMI_HTX_LATE_COL,
- SK_PNMI_HTX_DEFFERAL,
- SK_PNMI_HTX_EXCESS_DEF,
- SK_PNMI_HTX_UNDERRUN,
- SK_PNMI_HTX_CARRIER,
- SK_PNMI_HTX_UTILUNDER,
- SK_PNMI_HTX_UTILOVER,
- SK_PNMI_HTX_64,
- SK_PNMI_HTX_127,
- SK_PNMI_HTX_255,
- SK_PNMI_HTX_511,
- SK_PNMI_HTX_1023,
- SK_PNMI_HTX_MAX,
- SK_PNMI_HTX_LONGFRAMES,
- SK_PNMI_HTX_SYNC,
- SK_PNMI_HTX_SYNC_OCTET,
- SK_PNMI_HTX_RESERVED,
-
- SK_PNMI_HRX,
- SK_PNMI_HRX_OCTET,
- SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET,
- SK_PNMI_HRX_OCTETLOW,
- SK_PNMI_HRX_BADOCTET,
- SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
- SK_PNMI_HRX_BADOCTETLOW,
- SK_PNMI_HRX_BROADCAST,
- SK_PNMI_HRX_MULTICAST,
- SK_PNMI_HRX_UNICAST,
- SK_PNMI_HRX_PMACC,
- SK_PNMI_HRX_MACC,
- SK_PNMI_HRX_PMACC_ERR,
- SK_PNMI_HRX_MACC_UNKWN,
- SK_PNMI_HRX_BURST,
- SK_PNMI_HRX_MISSED,
- SK_PNMI_HRX_FRAMING,
- SK_PNMI_HRX_UNDERSIZE,
- SK_PNMI_HRX_OVERFLOW,
- SK_PNMI_HRX_JABBER,
- SK_PNMI_HRX_CARRIER,
- SK_PNMI_HRX_IRLENGTH,
- SK_PNMI_HRX_SYMBOL,
- SK_PNMI_HRX_SHORTS,
- SK_PNMI_HRX_RUNT,
- SK_PNMI_HRX_TOO_LONG,
- SK_PNMI_HRX_FCS,
- SK_PNMI_HRX_CEXT,
- SK_PNMI_HRX_UTILUNDER,
- SK_PNMI_HRX_UTILOVER,
- SK_PNMI_HRX_64,
- SK_PNMI_HRX_127,
- SK_PNMI_HRX_255,
- SK_PNMI_HRX_511,
- SK_PNMI_HRX_1023,
- SK_PNMI_HRX_MAX,
- SK_PNMI_HRX_LONGFRAMES,
-
- SK_PNMI_HRX_RESERVED,
-
- SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
-};
-
-/*
- * MAC specific data
- */
-typedef struct s_PnmiStatAddr {
- SK_U16 Reg; /* MAC register containing the value */
- SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/
-} SK_PNMI_STATADDR;
-
-
-/*
- * SK_PNMI_STRUCT_DATA copy offset evaluation macros
- */
-#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
-#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
-#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
-#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
-#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
-#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
-#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
-#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
-
-#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \
- Val32 = (s); \
- pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
- &(((SK_PNMI_STRUCT_DATA *)0)-> \
- ReturnStatus.ErrorStatus)); \
- SK_PNMI_STORE_U32(pVal, Val32); \
- Val32 = (o); \
- pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
- &(((SK_PNMI_STRUCT_DATA *)0)-> \
- ReturnStatus.ErrorOffset)); \
- SK_PNMI_STORE_U32(pVal, Val32);}
-
-/*
- * Time macros
- */
-#ifndef SK_PNMI_HUNDREDS_SEC
-#if SK_TICKS_PER_SEC == 100
-#define SK_PNMI_HUNDREDS_SEC(t) (t)
-#else
-#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC))
-#endif /* !SK_TICKS_PER_SEC */
-#endif /* !SK_PNMI_HUNDREDS_SEC */
-
-/*
- * Macros to work around alignment problems
- */
-#ifndef SK_PNMI_STORE_U16
-#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
- *((char *)(p) + 1) = \
- *(((char *)&(v)) + 1);}
-#endif
-
-#ifndef SK_PNMI_STORE_U32
-#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
- *((char *)(p) + 1) = \
- *(((char *)&(v)) + 1); \
- *((char *)(p) + 2) = \
- *(((char *)&(v)) + 2); \
- *((char *)(p) + 3) = \
- *(((char *)&(v)) + 3);}
-#endif
-
-#ifndef SK_PNMI_STORE_U64
-#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
- *((char *)(p) + 1) = \
- *(((char *)&(v)) + 1); \
- *((char *)(p) + 2) = \
- *(((char *)&(v)) + 2); \
- *((char *)(p) + 3) = \
- *(((char *)&(v)) + 3); \
- *((char *)(p) + 4) = \
- *(((char *)&(v)) + 4); \
- *((char *)(p) + 5) = \
- *(((char *)&(v)) + 5); \
- *((char *)(p) + 6) = \
- *(((char *)&(v)) + 6); \
- *((char *)(p) + 7) = \
- *(((char *)&(v)) + 7);}
-#endif
-
-#ifndef SK_PNMI_READ_U16
-#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \
- *(((char *)&(v)) + 1) = \
- *((char *)(p) + 1);}
-#endif
-
-#ifndef SK_PNMI_READ_U32
-#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \
- *(((char *)&(v)) + 1) = \
- *((char *)(p) + 1); \
- *(((char *)&(v)) + 2) = \
- *((char *)(p) + 2); \
- *(((char *)&(v)) + 3) = \
- *((char *)(p) + 3);}
-#endif
-
-#ifndef SK_PNMI_READ_U64
-#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \
- *(((char *)&(v)) + 1) = \
- *((char *)(p) + 1); \
- *(((char *)&(v)) + 2) = \
- *((char *)(p) + 2); \
- *(((char *)&(v)) + 3) = \
- *((char *)(p) + 3); \
- *(((char *)&(v)) + 4) = \
- *((char *)(p) + 4); \
- *(((char *)&(v)) + 5) = \
- *((char *)(p) + 5); \
- *(((char *)&(v)) + 6) = \
- *((char *)(p) + 6); \
- *(((char *)&(v)) + 7) = \
- *((char *)(p) + 7);}
-#endif
-
-/*
- * Macros for Debug
- */
-#ifdef DEBUG
-
-#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
- pAC->Pnmi.RlmtUpdatedFlag > 0 || \
- pAC->Pnmi.SirqUpdatedFlag > 0) { \
- SK_DBG_MSG(pAC, \
- SK_DBGMOD_PNMI, \
- SK_DBGCAT_CTRL, \
- ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
- vSt, \
- pAC->Pnmi.MacUpdatedFlag, \
- pAC->Pnmi.RlmtUpdatedFlag, \
- pAC->Pnmi.SirqUpdatedFlag))}}
-
-#else /* !DEBUG */
-
-#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */
-
-#endif /* !DEBUG */
-
-#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
deleted file mode 100644
index 1ed214ccb253..000000000000
--- a/drivers/net/sk98lin/h/skgepnmi.h
+++ /dev/null
@@ -1,962 +0,0 @@
-/*****************************************************************************
- *
- * Name: skgepnmi.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.62 $
- * Date: $Date: 2003/08/15 12:31:52 $
- * Purpose: Defines for Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _SKGEPNMI_H_
-#define _SKGEPNMI_H_
-
-/*
- * Include dependencies
- */
-#include "h/sktypes.h"
-#include "h/skerror.h"
-#include "h/sktimer.h"
-#include "h/ski2c.h"
-#include "h/skaddr.h"
-#include "h/skrlmt.h"
-#include "h/skvpd.h"
-
-/*
- * Management Database Version
- */
-#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */
-
-
-/*
- * Event definitions
- */
-#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */
-#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */
-#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */
-#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */
-#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */
-#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */
-#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */
-#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */
-
-#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */
-#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */
-#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */
-#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */
-#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */
-#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets
- 1 = single net; 2 = dual net */
-#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */
-
-
-/*
- * Return values
- */
-#define SK_PNMI_ERR_OK 0
-#define SK_PNMI_ERR_GENERAL 1
-#define SK_PNMI_ERR_TOO_SHORT 2
-#define SK_PNMI_ERR_BAD_VALUE 3
-#define SK_PNMI_ERR_READ_ONLY 4
-#define SK_PNMI_ERR_UNKNOWN_OID 5
-#define SK_PNMI_ERR_UNKNOWN_INST 6
-#define SK_PNMI_ERR_UNKNOWN_NET 7
-#define SK_PNMI_ERR_NOT_SUPPORTED 10
-
-
-/*
- * Return values of driver reset function SK_DRIVER_RESET() and
- * driver event function SK_DRIVER_EVENT()
- */
-#define SK_PNMI_ERR_OK 0
-#define SK_PNMI_ERR_FAIL 1
-
-
-/*
- * Return values of driver test function SK_DRIVER_SELFTEST()
- */
-#define SK_PNMI_TST_UNKNOWN (1 << 0)
-#define SK_PNMI_TST_TRANCEIVER (1 << 1)
-#define SK_PNMI_TST_ASIC (1 << 2)
-#define SK_PNMI_TST_SENSOR (1 << 3)
-#define SK_PNMI_TST_POWERMGMT (1 << 4)
-#define SK_PNMI_TST_PCI (1 << 5)
-#define SK_PNMI_TST_MAC (1 << 6)
-
-
-/*
- * RLMT specific definitions
- */
-#define SK_PNMI_RLMT_STATUS_STANDBY 1
-#define SK_PNMI_RLMT_STATUS_ACTIVE 2
-#define SK_PNMI_RLMT_STATUS_ERROR 3
-
-#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1
-#define SK_PNMI_RLMT_LSTAT_AUTONEG 2
-#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3
-#define SK_PNMI_RLMT_LSTAT_LOG_UP 4
-#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
-
-#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK)
-#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK)
-#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG)
-/* #define SK_PNMI_RLMT_MODE_CHK_EX */
-
-/*
- * OID definition
- */
-#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
-
-#define OID_GEN_XMIT_OK 0x00020101
-#define OID_GEN_RCV_OK 0x00020102
-#define OID_GEN_XMIT_ERROR 0x00020103
-#define OID_GEN_RCV_ERROR 0x00020104
-#define OID_GEN_RCV_NO_BUFFER 0x00020105
-
-/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
-#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
-/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */
-#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
-/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */
-#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
-/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */
-#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
-/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
-#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
-/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
-#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
-#define OID_GEN_RCV_CRC_ERROR 0x0002020D
-#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
-
-#define OID_802_3_PERMANENT_ADDRESS 0x01010101
-#define OID_802_3_CURRENT_ADDRESS 0x01010102
-/* #define OID_802_3_MULTICAST_LIST 0x01010103 */
-/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
-/* #define OID_802_3_MAC_OPTIONS 0x01010105 */
-
-#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
-#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
-#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
-#define OID_802_3_XMIT_DEFERRED 0x01020201
-#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
-#define OID_802_3_RCV_OVERRUN 0x01020203
-#define OID_802_3_XMIT_UNDERRUN 0x01020204
-#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
-#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
-
-/*
- * PnP and PM OIDs
- */
-#ifdef SK_POWER_MGMT
-#define OID_PNP_CAPABILITIES 0xFD010100
-#define OID_PNP_SET_POWER 0xFD010101
-#define OID_PNP_QUERY_POWER 0xFD010102
-#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
-#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
-#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
-#endif /* SK_POWER_MGMT */
-
-#endif /* _NDIS_ */
-
-#define OID_SKGE_MDB_VERSION 0xFF010100
-#define OID_SKGE_SUPPORTED_LIST 0xFF010101
-#define OID_SKGE_VPD_FREE_BYTES 0xFF010102
-#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103
-#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104
-#define OID_SKGE_VPD_KEY 0xFF010105
-#define OID_SKGE_VPD_VALUE 0xFF010106
-#define OID_SKGE_VPD_ACCESS 0xFF010107
-#define OID_SKGE_VPD_ACTION 0xFF010108
-
-#define OID_SKGE_PORT_NUMBER 0xFF010110
-#define OID_SKGE_DEVICE_TYPE 0xFF010111
-#define OID_SKGE_DRIVER_DESCR 0xFF010112
-#define OID_SKGE_DRIVER_VERSION 0xFF010113
-#define OID_SKGE_HW_DESCR 0xFF010114
-#define OID_SKGE_HW_VERSION 0xFF010115
-#define OID_SKGE_CHIPSET 0xFF010116
-#define OID_SKGE_ACTION 0xFF010117
-#define OID_SKGE_RESULT 0xFF010118
-#define OID_SKGE_BUS_TYPE 0xFF010119
-#define OID_SKGE_BUS_SPEED 0xFF01011A
-#define OID_SKGE_BUS_WIDTH 0xFF01011B
-/* 0xFF01011C unused */
-#define OID_SKGE_DIAG_ACTION 0xFF01011D
-#define OID_SKGE_DIAG_RESULT 0xFF01011E
-#define OID_SKGE_MTU 0xFF01011F
-#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120
-#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121
-#define OID_SKGE_PMD 0xFF010122
-#define OID_SKGE_CONNECTOR 0xFF010123
-#define OID_SKGE_LINK_CAP 0xFF010124
-#define OID_SKGE_LINK_MODE 0xFF010125
-#define OID_SKGE_LINK_MODE_STATUS 0xFF010126
-#define OID_SKGE_LINK_STATUS 0xFF010127
-#define OID_SKGE_FLOWCTRL_CAP 0xFF010128
-#define OID_SKGE_FLOWCTRL_MODE 0xFF010129
-#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A
-#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B
-#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C
-#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D
-#define OID_SKGE_MULTICAST_LIST 0xFF01012E
-#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
-
-#define OID_SKGE_TRAP 0xFF010130
-#define OID_SKGE_TRAP_NUMBER 0xFF010131
-
-#define OID_SKGE_RLMT_MODE 0xFF010140
-#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141
-#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142
-#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143
-#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160
-
-#define OID_SKGE_SPEED_CAP 0xFF010170
-#define OID_SKGE_SPEED_MODE 0xFF010171
-#define OID_SKGE_SPEED_STATUS 0xFF010172
-
-#define OID_SKGE_BOARDLEVEL 0xFF010180
-
-#define OID_SKGE_SENSOR_NUMBER 0xFF020100
-#define OID_SKGE_SENSOR_INDEX 0xFF020101
-#define OID_SKGE_SENSOR_DESCR 0xFF020102
-#define OID_SKGE_SENSOR_TYPE 0xFF020103
-#define OID_SKGE_SENSOR_VALUE 0xFF020104
-#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105
-#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106
-#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107
-#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108
-#define OID_SKGE_SENSOR_STATUS 0xFF020109
-#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A
-#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B
-#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C
-#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D
-
-#define OID_SKGE_CHKSM_NUMBER 0xFF020110
-#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111
-#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112
-#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113
-#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114
-#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115
-
-#define OID_SKGE_STAT_TX 0xFF020120
-#define OID_SKGE_STAT_TX_OCTETS 0xFF020121
-#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122
-#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123
-#define OID_SKGE_STAT_TX_UNICAST 0xFF020124
-#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125
-#define OID_SKGE_STAT_TX_BURST 0xFF020126
-#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127
-#define OID_SKGE_STAT_TX_FLOWC 0xFF020128
-#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129
-#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A
-#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B
-#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C
-#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D
-#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E
-#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F
-#define OID_SKGE_STAT_TX_CARRIER 0xFF020130
-/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */
-#define OID_SKGE_STAT_TX_64 0xFF020132
-#define OID_SKGE_STAT_TX_127 0xFF020133
-#define OID_SKGE_STAT_TX_255 0xFF020134
-#define OID_SKGE_STAT_TX_511 0xFF020135
-#define OID_SKGE_STAT_TX_1023 0xFF020136
-#define OID_SKGE_STAT_TX_MAX 0xFF020137
-#define OID_SKGE_STAT_TX_SYNC 0xFF020138
-#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139
-#define OID_SKGE_STAT_RX 0xFF02013A
-#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B
-#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C
-#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D
-#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E
-#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F
-#define OID_SKGE_STAT_RX_FLOWC 0xFF020140
-#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141
-#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142
-#define OID_SKGE_STAT_RX_BURST 0xFF020143
-#define OID_SKGE_STAT_RX_MISSED 0xFF020144
-#define OID_SKGE_STAT_RX_FRAMING 0xFF020145
-#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146
-#define OID_SKGE_STAT_RX_JABBER 0xFF020147
-#define OID_SKGE_STAT_RX_CARRIER 0xFF020148
-#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149
-#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A
-#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B
-#define OID_SKGE_STAT_RX_RUNT 0xFF02014C
-#define OID_SKGE_STAT_RX_CEXT 0xFF02014D
-#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E
-#define OID_SKGE_STAT_RX_FCS 0xFF02014F
-/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */
-#define OID_SKGE_STAT_RX_64 0xFF020151
-#define OID_SKGE_STAT_RX_127 0xFF020152
-#define OID_SKGE_STAT_RX_255 0xFF020153
-#define OID_SKGE_STAT_RX_511 0xFF020154
-#define OID_SKGE_STAT_RX_1023 0xFF020155
-#define OID_SKGE_STAT_RX_MAX 0xFF020156
-#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157
-
-#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160
-#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161
-#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162
-#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163
-
-#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164
-#define OID_SKGE_RLMT_STATUS 0xFF020165
-#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166
-#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167
-#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168
-#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169
-
-#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150
-#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151
-#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152
-#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153
-#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154
-#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155
-
-#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170
-#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171
-#define OID_SKGE_TX_RETRY 0xFF020172
-#define OID_SKGE_RX_INTR_CTS 0xFF020173
-#define OID_SKGE_TX_INTR_CTS 0xFF020174
-#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175
-#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176
-#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177
-#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178
-#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179
-#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A
-#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B
-#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C
-#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D
-#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E
-#define OID_SKGE_SYSUPTIME 0xFF02017F
-
-#define OID_SKGE_ALL_DATA 0xFF020190
-
-/* Defines for VCT. */
-#define OID_SKGE_VCT_GET 0xFF020200
-#define OID_SKGE_VCT_SET 0xFF020201
-#define OID_SKGE_VCT_STATUS 0xFF020202
-
-#ifdef SK_DIAG_SUPPORT
-/* Defines for driver DIAG mode. */
-#define OID_SKGE_DIAG_MODE 0xFF020204
-#endif /* SK_DIAG_SUPPORT */
-
-/* New OIDs */
-#define OID_SKGE_DRIVER_RELDATE 0xFF020210
-#define OID_SKGE_DRIVER_FILENAME 0xFF020211
-#define OID_SKGE_CHIPID 0xFF020212
-#define OID_SKGE_RAMSIZE 0xFF020213
-#define OID_SKGE_VAUXAVAIL 0xFF020214
-#define OID_SKGE_PHY_TYPE 0xFF020215
-#define OID_SKGE_PHY_LP_MODE 0xFF020216
-
-/* VCT struct to store a backup copy of VCT data after a port reset. */
-typedef struct s_PnmiVct {
- SK_U8 VctStatus;
- SK_U8 PCableLen;
- SK_U32 PMdiPairLen[4];
- SK_U8 PMdiPairSts[4];
-} SK_PNMI_VCT;
-
-
-/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
-#define SK_PNMI_VCT_NONE 0
-#define SK_PNMI_VCT_OLD_VCT_DATA 1
-#define SK_PNMI_VCT_NEW_VCT_DATA 2
-#define SK_PNMI_VCT_OLD_DSP_DATA 4
-#define SK_PNMI_VCT_NEW_DSP_DATA 8
-#define SK_PNMI_VCT_RUNNING 16
-
-
-/* VCT cable test status. */
-#define SK_PNMI_VCT_NORMAL_CABLE 0
-#define SK_PNMI_VCT_SHORT_CABLE 1
-#define SK_PNMI_VCT_OPEN_CABLE 2
-#define SK_PNMI_VCT_TEST_FAIL 3
-#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4
-
-#define OID_SKGE_TRAP_SEN_WAR_LOW 500
-#define OID_SKGE_TRAP_SEN_WAR_UPP 501
-#define OID_SKGE_TRAP_SEN_ERR_LOW 502
-#define OID_SKGE_TRAP_SEN_ERR_UPP 503
-#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520
-#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
-#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522
-#define OID_SKGE_TRAP_RLMT_PORT_UP 523
-#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524
-
-#ifdef SK_DIAG_SUPPORT
-/* Defines for driver DIAG mode. */
-#define SK_DIAG_ATTACHED 2
-#define SK_DIAG_RUNNING 1
-#define SK_DIAG_IDLE 0
-#endif /* SK_DIAG_SUPPORT */
-
-/*
- * Generic PNMI IOCTL subcommand definitions.
- */
-#define SK_GET_SINGLE_VAR 1
-#define SK_SET_SINGLE_VAR 2
-#define SK_PRESET_SINGLE_VAR 3
-#define SK_GET_FULL_MIB 4
-#define SK_SET_FULL_MIB 5
-#define SK_PRESET_FULL_MIB 6
-
-
-/*
- * Define error numbers and messages for syslog
- */
-#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1)
-#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID"
-#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2)
-#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys"
-#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3)
-#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID"
-#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4)
-#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action"
-#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5)
-#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver"
-#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6)
-#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command"
-#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7)
-#define SK_PNMI_ERR007MSG "General: Driver description not initialized"
-#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8)
-#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID"
-#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9)
-#define SK_PNMI_ERR009MSG "Addr: Unknown OID"
-#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10)
-#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID"
-#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11)
-#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long"
-#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12)
-#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID"
-#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13)
-#define SK_PNMI_ERR013MSG ""
-#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14)
-#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys"
-#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15)
-#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small"
-#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16)
-#define SK_PNMI_ERR016MSG "Vpd: Key string too long"
-#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17)
-#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer"
-#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18)
-#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid"
-#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19)
-#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long"
-#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21)
-#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long"
-#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22)
-#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before"
-#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23)
-#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action"
-#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24)
-#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action"
-#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25)
-#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry"
-#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26)
-#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD"
-#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27)
-#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry"
-#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28)
-#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry"
-#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29)
-#define SK_PNMI_ERR029MSG "General: Driver description string too long"
-#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30)
-#define SK_PNMI_ERR030MSG "General: Driver version not initialized"
-#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31)
-#define SK_PNMI_ERR031MSG "General: Driver version string too long"
-#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32)
-#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr"
-#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33)
-#define SK_PNMI_ERR033MSG "General: HW description string too long"
-#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34)
-#define SK_PNMI_ERR034MSG "General: Unknown OID"
-#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35)
-#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID"
-#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36)
-#define SK_PNMI_ERR036MSG ""
-#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37)
-#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
-#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38)
-#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
-#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39)
-#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID"
-#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40)
-#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID"
-#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41)
-#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID"
-#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42)
-#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
-#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43)
-#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
-#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44)
-#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
-#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45)
-#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
-#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46)
-#define SK_PNMI_ERR046MSG "Monitor: Unknown OID"
-#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47)
-#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0"
-#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48)
-#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0"
-#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49)
-#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
-#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50)
-#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!"
-#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51)
-#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious"
-#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52)
-#define SK_PNMI_ERR052MSG ""
-#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53)
-#define SK_PNMI_ERR053MSG "General: Driver release date not initialized"
-#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54)
-#define SK_PNMI_ERR054MSG "General: Driver release date string too long"
-#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55)
-#define SK_PNMI_ERR055MSG "General: Driver file name not initialized"
-#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56)
-#define SK_PNMI_ERR056MSG "General: Driver file name string too long"
-
-/*
- * Management counter macros called by the driver
- */
-#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \
- (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \
- (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \
- (char *)(v))
-
-#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \
- (char *)(v))
-
-#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
- { \
- (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
- if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
- (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
- } \
- }
-#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++)
-#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++)
-#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++)
-#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
-#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
-#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
- ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
-#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
- { \
- ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
- (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
- }
-#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
-
-#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
- { \
- if ((p) < SK_MAX_MACS) { \
- ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
- (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
- } \
- }
-
-#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
- { \
- if ((p) < SK_MAX_MACS) { \
- ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
- } \
- }
-
-#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
- { \
- if ((p) < SK_MAX_MACS) { \
- ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
- } \
- }
-
-#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
- { \
- if ((p) < SK_MAX_MACS) { \
- ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
- } \
- }
-
-/*
- * Conversion Macros
- */
-#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1)
-#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1)
-#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1)
-#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1)
-#define SK_PNMI_PORT_PHYS2INST(pAC,p) \
- (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
-#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2)
-
-/*
- * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
- */
-#define SK_PNMI_VPD_KEY_SIZE 5
-#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE)
-#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4)
-#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */
-
-#define SK_PNMI_MULTICAST_LISTLEN 64
-#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS)
-#define SK_PNMI_CHECKSUM_ENTRIES 3
-#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1)
-#define SK_PNMI_MONITOR_ENTRIES 20
-#define SK_PNMI_TRAP_ENTRIES 10
-#define SK_PNMI_TRAPLEN 128
-#define SK_PNMI_STRINGLEN1 80
-#define SK_PNMI_STRINGLEN2 25
-#define SK_PNMI_TRAP_QUEUE_LEN 512
-
-typedef struct s_PnmiVpd {
- char VpdKey[SK_PNMI_VPD_KEY_SIZE];
- char VpdValue[SK_PNMI_VPD_DATALEN];
- SK_U8 VpdAccess;
- SK_U8 VpdAction;
-} SK_PNMI_VPD;
-
-typedef struct s_PnmiSensor {
- SK_U8 SensorIndex;
- char SensorDescr[SK_PNMI_STRINGLEN2];
- SK_U8 SensorType;
- SK_U32 SensorValue;
- SK_U32 SensorWarningThresholdLow;
- SK_U32 SensorWarningThresholdHigh;
- SK_U32 SensorErrorThresholdLow;
- SK_U32 SensorErrorThresholdHigh;
- SK_U8 SensorStatus;
- SK_U64 SensorWarningCts;
- SK_U64 SensorErrorCts;
- SK_U64 SensorWarningTimestamp;
- SK_U64 SensorErrorTimestamp;
-} SK_PNMI_SENSOR;
-
-typedef struct s_PnmiChecksum {
- SK_U64 ChecksumRxOkCts;
- SK_U64 ChecksumRxUnableCts;
- SK_U64 ChecksumRxErrCts;
- SK_U64 ChecksumTxOkCts;
- SK_U64 ChecksumTxUnableCts;
-} SK_PNMI_CHECKSUM;
-
-typedef struct s_PnmiStat {
- SK_U64 StatTxOkCts;
- SK_U64 StatTxOctetsOkCts;
- SK_U64 StatTxBroadcastOkCts;
- SK_U64 StatTxMulticastOkCts;
- SK_U64 StatTxUnicastOkCts;
- SK_U64 StatTxLongFramesCts;
- SK_U64 StatTxBurstCts;
- SK_U64 StatTxPauseMacCtrlCts;
- SK_U64 StatTxMacCtrlCts;
- SK_U64 StatTxSingleCollisionCts;
- SK_U64 StatTxMultipleCollisionCts;
- SK_U64 StatTxExcessiveCollisionCts;
- SK_U64 StatTxLateCollisionCts;
- SK_U64 StatTxDeferralCts;
- SK_U64 StatTxExcessiveDeferralCts;
- SK_U64 StatTxFifoUnderrunCts;
- SK_U64 StatTxCarrierCts;
- SK_U64 Dummy1; /* StatTxUtilization */
- SK_U64 StatTx64Cts;
- SK_U64 StatTx127Cts;
- SK_U64 StatTx255Cts;
- SK_U64 StatTx511Cts;
- SK_U64 StatTx1023Cts;
- SK_U64 StatTxMaxCts;
- SK_U64 StatTxSyncCts;
- SK_U64 StatTxSyncOctetsCts;
- SK_U64 StatRxOkCts;
- SK_U64 StatRxOctetsOkCts;
- SK_U64 StatRxBroadcastOkCts;
- SK_U64 StatRxMulticastOkCts;
- SK_U64 StatRxUnicastOkCts;
- SK_U64 StatRxLongFramesCts;
- SK_U64 StatRxPauseMacCtrlCts;
- SK_U64 StatRxMacCtrlCts;
- SK_U64 StatRxPauseMacCtrlErrorCts;
- SK_U64 StatRxMacCtrlUnknownCts;
- SK_U64 StatRxBurstCts;
- SK_U64 StatRxMissedCts;
- SK_U64 StatRxFramingCts;
- SK_U64 StatRxFifoOverflowCts;
- SK_U64 StatRxJabberCts;
- SK_U64 StatRxCarrierCts;
- SK_U64 StatRxIRLengthCts;
- SK_U64 StatRxSymbolCts;
- SK_U64 StatRxShortsCts;
- SK_U64 StatRxRuntCts;
- SK_U64 StatRxCextCts;
- SK_U64 StatRxTooLongCts;
- SK_U64 StatRxFcsCts;
- SK_U64 Dummy2; /* StatRxUtilization */
- SK_U64 StatRx64Cts;
- SK_U64 StatRx127Cts;
- SK_U64 StatRx255Cts;
- SK_U64 StatRx511Cts;
- SK_U64 StatRx1023Cts;
- SK_U64 StatRxMaxCts;
-} SK_PNMI_STAT;
-
-typedef struct s_PnmiConf {
- char ConfMacCurrentAddr[6];
- char ConfMacFactoryAddr[6];
- SK_U8 ConfPMD;
- SK_U8 ConfConnector;
- SK_U32 ConfPhyType;
- SK_U32 ConfPhyMode;
- SK_U8 ConfLinkCapability;
- SK_U8 ConfLinkMode;
- SK_U8 ConfLinkModeStatus;
- SK_U8 ConfLinkStatus;
- SK_U8 ConfFlowCtrlCapability;
- SK_U8 ConfFlowCtrlMode;
- SK_U8 ConfFlowCtrlStatus;
- SK_U8 ConfPhyOperationCapability;
- SK_U8 ConfPhyOperationMode;
- SK_U8 ConfPhyOperationStatus;
- SK_U8 ConfSpeedCapability;
- SK_U8 ConfSpeedMode;
- SK_U8 ConfSpeedStatus;
-} SK_PNMI_CONF;
-
-typedef struct s_PnmiRlmt {
- SK_U32 RlmtIndex;
- SK_U32 RlmtStatus;
- SK_U64 RlmtTxHelloCts;
- SK_U64 RlmtRxHelloCts;
- SK_U64 RlmtTxSpHelloReqCts;
- SK_U64 RlmtRxSpHelloCts;
-} SK_PNMI_RLMT;
-
-typedef struct s_PnmiRlmtMonitor {
- SK_U32 RlmtMonitorIndex;
- char RlmtMonitorAddr[6];
- SK_U64 RlmtMonitorErrorCts;
- SK_U64 RlmtMonitorTimestamp;
- SK_U8 RlmtMonitorAdmin;
-} SK_PNMI_RLMT_MONITOR;
-
-typedef struct s_PnmiRequestStatus {
- SK_U32 ErrorStatus;
- SK_U32 ErrorOffset;
-} SK_PNMI_REQUEST_STATUS;
-
-typedef struct s_PnmiStrucData {
- SK_U32 MgmtDBVersion;
- SK_PNMI_REQUEST_STATUS ReturnStatus;
- SK_U32 VpdFreeBytes;
- char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
- SK_U32 VpdEntriesNumber;
- SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES];
- SK_U32 PortNumber;
- SK_U32 DeviceType;
- char DriverDescr[SK_PNMI_STRINGLEN1];
- char DriverVersion[SK_PNMI_STRINGLEN2];
- char DriverReleaseDate[SK_PNMI_STRINGLEN1];
- char DriverFileName[SK_PNMI_STRINGLEN1];
- char HwDescr[SK_PNMI_STRINGLEN1];
- char HwVersion[SK_PNMI_STRINGLEN2];
- SK_U16 Chipset;
- SK_U32 ChipId;
- SK_U8 VauxAvail;
- SK_U32 RamSize;
- SK_U32 MtuSize;
- SK_U32 Action;
- SK_U32 TestResult;
- SK_U8 BusType;
- SK_U8 BusSpeed;
- SK_U8 BusWidth;
- SK_U8 SensorNumber;
- SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES];
- SK_U8 ChecksumNumber;
- SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES];
- SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES];
- SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES];
- SK_U8 RlmtMode;
- SK_U32 RlmtPortNumber;
- SK_U8 RlmtPortActive;
- SK_U8 RlmtPortPreferred;
- SK_U64 RlmtChangeCts;
- SK_U64 RlmtChangeTime;
- SK_U64 RlmtChangeEstimate;
- SK_U64 RlmtChangeThreshold;
- SK_PNMI_RLMT Rlmt[SK_MAX_MACS];
- SK_U32 RlmtMonitorNumber;
- SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
- SK_U32 TrapNumber;
- SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN];
- SK_U64 TxSwQueueLen;
- SK_U64 TxSwQueueMax;
- SK_U64 TxRetryCts;
- SK_U64 RxIntrCts;
- SK_U64 TxIntrCts;
- SK_U64 RxNoBufCts;
- SK_U64 TxNoBufCts;
- SK_U64 TxUsedDescrNo;
- SK_U64 RxDeliveredCts;
- SK_U64 RxOctetsDeliveredCts;
- SK_U64 RxHwErrorsCts;
- SK_U64 TxHwErrorsCts;
- SK_U64 InErrorsCts;
- SK_U64 OutErrorsCts;
- SK_U64 ErrRecoveryCts;
- SK_U64 SysUpTime;
-} SK_PNMI_STRUCT_DATA;
-
-#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA))
-#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\
- &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
- /*
- * ReturnStatus field
- * must be located
- * before VpdFreeBytes
- */
-
-/*
- * Various definitions
- */
-#define SK_PNMI_MAX_PROTOS 3
-
-#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum
- * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
- * for check while init phase 1
- */
-
-/*
- * Estimate data structure
- */
-typedef struct s_PnmiEstimate {
- unsigned int EstValueIndex;
- SK_U64 EstValue[7];
- SK_U64 Estimate;
- SK_TIMER EstTimer;
-} SK_PNMI_ESTIMATE;
-
-
-/*
- * VCT timer data structure
- */
-typedef struct s_VctTimer {
- SK_TIMER VctTimer;
-} SK_PNMI_VCT_TIMER;
-
-
-/*
- * PNMI specific adapter context structure
- */
-typedef struct s_PnmiPort {
- SK_U64 StatSyncCts;
- SK_U64 StatSyncOctetsCts;
- SK_U64 StatRxLongFrameCts;
- SK_U64 StatRxFrameTooLongCts;
- SK_U64 StatRxPMaccErr;
- SK_U64 TxSwQueueLen;
- SK_U64 TxSwQueueMax;
- SK_U64 TxRetryCts;
- SK_U64 RxIntrCts;
- SK_U64 TxIntrCts;
- SK_U64 RxNoBufCts;
- SK_U64 TxNoBufCts;
- SK_U64 TxUsedDescrNo;
- SK_U64 RxDeliveredCts;
- SK_U64 RxOctetsDeliveredCts;
- SK_U64 RxHwErrorsCts;
- SK_U64 TxHwErrorsCts;
- SK_U64 InErrorsCts;
- SK_U64 OutErrorsCts;
- SK_U64 ErrRecoveryCts;
- SK_U64 RxShortZeroMark;
- SK_U64 CounterOffset[SK_PNMI_CNT_NO];
- SK_U32 CounterHigh[SK_PNMI_CNT_NO];
- SK_BOOL ActiveFlag;
- SK_U8 Align[3];
-} SK_PNMI_PORT;
-
-
-typedef struct s_PnmiData {
- SK_PNMI_PORT Port [SK_MAX_MACS];
- SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */
- SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO];
- SK_U32 TestResult;
- char HwVersion[10];
- SK_U16 Align01;
-
- char *pDriverDescription;
- char *pDriverVersion;
- char *pDriverReleaseDate;
- char *pDriverFileName;
-
- int MacUpdatedFlag;
- int RlmtUpdatedFlag;
- int SirqUpdatedFlag;
-
- SK_U64 RlmtChangeCts;
- SK_U64 RlmtChangeTime;
- SK_PNMI_ESTIMATE RlmtChangeEstimate;
- SK_U64 RlmtChangeThreshold;
-
- SK_U64 StartUpTime;
- SK_U32 DeviceType;
- char PciBusSpeed;
- char PciBusWidth;
- char Chipset;
- char PMD;
- char Connector;
- SK_BOOL DualNetActiveFlag;
- SK_U16 Align02;
-
- char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
- unsigned int TrapBufFree;
- unsigned int TrapQueueBeg;
- unsigned int TrapQueueEnd;
- unsigned int TrapBufPad;
- unsigned int TrapUnique;
- SK_U8 VctStatus[SK_MAX_MACS];
- SK_PNMI_VCT VctBackup[SK_MAX_MACS];
- SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
-#ifdef SK_DIAG_SUPPORT
- SK_U32 DiagAttached;
-#endif /* SK_DIAG_SUPPORT */
-} SK_PNMI;
-
-
-/*
- * Function prototypes
- */
-extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level);
-extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
- unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
- SK_EVPARA Param);
-extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
- unsigned int * pLen, SK_U32 NetIndex);
-
-#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
deleted file mode 100644
index 3eec6274e413..000000000000
--- a/drivers/net/sk98lin/h/skgesirq.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/******************************************************************************
- *
- * Name: skgesirq.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.30 $
- * Date: $Date: 2003/07/04 12:34:13 $
- * Purpose: SK specific Gigabit Ethernet special IRQ functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef _INC_SKGESIRQ_H_
-#define _INC_SKGESIRQ_H_
-
-/* Define return codes of SkGePortCheckUp and CheckShort */
-#define SK_HW_PS_NONE 0 /* No action needed */
-#define SK_HW_PS_RESTART 1 /* Restart needed */
-#define SK_HW_PS_LINK 2 /* Link Up actions needed */
-
-/*
- * Define the Event the special IRQ/INI module can handle
- */
-#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */
-#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */
-#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */
-#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */
-#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */
-#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */
-#define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */
-#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */
-#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */
-#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */
-
-#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */
-#define SK_WA_INA_TIME (100000UL) /* 100 msec */
-
-#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */
-
-/*
- * Define the error numbers and messages
- */
-#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0)
-#define SKERR_SIRQ_E001MSG "Unknown event"
-#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1)
-#define SKERR_SIRQ_E002MSG "Packet timeout RX1"
-#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1)
-#define SKERR_SIRQ_E003MSG "Packet timeout RX2"
-#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1)
-#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized"
-#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1)
-#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized"
-#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1)
-#define SKERR_SIRQ_E006MSG "CHECK failure R1"
-#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1)
-#define SKERR_SIRQ_E007MSG "CHECK failure R2"
-#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1)
-#define SKERR_SIRQ_E008MSG "CHECK failure XS1"
-#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1)
-#define SKERR_SIRQ_E009MSG "CHECK failure XA1"
-#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1)
-#define SKERR_SIRQ_E010MSG "CHECK failure XS2"
-#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1)
-#define SKERR_SIRQ_E011MSG "CHECK failure XA2"
-#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1)
-#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error"
-#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1)
-#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error"
-#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1)
-#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)"
-#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1)
-#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)"
-#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1)
-#define SKERR_SIRQ_E016MSG "Parity error MAC 1"
-#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1)
-#define SKERR_SIRQ_E017MSG "Parity error MAC 2"
-#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1)
-#define SKERR_SIRQ_E018MSG "Parity error RX 1"
-#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1)
-#define SKERR_SIRQ_E019MSG "Parity error RX 2"
-#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1)
-#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun"
-#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1)
-#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt"
-#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1)
-#define SKERR_SIRQ_E022MSG "Cable pair swap error"
-#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1)
-#define SKERR_SIRQ_E023MSG "Auto-negotiation error"
-#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1)
-#define SKERR_SIRQ_E024MSG "FIFO overflow error"
-#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1)
-#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected"
-
-extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
-extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
-
-#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
deleted file mode 100644
index 6a63f4a15de6..000000000000
--- a/drivers/net/sk98lin/h/ski2c.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/******************************************************************************
- *
- * Name: ski2c.h
- * Project: Gigabit Ethernet Adapters, TWSI-Module
- * Version: $Revision: 1.35 $
- * Date: $Date: 2003/10/20 09:06:30 $
- * Purpose: Defines to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKI2C.H contains all I2C specific defines
- */
-
-#ifndef _SKI2C_H_
-#define _SKI2C_H_
-
-typedef struct s_Sensor SK_SENSOR;
-
-#include "h/skgei2c.h"
-
-/*
- * Define the I2C events.
- */
-#define SK_I2CEV_IRQ 1 /* IRQ happened Event */
-#define SK_I2CEV_TIM 2 /* Timeout event */
-#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */
-
-/*
- * Define READ and WRITE Constants.
- */
-#define I2C_READ 0
-#define I2C_WRITE 1
-#define I2C_BURST 1
-#define I2C_SINGLE 0
-
-#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0)
-#define SKERR_I2C_E001MSG "Sensor index unknown"
-#define SKERR_I2C_E002 (SKERR_I2C_E001+1)
-#define SKERR_I2C_E002MSG "TWSI: transfer does not complete"
-#define SKERR_I2C_E003 (SKERR_I2C_E002+1)
-#define SKERR_I2C_E003MSG "LM80: NAK on device send"
-#define SKERR_I2C_E004 (SKERR_I2C_E003+1)
-#define SKERR_I2C_E004MSG "LM80: NAK on register send"
-#define SKERR_I2C_E005 (SKERR_I2C_E004+1)
-#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send"
-#define SKERR_I2C_E006 (SKERR_I2C_E005+1)
-#define SKERR_I2C_E006MSG "Unknown event"
-#define SKERR_I2C_E007 (SKERR_I2C_E006+1)
-#define SKERR_I2C_E007MSG "LM80 read out of state"
-#define SKERR_I2C_E008 (SKERR_I2C_E007+1)
-#define SKERR_I2C_E008MSG "Unexpected sensor read completed"
-#define SKERR_I2C_E009 (SKERR_I2C_E008+1)
-#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range"
-#define SKERR_I2C_E010 (SKERR_I2C_E009+1)
-#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range"
-#define SKERR_I2C_E011 (SKERR_I2C_E010+1)
-#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range"
-#define SKERR_I2C_E012 (SKERR_I2C_E011+1)
-#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range"
-#define SKERR_I2C_E013 (SKERR_I2C_E012+1)
-#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor"
-#define SKERR_I2C_E014 (SKERR_I2C_E013+1)
-#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range"
-#define SKERR_I2C_E015 (SKERR_I2C_E014+1)
-#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range"
-#define SKERR_I2C_E016 (SKERR_I2C_E015+1)
-#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete"
-
-/*
- * Define Timeout values
- */
-#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */
-#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */
-#define SK_I2C_TIM_WATCH 1000000L /* 1 second */
-
-/*
- * Define trap and error log hold times
- */
-#ifndef SK_SEN_ERR_TR_HOLD
-#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC)
-#endif
-#ifndef SK_SEN_ERR_LOG_HOLD
-#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC)
-#endif
-#ifndef SK_SEN_WARN_TR_HOLD
-#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC)
-#endif
-#ifndef SK_SEN_WARN_LOG_HOLD
-#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC)
-#endif
-
-/*
- * Defines for SenType
- */
-#define SK_SEN_UNKNOWN 0
-#define SK_SEN_TEMP 1
-#define SK_SEN_VOLT 2
-#define SK_SEN_FAN 3
-
-/*
- * Define for the SenErrorFlag
- */
-#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */
-#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */
-#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */
-#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */
-#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */
-
-/*
- * Define the Sensor struct
- */
-struct s_Sensor {
- char *SenDesc; /* Description */
- int SenType; /* Voltage or Temperature */
- SK_I32 SenValue; /* Current value of the sensor */
- SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */
- SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */
- SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */
- SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */
- int SenErrFlag; /* Sensor indicated an error */
- SK_BOOL SenInit; /* Is sensor initialized ? */
- SK_U64 SenErrCts; /* Error trap counter */
- SK_U64 SenWarnCts; /* Warning trap counter */
- SK_U64 SenBegErrTS; /* Begin error timestamp */
- SK_U64 SenBegWarnTS; /* Begin warning timestamp */
- SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */
- SK_U64 SenLastErrLogTS; /* Last error log timestamp */
- SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */
- SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */
- int SenState; /* Sensor State (see HW specific include) */
- int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
- /* Sensors read function */
- SK_U16 SenReg; /* Register Address for this sensor */
- SK_U8 SenDev; /* Device Selection for this sensor */
-};
-
-typedef struct s_I2c {
- SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */
- int CurrSens; /* Which sensor is currently queried */
- int MaxSens; /* Max. number of sensors */
- int TimerMode; /* Use the timer also to watch the state machine */
- int InitLevel; /* Initialized Level */
-#ifndef SK_DIAG
- int DummyReads; /* Number of non-checked dummy reads */
- SK_TIMER SenTimer; /* Sensors timer */
-#endif /* !SK_DIAG */
-} SK_I2C;
-
-extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
-#ifdef SK_DIAG
-extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
- int Burst);
-#else /* !SK_DIAG */
-extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
-extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
-#endif /* !SK_DIAG */
-#endif /* n_SKI2C_H */
-
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
deleted file mode 100644
index 2ec40d4fdf60..000000000000
--- a/drivers/net/sk98lin/h/skqueue.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/******************************************************************************
- *
- * Name: skqueue.h
- * Project: Gigabit Ethernet Adapters, Event Scheduler Module
- * Version: $Revision: 1.16 $
- * Date: $Date: 2003/09/16 12:50:32 $
- * Purpose: Defines for the Event queue
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKQUEUE.H contains all defines and types for the event queue
- */
-
-#ifndef _SKQUEUE_H_
-#define _SKQUEUE_H_
-
-
-/*
- * define the event classes to be served
- */
-#define SKGE_DRV 1 /* Driver Event Class */
-#define SKGE_RLMT 2 /* RLMT Event Class */
-#define SKGE_I2C 3 /* I2C Event Class */
-#define SKGE_PNMI 4 /* PNMI Event Class */
-#define SKGE_CSUM 5 /* Checksum Event Class */
-#define SKGE_HWAC 6 /* Hardware Access Event Class */
-
-#define SKGE_SWT 9 /* Software Timer Event Class */
-#define SKGE_LACP 10 /* LACP Aggregation Event Class */
-#define SKGE_RSF 11 /* RSF Aggregation Event Class */
-#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */
-#define SKGE_FD 13 /* FD Distributor Event Class */
-
-/*
- * define event queue as circular buffer
- */
-#define SK_MAX_EVENT 64
-
-/*
- * Parameter union for the Para stuff
- */
-typedef union u_EvPara {
- void *pParaPtr; /* Parameter Pointer */
- SK_U64 Para64; /* Parameter 64bit version */
- SK_U32 Para32[2]; /* Parameter Array of 32bit parameters */
-} SK_EVPARA;
-
-/*
- * Event Queue
- * skqueue.c
- * events are class/value pairs
- * class is addressee, e.g. RLMT, PNMI etc.
- * value is command, e.g. line state change, ring op change etc.
- */
-typedef struct s_EventElem {
- SK_U32 Class; /* Event class */
- SK_U32 Event; /* Event value */
- SK_EVPARA Para; /* Event parameter */
-} SK_EVENTELEM;
-
-typedef struct s_Queue {
- SK_EVENTELEM EvQueue[SK_MAX_EVENT];
- SK_EVENTELEM *EvPut;
- SK_EVENTELEM *EvGet;
-} SK_QUEUE;
-
-extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
-extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
- SK_EVPARA Para);
-extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
-
-
-/* Define Error Numbers and messages */
-#define SKERR_Q_E001 (SK_ERRBASE_QUEUE+0)
-#define SKERR_Q_E001MSG "Event queue overflow"
-#define SKERR_Q_E002 (SKERR_Q_E001+1)
-#define SKERR_Q_E002MSG "Undefined event class"
-#endif /* _SKQUEUE_H_ */
-
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
deleted file mode 100644
index ca75dfdcf2d6..000000000000
--- a/drivers/net/sk98lin/h/skrlmt.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/******************************************************************************
- *
- * Name: skrlmt.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.37 $
- * Date: $Date: 2003/04/15 09:43:43 $
- * Purpose: Header file for Redundant Link ManagemenT.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the header file for Redundant Link ManagemenT.
- *
- * Include File Hierarchy:
- *
- * "skdrv1st.h"
- * ...
- * "sktypes.h"
- * "skqueue.h"
- * "skaddr.h"
- * "skrlmt.h"
- * ...
- * "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef __INC_SKRLMT_H
-#define __INC_SKRLMT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-/* defines ********************************************************************/
-
-#define SK_RLMT_NET_DOWN_TEMP 1 /* NET_DOWN due to last port down. */
-#define SK_RLMT_NET_DOWN_FINAL 2 /* NET_DOWN due to RLMT_STOP. */
-
-/* ----- Default queue sizes - must be multiples of 8 KB ----- */
-
-/* Less than 8 KB free in RX queue => pause frames. */
-#define SK_RLMT_STANDBY_QRXSIZE 128 /* Size of rx standby queue in KB. */
-#define SK_RLMT_STANDBY_QXASIZE 32 /* Size of async standby queue in KB. */
-#define SK_RLMT_STANDBY_QXSSIZE 0 /* Size of sync standby queue in KB. */
-
-#define SK_RLMT_MAX_TX_BUF_SIZE 60 /* Maximum RLMT transmit size. */
-
-/* ----- PORT states ----- */
-
-#define SK_RLMT_PS_INIT 0 /* Port state: Init. */
-#define SK_RLMT_PS_LINK_DOWN 1 /* Port state: Link down. */
-#define SK_RLMT_PS_DOWN 2 /* Port state: Port down. */
-#define SK_RLMT_PS_GOING_UP 3 /* Port state: Going up. */
-#define SK_RLMT_PS_UP 4 /* Port state: Up. */
-
-/* ----- RLMT states ----- */
-
-#define SK_RLMT_RS_INIT 0 /* RLMT state: Init. */
-#define SK_RLMT_RS_NET_DOWN 1 /* RLMT state: Net down. */
-#define SK_RLMT_RS_NET_UP 2 /* RLMT state: Net up. */
-
-/* ----- PORT events ----- */
-
-#define SK_RLMT_LINK_UP 1001 /* Link came up. */
-#define SK_RLMT_LINK_DOWN 1002 /* Link went down. */
-#define SK_RLMT_PORT_ADDR 1003 /* Port address changed. */
-
-/* ----- RLMT events ----- */
-
-#define SK_RLMT_START 2001 /* Start RLMT. */
-#define SK_RLMT_STOP 2002 /* Stop RLMT. */
-#define SK_RLMT_PACKET_RECEIVED 2003 /* Packet was received for RLMT. */
-#define SK_RLMT_STATS_CLEAR 2004 /* Clear statistics. */
-#define SK_RLMT_STATS_UPDATE 2005 /* Update statistics. */
-#define SK_RLMT_PREFPORT_CHANGE 2006 /* Change preferred port. */
-#define SK_RLMT_MODE_CHANGE 2007 /* New RlmtMode. */
-#define SK_RLMT_SET_NETS 2008 /* Number of Nets (1 or 2). */
-
-/* ----- RLMT mode bits ----- */
-
-/*
- * CAUTION: These defines are private to RLMT.
- * Please use the RLMT mode defines below.
- */
-
-#define SK_RLMT_CHECK_LINK 1 /* Check Link. */
-#define SK_RLMT_CHECK_LOC_LINK 2 /* Check other link on same adapter. */
-#define SK_RLMT_CHECK_SEG 4 /* Check segmentation. */
-
-#ifndef RLMT_CHECK_REMOTE
-#define SK_RLMT_CHECK_OTHERS SK_RLMT_CHECK_LOC_LINK
-#else /* RLMT_CHECK_REMOTE */
-#define SK_RLMT_CHECK_REM_LINK 8 /* Check link(s) on other adapter(s). */
-#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED 3
-#define SK_RLMT_CHECK_OTHERS \
- (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
-#endif /* RLMT_CHECK_REMOTE */
-
-#ifndef SK_RLMT_ENABLE_TRANSPARENT
-#define SK_RLMT_TRANSPARENT 0 /* RLMT transparent - inactive. */
-#else /* SK_RLMT_ENABLE_TRANSPARENT */
-#define SK_RLMT_TRANSPARENT 128 /* RLMT transparent. */
-#endif /* SK_RLMT_ENABLE_TRANSPARENT */
-
-/* ----- RLMT modes ----- */
-
-/* Check Link State. */
-#define SK_RLMT_MODE_CLS (SK_RLMT_CHECK_LINK)
-
-/* Check Local Ports: check other links on the same adapter. */
-#define SK_RLMT_MODE_CLP (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
-
-/* Check Local Ports and Segmentation Status. */
-#define SK_RLMT_MODE_CLPSS \
- (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
-
-#ifdef RLMT_CHECK_REMOTE
-/* Check Local and Remote Ports: check links (local or remote). */
- Name of define TBD!
-#define SK_RLMT_MODE_CRP \
- (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
-
-/* Check Local and Remote Ports and Segmentation Status. */
- Name of define TBD!
-#define SK_RLMT_MODE_CRPSS \
- (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
- SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
-#endif /* RLMT_CHECK_REMOTE */
-
-/* ----- RLMT lookahead result bits ----- */
-
-#define SK_RLMT_RX_RLMT 1 /* Give packet to RLMT. */
-#define SK_RLMT_RX_PROTOCOL 2 /* Give packet to protocol. */
-
-/* Macros */
-
-#if 0
-SK_AC *pAC /* adapter context */
-SK_U32 PortNum /* receiving port */
-unsigned PktLen /* received packet's length */
-SK_BOOL IsBc /* Flag: packet is broadcast */
-unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
-unsigned *pNumBytes /* #Bytes to present to SK_RLMT_LOOKAHEAD */
-#endif /* 0 */
-
-#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
- SK_AC *_pAC; \
- SK_U32 _PortNum; \
- _pAC = (pAC); \
- _PortNum = (SK_U32)(PortNum); \
- /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
- _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
- if (_pAC->Rlmt.RlmtOff) { \
- *(pNumBytes) = 0; \
- } \
- else {\
- if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
- *(pNumBytes) = 0; \
- } \
- else if (IsBc) { \
- if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
- *(pNumBytes) = 6; \
- *(pOffset) = 6; \
- } \
- else { \
- *(pNumBytes) = 0; \
- } \
- } \
- else { \
- if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
- /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
- *(pNumBytes) = 0; \
- } \
- else { \
- *(pNumBytes) = 6; \
- *(pOffset) = 0; \
- } \
- } \
- } \
-}
-
-#if 0
-SK_AC *pAC /* adapter context */
-SK_U32 PortNum /* receiving port */
-SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */
-SK_BOOL IsBc /* Flag: packet is broadcast */
-SK_BOOL IsMc /* Flag: packet is multicast */
-unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
-SK_RLMT_LOOKAHEAD() expects *pNumBytes from
-packet offset *pOffset (s.a.) at *pLaPacket.
-
-If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
-BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
-can trash unneeded parts of the if construction.
-#endif /* 0 */
-
-#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
- SK_AC *_pAC; \
- SK_U32 _PortNum; \
- SK_U8 *_pLaPacket; \
- _pAC = (pAC); \
- _PortNum = (SK_U32)(PortNum); \
- _pLaPacket = (SK_U8 *)(pLaPacket); \
- if (IsBc) {\
- if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
- _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
- _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
- _pAC->Rlmt.CheckSwitch = SK_TRUE; \
- } \
- /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
- *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
- } \
- else if (IsMc) { \
- if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
- _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
- if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
- *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
- } \
- else { \
- *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
- } \
- } \
- else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
- *(pForRlmt) = SK_RLMT_RX_RLMT; \
- } \
- else { \
- /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
- *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
- } \
- } \
- else { \
- if (SK_ADDR_EQUAL( \
- _pLaPacket, \
- _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
- *(pForRlmt) = SK_RLMT_RX_RLMT; \
- } \
- else { \
- /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
- *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
- } \
- } \
-}
-
-#ifdef SK_RLMT_FAST_LOOKAHEAD
-Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
-#endif /* SK_RLMT_FAST_LOOKAHEAD */
-#ifdef SK_RLMT_SLOW_LOOKAHEAD
-Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
-#endif /* SK_RLMT_SLOW_LOOKAHEAD */
-
-/* typedefs *******************************************************************/
-
-#ifdef SK_RLMT_MBUF_PRIVATE
-typedef struct s_RlmtMbuf {
- some content
-} SK_RLMT_MBUF;
-#endif /* SK_RLMT_MBUF_PRIVATE */
-
-
-#ifdef SK_LA_INFO
-typedef struct s_Rlmt_PacketInfo {
- unsigned PacketLength; /* Length of packet. */
- unsigned PacketType; /* Directed/Multicast/Broadcast. */
-} SK_RLMT_PINFO;
-#endif /* SK_LA_INFO */
-
-
-typedef struct s_RootId {
- SK_U8 Id[8]; /* Root Bridge Id. */
-} SK_RLMT_ROOT_ID;
-
-
-typedef struct s_port {
- SK_MAC_ADDR CheckAddr;
- SK_BOOL SuspectTx;
-} SK_PORT_CHECK;
-
-
-typedef struct s_RlmtNet SK_RLMT_NET;
-
-
-typedef struct s_RlmtPort {
-
-/* ----- Public part (read-only) ----- */
-
- SK_U8 PortState; /* Current state of this port. */
-
- /* For PNMI */
- SK_BOOL LinkDown;
- SK_BOOL PortDown;
- SK_U8 Align01;
-
- SK_U32 PortNumber; /* Number of port on adapter. */
- SK_RLMT_NET * Net; /* Net port belongs to. */
-
- SK_U64 TxHelloCts;
- SK_U64 RxHelloCts;
- SK_U64 TxSpHelloReqCts;
- SK_U64 RxSpHelloCts;
-
-/* ----- Private part ----- */
-
-/* SK_U64 PacketsRx; */ /* Total packets received. */
- SK_U32 PacketsPerTimeSlot; /* Packets rxed between TOs. */
-/* SK_U32 DataPacketsPerTimeSlot; */ /* Data packets ... */
- SK_U32 BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
- SK_U64 BcTimeStamp; /* Time of last BC receive. */
- SK_U64 GuTimeStamp; /* Time of entering GOING_UP. */
-
- SK_TIMER UpTimer; /* Timer struct Link/Port up. */
- SK_TIMER DownRxTimer; /* Timer struct down rx. */
- SK_TIMER DownTxTimer; /* Timer struct down tx. */
-
- SK_U32 CheckingState; /* Checking State. */
-
- SK_ADDR_PORT * AddrPort;
-
- SK_U8 Random[4]; /* Random value. */
- unsigned PortsChecked; /* #ports checked. */
- unsigned PortsSuspect; /* #ports checked that are s. */
- SK_PORT_CHECK PortCheck[1];
-/* SK_PORT_CHECK PortCheck[SK_MAX_MACS - 1]; */
-
- SK_BOOL PortStarted; /* Port is started. */
- SK_BOOL PortNoRx; /* NoRx for >= 1 time slot. */
- SK_BOOL RootIdSet;
- SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
-} SK_RLMT_PORT;
-
-
-struct s_RlmtNet {
-
-/* ----- Public part (read-only) ----- */
-
- SK_U32 NetNumber; /* Number of net. */
-
- SK_RLMT_PORT * Port[SK_MAX_MACS]; /* Ports that belong to this net. */
- SK_U32 NumPorts; /* Number of ports. */
- SK_U32 PrefPort; /* Preferred port. */
-
- /* For PNMI */
-
- SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */
- SK_U32 RlmtMode; /* Check ... */
- SK_U32 ActivePort; /* Active port. */
- SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */
-
- SK_U8 RlmtState; /* Current RLMT state. */
-
-/* ----- Private part ----- */
- SK_BOOL RootIdSet;
- SK_U16 Align01;
-
- int LinksUp; /* #Links up. */
- int PortsUp; /* #Ports up. */
- SK_U32 TimeoutValue; /* RLMT timeout value. */
-
- SK_U32 CheckingState; /* Checking State. */
- SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
-
- SK_TIMER LocTimer; /* Timer struct. */
- SK_TIMER SegTimer; /* Timer struct. */
-};
-
-
-typedef struct s_Rlmt {
-
-/* ----- Public part (read-only) ----- */
-
- SK_U32 NumNets; /* Number of nets. */
- SK_U32 NetsStarted; /* Number of nets started. */
- SK_RLMT_NET Net[SK_MAX_NETS]; /* Array of available nets. */
- SK_RLMT_PORT Port[SK_MAX_MACS]; /* Array of available ports. */
-
-/* ----- Private part ----- */
- SK_BOOL CheckSwitch;
- SK_BOOL RlmtOff; /* set to zero if the Mac addresses
- are equal or the second one
- is zero */
- SK_U16 Align01;
-
-} SK_RLMT;
-
-
-extern SK_MAC_ADDR BridgeMcAddr;
-extern SK_MAC_ADDR SkRlmtMcAddr;
-
-/* function prototypes ********************************************************/
-
-
-#ifndef SK_KR_PROTO
-
-/* Functions provided by SkRlmt */
-
-/* ANSI/C++ compliant function prototypes */
-
-extern void SkRlmtInit(
- SK_AC *pAC,
- SK_IOC IoC,
- int Level);
-
-extern int SkRlmtEvent(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 Event,
- SK_EVPARA Para);
-
-#else /* defined(SK_KR_PROTO) */
-
-/* Non-ANSI/C++ compliant function prototypes */
-
-#error KR-style function prototypes are not yet provided.
-
-#endif /* defined(SK_KR_PROTO)) */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
deleted file mode 100644
index 04e6d7c1ec33..000000000000
--- a/drivers/net/sk98lin/h/sktimer.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/******************************************************************************
- *
- * Name: sktimer.h
- * Project: Gigabit Ethernet Adapters, Event Scheduler Module
- * Version: $Revision: 1.11 $
- * Date: $Date: 2003/09/16 12:58:18 $
- * Purpose: Defines for the timer functions
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * SKTIMER.H contains all defines and types for the timer functions
- */
-
-#ifndef _SKTIMER_H_
-#define _SKTIMER_H_
-
-#include "h/skqueue.h"
-
-/*
- * SK timer
- * - needed wherever a timer is used. Put this in your data structure
- * wherever you want.
- */
-typedef struct s_Timer SK_TIMER;
-
-struct s_Timer {
- SK_TIMER *TmNext; /* linked list */
- SK_U32 TmClass; /* Timer Event class */
- SK_U32 TmEvent; /* Timer Event value */
- SK_EVPARA TmPara; /* Timer Event parameter */
- SK_U32 TmDelta; /* delta time */
- int TmActive; /* flag: active/inactive */
-};
-
-/*
- * Timer control struct.
- * - use in Adapters context name pAC->Tim
- */
-typedef struct s_TimCtrl {
- SK_TIMER *StQueue; /* Head of Timer queue */
-} SK_TIMCTRL;
-
-extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
-extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
-extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
- SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
-extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
-#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
deleted file mode 100644
index 40edc96e1055..000000000000
--- a/drivers/net/sk98lin/h/sktypes.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************
- *
- * Name: sktypes.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.2 $
- * Date: $Date: 2003/10/07 08:16:51 $
- * Purpose: Define data types for Linux
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * In this file, all data types that are needed by the common modules
- * are mapped to Linux data types.
- *
- *
- * Include File Hierarchy:
- *
- *
- ******************************************************************************/
-
-#ifndef __INC_SKTYPES_H
-#define __INC_SKTYPES_H
-
-
-/* defines *******************************************************************/
-
-/*
- * Data types with a specific size. 'I' = signed, 'U' = unsigned.
- */
-#define SK_I8 s8
-#define SK_U8 u8
-#define SK_I16 s16
-#define SK_U16 u16
-#define SK_I32 s32
-#define SK_U32 u32
-#define SK_I64 s64
-#define SK_U64 u64
-
-#define SK_UPTR ulong /* casting pointer <-> integral */
-
-/*
-* Boolean type.
-*/
-#define SK_BOOL SK_U8
-#define SK_FALSE 0
-#define SK_TRUE (!SK_FALSE)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
-
-#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
deleted file mode 100644
index a1a7294828e5..000000000000
--- a/drivers/net/sk98lin/h/skversion.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/******************************************************************************
- *
- * Name: version.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.5 $
- * Date: $Date: 2003/10/07 08:16:51 $
- * Purpose: SK specific Error log support
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifdef lint
-static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
-static const char SysKonnectBuildNumber[] =
- "@(#)SK-BUILD: 6.23 PL: 01";
-#endif /* !defined(lint) */
-
-#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \
- "(C)Copyright 1999-2004 Marvell(R)."
-
-#define VER_STRING "6.23"
-#define DRIVER_FILE_NAME "sk98lin"
-#define DRIVER_REL_DATE "Feb-13-2004"
-
-
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
deleted file mode 100644
index fdd9e48e8040..000000000000
--- a/drivers/net/sk98lin/h/skvpd.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/******************************************************************************
- *
- * Name: skvpd.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.15 $
- * Date: $Date: 2003/01/13 10:39:38 $
- * Purpose: Defines and Macros for VPD handling
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * skvpd.h contains Diagnostic specific defines for VPD handling
- */
-
-#ifndef __INC_SKVPD_H_
-#define __INC_SKVPD_H_
-
-/*
- * Define Resource Type Identifiers and VPD keywords
- */
-#define RES_ID 0x82 /* Resource Type ID String (Product Name) */
-#define RES_VPD_R 0x90 /* start of VPD read only area */
-#define RES_VPD_W 0x91 /* start of VPD read/write area */
-#define RES_END 0x78 /* Resource Type End Tag */
-
-#ifndef VPD_NAME
-#define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */
-#endif /* VPD_NAME */
-#define VPD_PN "PN" /* Adapter Part Number */
-#define VPD_EC "EC" /* Adapter Engineering Level */
-#define VPD_MN "MN" /* Manufacture ID */
-#define VPD_SN "SN" /* Serial Number */
-#define VPD_CP "CP" /* Extended Capability */
-#define VPD_RV "RV" /* Checksum and Reserved */
-#define VPD_YA "YA" /* Asset Tag Identifier */
-#define VPD_VL "VL" /* First Error Log Message (SK specific) */
-#define VPD_VF "VF" /* Second Error Log Message (SK specific) */
-#define VPD_RW "RW" /* Remaining Read / Write Area */
-
-/* 'type' values for vpd_setup_para() */
-#define VPD_RO_KEY 1 /* RO keys are "PN", "EC", "MN", "SN", "RV" */
-#define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */
-
-/* 'op' values for vpd_setup_para() */
-#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */
-#define OWR_KEY 2 /* overwrite key if already exists */
-
-/*
- * Define READ and WRITE Constants.
- */
-
-#define VPD_DEV_ID_GENESIS 0x4300
-
-#define VPD_SIZE_YUKON 256
-#define VPD_SIZE_GENESIS 512
-#define VPD_SIZE 512
-#define VPD_READ 0x0000
-#define VPD_WRITE 0x8000
-
-#define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
-
-#define VPD_GET_RES_LEN(p) ((unsigned int) \
- (* (SK_U8 *)&(p)[1]) |\
- ((* (SK_U8 *)&(p)[2]) << 8))
-#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2]))
-#define VPD_GET_VAL(p) ((char *)&(p)[3])
-
-#define VPD_MAX_LEN 50
-
-/* VPD status */
- /* bit 7..1 reserved */
-#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
- /* and vpd_free_rw valid */
-
-/*
- * VPD structs
- */
-typedef struct s_vpd_status {
- unsigned short Align01; /* Alignment */
- unsigned short vpd_status; /* VPD status, description see above */
- int vpd_free_ro; /* unused bytes in read only area */
- int vpd_free_rw; /* bytes available in read/write area */
-} SK_VPD_STATUS;
-
-typedef struct s_vpd {
- SK_VPD_STATUS v; /* VPD status structure */
- char vpd_buf[VPD_SIZE]; /* VPD buffer */
- int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */
- int vpd_size; /* saved VPD-size */
-} SK_VPD;
-
-typedef struct s_vpd_para {
- unsigned int p_len; /* parameter length */
- char *p_val; /* points to the value */
-} SK_VPD_PARA;
-
-/*
- * structure of Large Resource Type Identifiers
- */
-
-/* was removed because of alignment problems */
-
-/*
- * structure of VPD keywords
- */
-typedef struct s_vpd_key {
- char p_key[2]; /* 2 bytes ID string */
- unsigned char p_len; /* 1 byte length */
- char p_val; /* start of the value string */
-} SK_VPD_KEY;
-
-
-/*
- * System specific VPD macros
- */
-#ifndef SKDIAG
-#ifndef VPD_DO_IO
-#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
-#else /* VPD_DO_IO */
-#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
-#endif /* VPD_DO_IO */
-#else /* SKDIAG */
-#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
- if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciWriteCfgByte(pAC,Addr,Val); \
- else \
- SK_OUT8(pAC,PCI_C(Addr),Val); \
- }
-#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
- if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciWriteCfgWord(pAC,Addr,Val); \
- else \
- SK_OUT16(pAC,PCI_C(Addr),Val); \
- }
-#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
- if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciReadCfgByte(pAC,Addr,pVal); \
- else \
- SK_IN8(pAC,PCI_C(Addr),pVal); \
- }
-#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
- if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciReadCfgWord(pAC,Addr,pVal); \
- else \
- SK_IN16(pAC,PCI_C(Addr),pVal); \
- }
-#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
- if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciReadCfgDWord(pAC,Addr,pVal); \
- else \
- SK_IN32(pAC,PCI_C(Addr),pVal); \
- }
-#endif /* nSKDIAG */
-
-/* function prototypes ********************************************************/
-
-#ifndef SK_KR_PROTO
-#ifdef SKDIAG
-extern SK_U32 VpdReadDWord(
- SK_AC *pAC,
- SK_IOC IoC,
- int addr);
-#endif /* SKDIAG */
-
-extern SK_VPD_STATUS *VpdStat(
- SK_AC *pAC,
- SK_IOC IoC);
-
-extern int VpdKeys(
- SK_AC *pAC,
- SK_IOC IoC,
- char *buf,
- int *len,
- int *elements);
-
-extern int VpdRead(
- SK_AC *pAC,
- SK_IOC IoC,
- const char *key,
- char *buf,
- int *len);
-
-extern SK_BOOL VpdMayWrite(
- char *key);
-
-extern int VpdWrite(
- SK_AC *pAC,
- SK_IOC IoC,
- const char *key,
- const char *buf);
-
-extern int VpdDelete(
- SK_AC *pAC,
- SK_IOC IoC,
- char *key);
-
-extern int VpdUpdate(
- SK_AC *pAC,
- SK_IOC IoC);
-
-#ifdef SKDIAG
-extern int VpdReadBlock(
- SK_AC *pAC,
- SK_IOC IoC,
- char *buf,
- int addr,
- int len);
-
-extern int VpdWriteBlock(
- SK_AC *pAC,
- SK_IOC IoC,
- char *buf,
- int addr,
- int len);
-#endif /* SKDIAG */
-#else /* SK_KR_PROTO */
-extern SK_U32 VpdReadDWord();
-extern SK_VPD_STATUS *VpdStat();
-extern int VpdKeys();
-extern int VpdRead();
-extern SK_BOOL VpdMayWrite();
-extern int VpdWrite();
-extern int VpdDelete();
-extern int VpdUpdate();
-#endif /* SK_KR_PROTO */
-
-#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
deleted file mode 100644
index 7f8e6d0084c7..000000000000
--- a/drivers/net/sk98lin/h/xmac_ii.h
+++ /dev/null
@@ -1,1579 +0,0 @@
-/******************************************************************************
- *
- * Name: xmac_ii.h
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.52 $
- * Date: $Date: 2003/10/02 16:35:50 $
- * Purpose: Defines and Macros for Gigabit Ethernet Controller
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifndef __INC_XMAC_H
-#define __INC_XMAC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* defines ********************************************************************/
-
-/*
- * XMAC II registers
- *
- * The XMAC registers are 16 or 32 bits wide.
- * The XMACs host processor interface is set to 16 bit mode,
- * therefore ALL registers will be addressed with 16 bit accesses.
- *
- * The following macros are provided to access the XMAC registers
- * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
- * XM_INHASH(), and XM_OUTHASH().
- * The macros are defined in SkGeHw.h.
- *
- * Note: NA reg = Network Address e.g DA, SA etc.
- *
- */
-#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */
- /* 0x0004: reserved */
-#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */
-#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/
-#define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */
-#define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */
- /* 0x0018 - 0x001e: reserved */
-#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */
-#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */
-#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */
-#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */
-#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */
-#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */
-#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */
- /* 0x003c: reserved */
-#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */
-#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */
-#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */
-#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */
- /* 0x0050 - 0x005e: reserved */
-#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */
-#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */
-#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */
-#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */
-#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */
- /* 0x006e: reserved */
-#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */
-#define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */
-#define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/
-#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */
-
- /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */
- /* use the XM_EXM() macro to address */
-#define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */
-
- /*
- * XM_EXM(Reg)
- *
- * returns the XMAC address offset of specified Exact Match Addr Reg
- *
- * para: Reg EXM register to addr (0 .. 15)
- *
- * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
- */
-#define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3))
-
-#define XM_SRC_CHK 0x0100 /* NA reg r/w Source Check Address Register */
-#define XM_SA 0x0108 /* NA reg r/w Station Address Register */
-#define XM_HSM 0x0110 /* 64 bit r/w Hash Match Address Registers */
-#define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */
-#define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */
-#define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */
-#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */
-#define XM_MODE 0x0124 /* 32 bit r/w Mode Register */
-#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */
- /* 0x012e: reserved */
-#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */
-#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */
- /* 0x0138 - 0x01fe: reserved */
-#define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */
-#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */
-#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */
-#define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */
-#define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */
- /* 0x0204 - 0x027e: reserved */
-#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */
-#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/
-#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */
-#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */
-#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */
-#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */
-#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */
-#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */
-#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */
-#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */
-#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */
-#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */
-#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */
-#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */
-#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */
-#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */
-#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */
-#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */
-#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */
- /* 0x02cc - 0x02ce: reserved */
-#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */
-#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */
-#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */
-#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */
-#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/
-#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/
- /* 0x02e8 - 0x02fe: reserved */
-#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */
-#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */
-#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/
-#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */
-#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */
-#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */
-#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */
-#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */
-#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */
-#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/
-#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */
-#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */
-#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */
-#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */
-#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */
-#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */
-#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */
-#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */
-#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */
-#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */
-#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */
-#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */
- /* 0x0358 - 0x035a: reserved */
-#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/
-#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */
- /* 0x0364 - 0x0366: reserved */
-#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */
-#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */
-#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */
-#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */
-#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/
-#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/
- /* 0x02e8 - 0x02fe: reserved */
-
-
-/*----------------------------------------------------------------------------*/
-/*
- * XMAC Bit Definitions
- *
- * If the bit access behaviour differs from the register access behaviour
- * (r/w, r/o) this is documented after the bit number.
- * The following bit access behaviours are used:
- * (sc) self clearing
- * (ro) read only
- */
-
-/* XM_MMU_CMD 16 bit r/w MMU Command Register */
- /* Bit 15..13: reserved */
-#define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */
-#define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */
-#define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */
-#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */
- /* Bit 8: reserved */
-#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */
-#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */
-#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */
-#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */
-#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */
-#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */
-#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */
-#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */
-
-
-/* XM_TX_CMD 16 bit r/w Transmit Command Register */
- /* Bit 15..7: reserved */
-#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/
-#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */
-#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */
-#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */
-#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */
-#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */
-#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */
-
-
-/* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */
- /* Bit 15..5: reserved */
-#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */
-
-
-/* XM_TX_STIME 16 bit r/w Transmit Slottime Register */
- /* Bit 15..7: reserved */
-#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */
-
-
-/* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */
- /* Bit 15..8: reserved */
-#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */
-
-
-/* XM_RX_CMD 16 bit r/w Receive Command Register */
- /* Bit 15..9: reserved */
-#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */
- /* inrange error packets */
-#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */
- /* jumbo packets */
-#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */
-#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */
-#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */
-#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */
-#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */
-#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */
-#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */
-
-
-/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
- /* Bit 15..5: reserved */
-#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
-
-
-/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
- /* Bit 31..7: reserved */
-#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */
-#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */
- /* Bit 4: reserved */
-#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */
-#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */
- /* Bit 1: reserved */
-#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */
-
-
-/* XM_IMSK 16 bit r/w Interrupt Mask Register */
-/* XM_ISRC 16 bit r/o Interrupt Status Register */
- /* Bit 15: reserved */
-#define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */
-#define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */
-#define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */
-#define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */
-#define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */
-#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */
-#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */
-#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */
-#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */
-#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */
-#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */
-#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */
-#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */
-#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */
-#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */
-
-#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
- XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
-
-
-/* XM_HW_CFG 16 bit r/w Hardware Config Register */
- /* Bit 15.. 4: reserved */
-#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */
-#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/
- /* Bit 1: reserved */
-#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */
-
-
-/* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */
-/* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */
- /* Bit 15..10 reserved */
-#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */
-
-/* XM_TX_THR 16 bit r/w Tx Request Threshold */
-/* XM_HT_THR 16 bit r/w Host Request Threshold */
-/* XM_RX_THR 16 bit r/w Rx Request Threshold */
- /* Bit 15..11 reserved */
-#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */
-
-
-/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */
-#define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */
-#define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */
-#define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */
-#define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */
-#define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */
-#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/
-#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */
-#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */
-#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */
-#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */
-#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */
-#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */
-#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */
-#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */
-#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */
-
-/* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */
-/* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */
- /* Bit 15..11: reserved */
-#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */
-
-
-/* XM_DEV_ID 32 bit r/o Device ID Register */
-#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */
-#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */
-
-
-/* XM_MODE 32 bit r/w Mode Register */
- /* Bit 31..27: reserved */
-#define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */
-#define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */
- /* extern generated */
-#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */
-#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */
- /* intern generated */
-#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */
-#define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */
-#define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */
-#define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */
-#define XM_MD_SPOL_I (1L<<18) /* Bit 18: Send Pause on Low */
- /* intern generated */
-#define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */
- /* intern generated */
-#define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */
-#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */
-#define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */
-#define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */
-#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */
-#define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */
-#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */
-#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */
-#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */
-#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */
-#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */
-#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */
-#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */
-#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */
-#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */
-#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */
-#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */
-
-#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
-#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
- XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
-
-/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
- /* Bit 16..6: reserved */
-#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */
-#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */
-#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */
-#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */
-#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */
-#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */
-
-
-/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */
-/* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */
-#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/
-#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/
-#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/
-#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/
-#define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */
-#define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */
-#define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */
-#define XMR_UTIL_UR (1L<<24) /* Bit 24: Rx Util Cnt Underrun */
-#define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */
- /* Bit 22: reserved */
-#define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */
-#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/
-#define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */
-#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/
-#define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */
- /* Bit 16: reserved */
-#define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */
-#define XMR_JAB_PKT_OV (1L<<14) /* Bit 14: Rx Jabb Packet Cnt Ov */
-#define XMR_FIFO_OV (1L<<13) /* Bit 13: Rx FIFO Ov Ev Cnt Ov */
-#define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */
-#define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */
-#define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */
-#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/
-#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */
-#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */
-#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/
-#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/
-#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */
-#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */
-#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/
-#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/
-#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */
-
-#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV)
-
-/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */
-/* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */
- /* Bit 31..26: reserved */
-#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/
-#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/
-#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/
-#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/
-#define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */
-#define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */
-#define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */
-#define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */
-#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/
-#define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */
-#define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */
-#define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */
-#define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */
-#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/
-#define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */
-#define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */
-#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/
-#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/
-#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */
-#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */
-#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */
-#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */
-#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */
-#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/
-#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/
-#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */
-
-#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV)
-
-/*
- * Receive Frame Status Encoding
- */
-#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */
-#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/
-#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/
-#define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */
-#define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */
-#define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */
- /* Bit 12: reserved */
-#define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */
-#define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */
-#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */
-#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */
-#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */
-#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */
-#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */
-#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */
-#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */
-#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */
-#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */
-#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */
-
-/*
- * XMR_FS_ERR will be set if
- * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
- * XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
- * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
- * XMR_FS_ERR unless the corresponding bit in the Receive Command
- * Register is set.
- */
-#define XMR_FS_ANY_ERR XMR_FS_ERR
-
-/*----------------------------------------------------------------------------*/
-/*
- * XMAC-PHY Registers, indirect addressed over the XMAC
- */
-#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */
-#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */
-#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
-#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
-#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
-#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */
-#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
-#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */
-#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
- /* 0x09 - 0x0e: reserved */
-#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */
-#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Broadcom-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */
-#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */
-#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
-#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
-#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
-#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
-#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
-#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */
-#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
- /* Broadcom-specific registers */
-#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
-#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
- /* 0x0b - 0x0e: reserved */
-#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
-#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */
-#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */
-#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */
-#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */
-#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */
- /* 0x15 - 0x17: reserved */
-#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */
-#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */
-#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */
-#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */
- /* 0x1c: reserved */
- /* 0x1d - 0x1f: test registers */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Marvel-PHY Registers, indirect addressed over GMAC
- */
-#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */
-#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */
-#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
-#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
-#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
-#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
-#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
-#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */
-#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
- /* Marvel-specific registers */
-#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
-#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
- /* 0x0b - 0x0e: reserved */
-#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
-#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */
-#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */
-#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */
-#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
-#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */
-#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */
-#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */
- /* 0x17: reserved */
-#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */
-#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */
-#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */
-#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */
-#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */
- /* 0x1d - 0x1f: reserved */
-
-/*----------------------------------------------------------------------------*/
-/*
- * Level One-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */
-#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */
-#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
-#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
-#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
-#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
-#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
-#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */
-#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
- /* Level One-specific registers */
-#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/
-#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
- /* 0x0b -0x0e: reserved */
-#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
-#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/
-#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */
-#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */
-#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
-#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */
-#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */
-#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */
- /* 0x17 -0x1c: reserved */
-
-/*----------------------------------------------------------------------------*/
-/*
- * National-PHY Registers, indirect addressed over XMAC
- */
-#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */
-#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */
-#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
-#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
-#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
-#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */
-#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
-#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */
-#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */
- /* National-specific registers */
-#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */
-#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
- /* 0x0b -0x0e: reserved */
-#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */
-#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */
-#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */
-#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */
-#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */
-#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */
- /* 0x15 -0x18: reserved */
-#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */
-
-
-/*----------------------------------------------------------------------------*/
-
-/*
- * PHY bit definitions
- * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
- * XMAC/Broadcom/LevelOne/National/Marvell-specific.
- * All other are general.
- */
-
-/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/
-/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/
-/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/
-/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/
-#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */
-#define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */
-#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
-#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */
-#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
-#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
-#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */
-#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */
-#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */
-#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */
- /* Bit 5..0: reserved */
-
-#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */
-#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */
-#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */
-
-
-/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/
-/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/
-/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/
-/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/
- /* Bit 15..9: reserved */
- /* (BC/L1) 100/10 Mbps cap bits ignored*/
-#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */
- /* Bit 7: reserved */
-#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */
-#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */
-#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */
-#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */
-#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */
-#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */
-#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */
-
-
-/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */
-/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */
-/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */
-/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */
-#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */
-#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */
-#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */
-
-/* different Broadcom PHY Ids */
-#define PHY_BCOM_ID1_A1 0x6041
-#define PHY_BCOM_ID1_B2 0x6043
-#define PHY_BCOM_ID1_C0 0x6044
-#define PHY_BCOM_ID1_C5 0x6047
-
-
-/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
-/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
-#define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */
-#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */
-#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */
- /* Bit 11.. 9: reserved */
-#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */
-#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */
-#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */
- /* Bit 4.. 0: reserved */
-
-/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
-/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
-/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
- /* Bit 14: reserved */
-#define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */
- /* Bit 12: reserved */
-#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
-#define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */
- /* Bit 9..5: 100/10 BT cap bits ingnored */
-#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
-
-/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
-/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
-/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
- /* Bit 14: reserved */
-#define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */
- /* Bit 12: reserved */
-#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
-#define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */
- /* Bit 9..5: 100/10 BT cap bits ingnored */
-#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
-
-/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
-/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
-/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
- /* Bit 14: reserved */
-#define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */
- /* Bit 12: reserved */
-#define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */
-#define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */
- /* Bit 9..5: 100/10 BT cap bits ingnored */
-#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
-
-/* field type definition for PHY_x_AN_SEL */
-#define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */
-
-/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
- /* Bit 15..4: reserved */
-#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */
-#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */
-#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */
- /* Bit 0: reserved */
-
-/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
-/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
-/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
- /* Bit 15..5: reserved */
-#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */
-/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */
-/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */
-/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */
-#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */
-
-/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/
-/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/
-/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/
-/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/
-/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/
-/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/
-#define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */
-#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */
-#define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */
-#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */
-#define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */
-#define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */
-
-/*
- * XMAC-Specific
- */
-/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
-#define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */
-#define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */
- /* Bit 13..0: reserved */
-
-/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
- /* Bit 15..9: reserved */
-#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */
-#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */
-#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */
-#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */
-#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */
- /* Bit 2..0: reserved */
-/*
- * Remote Fault Bits (PHY_X_AN_RFB) encoding
- */
-#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */
-#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */
-#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */
-#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */
-
-/*
- * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
- */
-#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */
-#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */
-#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */
-#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */
-
-
-/*
- * Broadcom-Specific
- */
-/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
-#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
-#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
-#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
-#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
-#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
-#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
- /* Bit 7..0: reserved */
-
-/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
-/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
-#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
-#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
-#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
-#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
-#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
-#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
- /* Bit 9..8: reserved */
-#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
-
-/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/
-#define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
-#define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
-#define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
-#define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
- /* Bit 11..0: reserved */
-
-/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/
-#define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */
-#define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */
-#define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
-#define PHY_B_PEC_INT_DIS (1<<12) /* Bit 12: Interrupts Disabled */
-#define PHY_B_PEC_F_INT (1<<11) /* Bit 11: Force Interrupt */
-#define PHY_B_PEC_BY_45 (1<<10) /* Bit 10: Bypass 4B5B-Decoder */
-#define PHY_B_PEC_BY_SCR (1<<9) /* Bit 9: Bypass Scrambler */
-#define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */
-#define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */
-#define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */
-#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */
-#define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */
-#define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */
-#define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */
-#define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */
-#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */
-
-/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/
- /* Bit 15..14: reserved */
-#define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */
-#define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */
-#define PHY_B_PES_RRS (1<<11) /* Bit 11: Remote Receiver Stat. */
-#define PHY_B_PES_LRS (1<<10) /* Bit 10: Local Receiver Stat. */
-#define PHY_B_PES_LOCKED (1<<9) /* Bit 9: Locked */
-#define PHY_B_PES_LS (1<<8) /* Bit 8: Link Status */
-#define PHY_B_PES_RF (1<<7) /* Bit 7: Remote Fault */
-#define PHY_B_PES_CE_ER (1<<6) /* Bit 6: Carrier Ext Error */
-#define PHY_B_PES_BAD_SSD (1<<5) /* Bit 5: Bad SSD */
-#define PHY_B_PES_BAD_ESD (1<<4) /* Bit 4: Bad ESD */
-#define PHY_B_PES_RX_ER (1<<3) /* Bit 3: Receive Error */
-#define PHY_B_PES_TX_ER (1<<2) /* Bit 2: Transmit Error */
-#define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */
-#define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */
-
-/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
- /* Bit 15..8: reserved */
-#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */
-
-/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/
-#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */
-#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */
-
-/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/
-#define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */
-#define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */
-#define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */
- /* Bit 11: reserved */
-#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */
- /* Bit 9.. 8: reserved */
-#define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */
- /* Bit 6: reserved */
-#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */
- /* Bit 4: reserved */
-#define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */
- /* Bit 2.. 0: reserved */
-
-/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/
-#define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */
-#define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */
-#define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */
-#define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */
-#define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */
-#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */
-#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */
-#define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */
-#define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */
-#define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */
-#define PHY_B_AS_LP_NPAB (1<<3) /* Bit 3: LP Next Page Ability */
-#define PHY_B_AS_LS (1<<2) /* Bit 2: Link Status */
-#define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */
-#define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */
-
-#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT)
-
-/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/
-/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
- /* Bit 15: reserved */
-#define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */
-#define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */
-#define PHY_B_IS_HCT (1<<12) /* Bit 12: counter above 32k */
-#define PHY_B_IS_LCT (1<<11) /* Bit 11: counter above 128 */
-#define PHY_B_IS_AN_PR (1<<10) /* Bit 10: Page Received */
-#define PHY_B_IS_NO_HDCL (1<<9) /* Bit 9: No HCD Link */
-#define PHY_B_IS_NO_HDC (1<<8) /* Bit 8: No HCD */
-#define PHY_B_IS_NEG_USHDC (1<<7) /* Bit 7: Negotiated Unsup. HCD */
-#define PHY_B_IS_SCR_S_ER (1<<6) /* Bit 6: Scrambler Sync Error */
-#define PHY_B_IS_RRS_CHANGE (1<<5) /* Bit 5: Remote Rx Stat Change */
-#define PHY_B_IS_LRS_CHANGE (1<<4) /* Bit 4: Local Rx Stat Change */
-#define PHY_B_IS_DUP_CHANGE (1<<3) /* Bit 3: Duplex Mode Change */
-#define PHY_B_IS_LSP_CHANGE (1<<2) /* Bit 2: Link Speed Change */
-#define PHY_B_IS_LST_CHANGE (1<<1) /* Bit 1: Link Status Changed */
-#define PHY_B_IS_CRC_ER (1<<0) /* Bit 0: CRC Error */
-
-#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
-
-/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
-#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
-#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
-#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
-#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
-
-/*
- * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
- */
-#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */
-#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */
-/* others: 100/10: invalid for us */
-
-/*
- * Level One-Specific
- */
-/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
-#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
-#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
-#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
-#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
-#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
-#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
- /* Bit 7..0: reserved */
-
-/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
-#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
-#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
-#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
-#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
-#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
-#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
- /* Bit 9..8: reserved */
-#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
-
-/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
-#define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
-#define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
-#define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
-#define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
- /* Bit 11..0: reserved */
-
-/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
-#define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */
- /* Bit 14: reserved */
-#define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
-#define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */
-#define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */
-#define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */
-#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */
-#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */
-#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */
-#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */
-#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */
-#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */
-#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */
-#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */
-#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */
-#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */
-
-/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
-#define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */
-#define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */
-#define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */
-#define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */
-#define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */
-#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */
-#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */
-#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */
-#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */
-#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */
-#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */
-#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */
-#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */
-
-/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
-/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
- /* Bit 15..14: reserved */
-#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */
- /* Bit 12: not described */
-#define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */
-#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */
-#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */
-#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */
-#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */
-#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */
-#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */
-#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */
-#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */
-#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */
-#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */
-#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */
-
-/* int. mask */
-#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
-
-/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
-#define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */
-#define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */
-#define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */
-#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */
-#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */
-#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */
-#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */
-#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */
-#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */
-
-/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
-#define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */
- /* Bit 14: reserved */
-#define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */
-#define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */
- /* Bit 11: reserved */
-#define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/
- /* Bit 9..0: not described */
-
-/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
-#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */
-#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */
-
-
-/*
- * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
- */
-#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
-#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
-#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
-#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
-
-
-/*
- * National-Specific
- */
-/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
-#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
-#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
-#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
-#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
-#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
-#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
-#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */
- /* Bit 6..0: reserved */
-
-/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
-#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
-#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
-#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
-#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/
-#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
-#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
-#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */
- /* Bit 8: reserved */
-#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
-
-/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
-#define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
-#define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
-#define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
-#define PHY_N_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
- /* Bit 11..0: reserved */
-
-/* todo: those are still missing */
-/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/
-/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/
-/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/
-/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/
-/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/
-/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/
-
-/*
- * Marvell-Specific
- */
-/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
-/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/
-#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */
-#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */
-#define PHY_M_AN_RF BIT_13 /* Remote Fault */
- /* Bit 12: reserved */
-#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */
-#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */
-#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */
-#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */
-#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */
-#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */
-
-/* special defines for FIBER (88E1011S only) */
-#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */
-#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */
-#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */
-#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */
-
-/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
-#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */
-#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */
-#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */
-#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */
-
-/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
-#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
-#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */
-#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */
-#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */
-#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
-#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
- /* Bit 7..0: reserved */
-
-/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/
-#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */
-#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */
-#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */
-#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */
-#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */
-#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */
-#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */
-#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */
-#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */
-#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */
-#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */
-#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */
-
-#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */
-#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */
-
-#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)
-#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */
-#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */
-#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */
-
-/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/
-#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */
-#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */
-#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */
-#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */
-#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */
-#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */
-#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */
-#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */
-#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */
-#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */
-#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */
-#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */
-#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */
-#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */
-#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */
-#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */
-
-#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
-
-/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
-/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/
-#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */
-#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */
-#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */
-#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */
-#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */
-#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */
-#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */
-#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */
-#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */
-#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */
-#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */
-#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */
- /* Bit 3..2: reserved */
-#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */
-#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */
-
-#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
- PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
-
-/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/
-#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */
-#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */
-#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */
-#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */
-
-#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */
-#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */
-#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */
-
-#define MAC_TX_CLK_0_MHZ 2
-#define MAC_TX_CLK_2_5_MHZ 6
-#define MAC_TX_CLK_25_MHZ 7
-
-/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/
-#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */
-#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */
-#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */
-#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */
- /* Bit 7.. 5: reserved */
-#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */
-#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */
-#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */
-#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */
-
-#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */
-
-#define PULS_NO_STR 0 /* no pulse stretching */
-#define PULS_21MS 1 /* 21 ms to 42 ms */
-#define PULS_42MS 2 /* 42 ms to 84 ms */
-#define PULS_84MS 3 /* 84 ms to 170 ms */
-#define PULS_170MS 4 /* 170 ms to 340 ms */
-#define PULS_340MS 5 /* 340 ms to 670 ms */
-#define PULS_670MS 6 /* 670 ms to 1.3 s */
-#define PULS_1300MS 7 /* 1.3 s to 2.7 s */
-
-#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */
-
-#define BLINK_42MS 0 /* 42 ms */
-#define BLINK_84MS 1 /* 84 ms */
-#define BLINK_170MS 2 /* 170 ms */
-#define BLINK_340MS 3 /* 340 ms */
-#define BLINK_670MS 4 /* 670 ms */
- /* values 5 - 7: reserved */
-
-/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
-#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */
-#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */
-#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */
-#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */
-#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */
-#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */
-
-#define MO_LED_NORM 0
-#define MO_LED_BLINK 1
-#define MO_LED_OFF 2
-#define MO_LED_ON 3
-
-/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
- /* Bit 15.. 7: reserved */
-#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */
-#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */
-#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */
-#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */
-#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */
-
-/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
-#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */
-#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */
-#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */
-#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */
-#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */
-#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */
- /* Bit 9..4: reserved */
-#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */
-#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
-
-
-/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/
-#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */
-#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */
- /* Bit 12.. 8: reserved */
-#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */
-
-/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
-#define CABD_STAT_NORMAL 0
-#define CABD_STAT_SHORT 1
-#define CABD_STAT_OPEN 2
-#define CABD_STAT_FAIL 3
-
-
-/*
- * GMAC registers
- *
- * The GMAC registers are 16 or 32 bits wide.
- * The GMACs host processor interface is 16 bits wide,
- * therefore ALL registers will be addressed with 16 bit accesses.
- *
- * The following macros are provided to access the GMAC registers
- * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
- * GM_INHASH(), and GM_OUTHASH().
- * The macros are defined in SkGeHw.h.
- *
- * Note: NA reg = Network Address e.g DA, SA etc.
- *
- */
-
-/* Port Registers */
-#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */
-#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */
-#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */
-#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */
-#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */
-#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */
-#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */
-
-/* Source Address Registers */
-#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */
-#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */
-#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */
-#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */
-#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */
-#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */
-
-/* Multicast Address Hash Registers */
-#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */
-#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */
-#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */
-#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */
-
-/* Interrupt Source Registers */
-#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */
-#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */
-#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */
-
-/* Interrupt Mask Registers */
-#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */
-#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */
-#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */
-
-/* Serial Management Interface (SMI) Registers */
-#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */
-#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */
-#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */
-
-/* MIB Counters */
-#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
-#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
-
-/*
- * MIB Counters base address definitions (low word) -
- * use offset 4 for access to high word (32 bit r/o)
- */
-#define GM_RXF_UC_OK \
- (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */
-#define GM_RXF_BC_OK \
- (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */
-#define GM_RXF_MPAUSE \
- (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */
-#define GM_RXF_MC_OK \
- (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */
-#define GM_RXF_FCS_ERR \
- (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */
- /* GM_MIB_CNT_BASE + 40: reserved */
-#define GM_RXO_OK_LO \
- (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */
-#define GM_RXO_OK_HI \
- (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */
-#define GM_RXO_ERR_LO \
- (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */
-#define GM_RXO_ERR_HI \
- (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */
-#define GM_RXF_SHT \
- (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */
-#define GM_RXE_FRAG \
- (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */
-#define GM_RXF_64B \
- (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */
-#define GM_RXF_127B \
- (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
-#define GM_RXF_255B \
- (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
-#define GM_RXF_511B \
- (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
-#define GM_RXF_1023B \
- (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
-#define GM_RXF_1518B \
- (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
-#define GM_RXF_MAX_SZ \
- (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
-#define GM_RXF_LNG_ERR \
- (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
-#define GM_RXF_JAB_PKT \
- (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
- /* GM_MIB_CNT_BASE + 168: reserved */
-#define GM_RXE_FIFO_OV \
- (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
- /* GM_MIB_CNT_BASE + 184: reserved */
-#define GM_TXF_UC_OK \
- (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
-#define GM_TXF_BC_OK \
- (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
-#define GM_TXF_MPAUSE \
- (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
-#define GM_TXF_MC_OK \
- (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
-#define GM_TXO_OK_LO \
- (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
-#define GM_TXO_OK_HI \
- (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
-#define GM_TXF_64B \
- (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
-#define GM_TXF_127B \
- (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
-#define GM_TXF_255B \
- (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
-#define GM_TXF_511B \
- (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
-#define GM_TXF_1023B \
- (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
-#define GM_TXF_1518B \
- (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
-#define GM_TXF_MAX_SZ \
- (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
- /* GM_MIB_CNT_BASE + 296: reserved */
-#define GM_TXF_COL \
- (GM_MIB_CNT_BASE + 304) /* Tx Collision */
-#define GM_TXF_LAT_COL \
- (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
-#define GM_TXF_ABO_COL \
- (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
-#define GM_TXF_MUL_COL \
- (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
-#define GM_TXF_SNG_COL \
- (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
-#define GM_TXE_FIFO_UR \
- (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
-
-/*----------------------------------------------------------------------------*/
-/*
- * GMAC Bit Definitions
- *
- * If the bit access behaviour differs from the register access behaviour
- * (r/w, r/o) this is documented after the bit number.
- * The following bit access behaviours are used:
- * (sc) self clearing
- * (r/o) read only
- */
-
-/* GM_GP_STAT 16 bit r/o General Purpose Status Register */
-#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */
-#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */
-#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */
-#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */
-#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */
-#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */
-#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */
-#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */
- /* Bit 7..6: reserved */
-#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */
-#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */
-#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */
-#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */
-#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */
- /* Bit 0: reserved */
-
-/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
- /* Bit 15: reserved */
-#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */
-#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */
-#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */
-#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */
-#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */
-#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */
-#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */
-#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */
-#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */
-#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */
-#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */
-#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */
-#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */
-#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */
-#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */
-
-#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
-#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
- GM_GPCR_AU_SPD_DIS)
-
-/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
-#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */
-#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */
-#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */
-#define GM_TXCR_COL_THR_MSK (7<<10) /* Bit 12..10: Collision Threshold */
-
-#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
-
-#define TX_COL_DEF 0x04
-
-/* GM_RX_CTRL 16 bit r/w Receive Control Register */
-#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */
-#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */
-#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */
-#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */
-
-/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
-#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */
-#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */
-#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */
- /* Bit 3..0: reserved */
-
-#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
-#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
-#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
-
-#define TX_JAM_LEN_DEF 0x03
-#define TX_JAM_IPG_DEF 0x0b
-#define TX_IPG_JAM_DEF 0x1c
-
-/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */
-#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */
-#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */
-#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */
-#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */
- /* Bit 7..5: reserved */
-#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
-
-#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK)
-#define DATA_BLIND_DEF 0x04
-
-#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK)
-#define IPG_DATA_DEF 0x1e
-
-/* GM_SMI_CTRL 16 bit r/w SMI Control Register */
-#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */
-#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */
-#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/
-#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */
-#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */
- /* Bit 2..0: reserved */
-
-#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
-#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
-
- /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */
- /* Bit 15..6: reserved */
-#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */
-#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */
- /* Bit 3..0: reserved */
-
-/* Receive Frame Status Encoding */
-#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */
- /* Bit 15..14: reserved */
-#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */
-#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */
-#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */
-#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */
-#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */
-#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */
-#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */
-#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */
-#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */
-#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */
-#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */
- /* Bit 2: reserved */
-#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */
-#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */
-
-/*
- * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
- */
-#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
- GMR_FS_LONG_ERR | \
- GMR_FS_MII_ERR | \
- GMR_FS_BAD_FC | \
- GMR_FS_GOOD_FC | \
- GMR_FS_JABBER)
-
-/* Rx GMAC FIFO Flush Mask (default) */
-#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \
- GMR_FS_RX_FF_OV | \
- GMR_FS_MII_ERR | \
- GMR_FS_BAD_FC | \
- GMR_FS_GOOD_FC | \
- GMR_FS_UN_SIZE | \
- GMR_FS_JABBER)
-
-/* typedefs *******************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
deleted file mode 100644
index 6e6c56aa6d6f..000000000000
--- a/drivers/net/sk98lin/skaddr.c
+++ /dev/null
@@ -1,1788 +0,0 @@
-/******************************************************************************
- *
- * Name: skaddr.c
- * Project: Gigabit Ethernet Adapters, ADDR-Module
- * Version: $Revision: 1.52 $
- * Date: $Date: 2003/06/02 13:46:15 $
- * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage multicast addresses, address override,
- * and promiscuous mode on GEnesis and Yukon adapters.
- *
- * Address Layout:
- * port address: physical MAC address
- * 1st exact match: logical MAC address (GEnesis only)
- * 2nd exact match: RLMT multicast (GEnesis only)
- * exact match 3-13: OS-specific multicasts (GEnesis only)
- *
- * Include File Hierarchy:
- *
- * "skdrv1st.h"
- * "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
-#endif /* DEBUG ||!LINT || !SK_SLIM */
-
-#define __SKADDR_C
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-
-#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */
-#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */
-#define HASH_BITS 6 /* #bits in hash */
-#define SK_MC_BIT 0x01
-
-/* Error numbers and messages. */
-
-#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0)
-#define SKERR_ADDR_E001MSG "Bad Flags."
-#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1)
-#define SKERR_ADDR_E002MSG "New Error."
-
-/* typedefs *******************************************************************/
-
-/* None. */
-
-/* global variables ***********************************************************/
-
-/* 64-bit hash values with all bits set. */
-
-static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-
-/* local variables ************************************************************/
-
-#ifdef DEBUG
-static int Next0[SK_MAX_MACS] = {0};
-#endif /* DEBUG */
-
-static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
- SK_MAC_ADDR *pMc, int Flags);
-static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
- int Flags);
-static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
-static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
- SK_U32 PortNumber, int NewPromMode);
-static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
- SK_MAC_ADDR *pMc, int Flags);
-static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
- int Flags);
-static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
-static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
- SK_U32 PortNumber, int NewPromMode);
-
-/* functions ******************************************************************/
-
-/******************************************************************************
- *
- * SkAddrInit - initialize data, set state to init
- *
- * Description:
- *
- * SK_INIT_DATA
- * ============
- *
- * This routine clears the multicast tables and resets promiscuous mode.
- * Some entries are reserved for the "logical MAC address", the
- * SK-RLMT multicast address, and the BPDU multicast address.
- *
- *
- * SK_INIT_IO
- * ==========
- *
- * All permanent MAC addresses are read from EPROM.
- * If the current MAC addresses are not already set in software,
- * they are set to the values of the permanent addresses.
- * The current addresses are written to the corresponding MAC.
- *
- *
- * SK_INIT_RUN
- * ===========
- *
- * Nothing.
- *
- * Context:
- * init, pageable
- *
- * Returns:
- * SK_ADDR_SUCCESS
- */
-int SkAddrInit(
-SK_AC *pAC, /* the adapter context */
-SK_IOC IoC, /* I/O context */
-int Level) /* initialization level */
-{
- int j;
- SK_U32 i;
- SK_U8 *InAddr;
- SK_U16 *OutAddr;
- SK_ADDR_PORT *pAPort;
-
- switch (Level) {
- case SK_INIT_DATA:
- SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0,
- (SK_U16) sizeof(SK_ADDR));
-
- for (i = 0; i < SK_MAX_MACS; i++) {
- pAPort = &pAC->Addr.Port[i];
- pAPort->PromMode = SK_PROM_MODE_NONE;
-
- pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
- pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
- pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
- pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
- }
-#ifdef xDEBUG
- for (i = 0; i < SK_MAX_MACS; i++) {
- if (pAC->Addr.Port[i].NextExactMatchRlmt <
- SK_ADDR_FIRST_MATCH_RLMT) {
- Next0[i] |= 4;
- }
- }
-#endif /* DEBUG */
- /* pAC->Addr.InitDone = SK_INIT_DATA; */
- break;
-
- case SK_INIT_IO:
-#ifndef SK_NO_RLMT
- for (i = 0; i < SK_MAX_NETS; i++) {
- pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
- }
-#endif /* !SK_NO_RLMT */
-#ifdef xDEBUG
- for (i = 0; i < SK_MAX_MACS; i++) {
- if (pAC->Addr.Port[i].NextExactMatchRlmt <
- SK_ADDR_FIRST_MATCH_RLMT) {
- Next0[i] |= 8;
- }
- }
-#endif /* DEBUG */
-
- /* Read permanent logical MAC address from Control Register File. */
- for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
- InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
- SK_IN8(IoC, B2_MAC_1 + j, InAddr);
- }
-
- if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
- /* Set the current logical MAC address to the permanent one. */
- pAC->Addr.Net[0].CurrentMacAddress =
- pAC->Addr.Net[0].PermanentMacAddress;
- pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
- }
-
- /* Set the current logical MAC address. */
- pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
- pAC->Addr.Net[0].CurrentMacAddress;
-#if SK_MAX_NETS > 1
- /* Set logical MAC address for net 2 to (log | 3). */
- if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
- pAC->Addr.Net[1].PermanentMacAddress =
- pAC->Addr.Net[0].PermanentMacAddress;
- pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
- /* Set the current logical MAC address to the permanent one. */
- pAC->Addr.Net[1].CurrentMacAddress =
- pAC->Addr.Net[1].PermanentMacAddress;
- pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
- }
-#endif /* SK_MAX_NETS > 1 */
-
-#ifdef DEBUG
- for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
- ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
- i,
- pAC->Addr.Net[i].PermanentMacAddress.a[0],
- pAC->Addr.Net[i].PermanentMacAddress.a[1],
- pAC->Addr.Net[i].PermanentMacAddress.a[2],
- pAC->Addr.Net[i].PermanentMacAddress.a[3],
- pAC->Addr.Net[i].PermanentMacAddress.a[4],
- pAC->Addr.Net[i].PermanentMacAddress.a[5]))
-
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
- ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
- i,
- pAC->Addr.Net[i].CurrentMacAddress.a[0],
- pAC->Addr.Net[i].CurrentMacAddress.a[1],
- pAC->Addr.Net[i].CurrentMacAddress.a[2],
- pAC->Addr.Net[i].CurrentMacAddress.a[3],
- pAC->Addr.Net[i].CurrentMacAddress.a[4],
- pAC->Addr.Net[i].CurrentMacAddress.a[5]))
- }
-#endif /* DEBUG */
-
- for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
- pAPort = &pAC->Addr.Port[i];
-
- /* Read permanent port addresses from Control Register File. */
- for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
- InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
- SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
- }
-
- if (!pAPort->CurrentMacAddressSet) {
- /*
- * Set the current and previous physical MAC address
- * of this port to its permanent MAC address.
- */
- pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
- pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
- pAPort->CurrentMacAddressSet = SK_TRUE;
- }
-
- /* Set port's current physical MAC address. */
- OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- XM_OUTADDR(IoC, i, XM_SA, OutAddr);
- }
-#endif /* GENESIS */
-#ifdef YUKON
- if (!pAC->GIni.GIGenesis) {
- GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
- }
-#endif /* YUKON */
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
- ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAPort->PermanentMacAddress.a[0],
- pAPort->PermanentMacAddress.a[1],
- pAPort->PermanentMacAddress.a[2],
- pAPort->PermanentMacAddress.a[3],
- pAPort->PermanentMacAddress.a[4],
- pAPort->PermanentMacAddress.a[5]))
-
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
- ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAPort->CurrentMacAddress.a[0],
- pAPort->CurrentMacAddress.a[1],
- pAPort->CurrentMacAddress.a[2],
- pAPort->CurrentMacAddress.a[3],
- pAPort->CurrentMacAddress.a[4],
- pAPort->CurrentMacAddress.a[5]))
-#endif /* DEBUG */
- }
- /* pAC->Addr.InitDone = SK_INIT_IO; */
- break;
-
- case SK_INIT_RUN:
-#ifdef xDEBUG
- for (i = 0; i < SK_MAX_MACS; i++) {
- if (pAC->Addr.Port[i].NextExactMatchRlmt <
- SK_ADDR_FIRST_MATCH_RLMT) {
- Next0[i] |= 16;
- }
- }
-#endif /* DEBUG */
-
- /* pAC->Addr.InitDone = SK_INIT_RUN; */
- break;
-
- default: /* error */
- break;
- }
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrInit */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- * SkAddrMcClear - clear the multicast table
- *
- * Description:
- * This routine clears the multicast table.
- *
- * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- * immediately.
- *
- * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
- * to the adapter in use. The real work is done there.
- *
- * Context:
- * runtime, pageable
- * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- * may be called after SK_INIT_IO without limitation
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-int SkAddrMcClear(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Index of affected port */
-int Flags) /* permanent/non-perm, sw-only */
-{
- int ReturnCode;
-
- if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-
- if (pAC->GIni.GIGenesis) {
- ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
- }
- else {
- ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
- }
-
- return (ReturnCode);
-
-} /* SkAddrMcClear */
-
-#endif /* !SK_SLIM */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- * SkAddrXmacMcClear - clear the multicast table
- *
- * Description:
- * This routine clears the multicast table
- * (either entry 2 or entries 3-16 and InexactFilter) of the given port.
- * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- * immediately.
- *
- * Context:
- * runtime, pageable
- * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- * may be called after SK_INIT_IO without limitation
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-static int SkAddrXmacMcClear(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Index of affected port */
-int Flags) /* permanent/non-perm, sw-only */
-{
- int i;
-
- if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
-
- /* Clear RLMT multicast addresses. */
- pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
- }
- else { /* not permanent => DRV */
-
- /* Clear InexactFilter */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
- }
-
- /* Clear DRV multicast addresses. */
-
- pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
- }
-
- if (!(Flags & SK_MC_SW_ONLY)) {
- (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
- }
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrXmacMcClear */
-
-#endif /* !SK_SLIM */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- * SkAddrGmacMcClear - clear the multicast table
- *
- * Description:
- * This routine clears the multicast hashing table (InexactFilter)
- * (either the RLMT or the driver bits) of the given port.
- *
- * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
- * immediately.
- *
- * Context:
- * runtime, pageable
- * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
- * may be called after SK_INIT_IO without limitation
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-static int SkAddrGmacMcClear(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Index of affected port */
-int Flags) /* permanent/non-perm, sw-only */
-{
- int i;
-
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
-#endif /* DEBUG */
-
- /* Clear InexactFilter */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
- }
-
- if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
-
- /* Copy DRV bits to InexactFilter. */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
-
- /* Clear InexactRlmtFilter. */
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
-
- }
- }
- else { /* not permanent => DRV */
-
- /* Copy RLMT bits to InexactFilter. */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
-
- /* Clear InexactDrvFilter. */
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
- }
- }
-
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
-#endif /* DEBUG */
-
- if (!(Flags & SK_MC_SW_ONLY)) {
- (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
- }
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrGmacMcClear */
-
-#ifndef SK_ADDR_CHEAT
-
-/******************************************************************************
- *
- * SkXmacMcHash - hash multicast address
- *
- * Description:
- * This routine computes the hash value for a multicast address.
- * A CRC32 algorithm is used.
- *
- * Notes:
- * The code was adapted from the XaQti data sheet.
- *
- * Context:
- * runtime, pageable
- *
- * Returns:
- * Hash value of multicast address.
- */
-static SK_U32 SkXmacMcHash(
-unsigned char *pMc) /* Multicast address */
-{
- SK_U32 Idx;
- SK_U32 Bit;
- SK_U32 Data;
- SK_U32 Crc;
-
- Crc = 0xFFFFFFFFUL;
- for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
- Data = *pMc++;
- for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
- Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
- }
- }
-
- return (Crc & ((1 << HASH_BITS) - 1));
-
-} /* SkXmacMcHash */
-
-
-/******************************************************************************
- *
- * SkGmacMcHash - hash multicast address
- *
- * Description:
- * This routine computes the hash value for a multicast address.
- * A CRC16 algorithm is used.
- *
- * Notes:
- *
- *
- * Context:
- * runtime, pageable
- *
- * Returns:
- * Hash value of multicast address.
- */
-static SK_U32 SkGmacMcHash(
-unsigned char *pMc) /* Multicast address */
-{
- SK_U32 Data;
- SK_U32 TmpData;
- SK_U32 Crc;
- int Byte;
- int Bit;
-
- Crc = 0xFFFFFFFFUL;
- for (Byte = 0; Byte < 6; Byte++) {
- /* Get next byte. */
- Data = (SK_U32) pMc[Byte];
-
- /* Change bit order in byte. */
- TmpData = Data;
- for (Bit = 0; Bit < 8; Bit++) {
- if (TmpData & 1L) {
- Data |= 1L << (7 - Bit);
- }
- else {
- Data &= ~(1L << (7 - Bit));
- }
- TmpData >>= 1;
- }
-
- Crc ^= (Data << 24);
- for (Bit = 0; Bit < 8; Bit++) {
- if (Crc & 0x80000000) {
- Crc = (Crc << 1) ^ GMAC_POLY;
- }
- else {
- Crc <<= 1;
- }
- }
- }
-
- return (Crc & ((1 << HASH_BITS) - 1));
-
-} /* SkGmacMcHash */
-
-#endif /* !SK_ADDR_CHEAT */
-
-/******************************************************************************
- *
- * SkAddrMcAdd - add a multicast address to a port
- *
- * Description:
- * This routine enables reception for a given address on the given port.
- *
- * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
- * adapter in use. The real work is done there.
- *
- * Notes:
- * The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_DATA
- *
- * Returns:
- * SK_MC_FILTERING_EXACT
- * SK_MC_FILTERING_INEXACT
- * SK_MC_ILLEGAL_ADDRESS
- * SK_MC_ILLEGAL_PORT
- * SK_MC_RLMT_OVERFLOW
- */
-int SkAddrMcAdd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Port Number */
-SK_MAC_ADDR *pMc, /* multicast address to be added */
-int Flags) /* permanent/non-permanent */
-{
- int ReturnCode;
-
- if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-
- if (pAC->GIni.GIGenesis) {
- ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
- }
- else {
- ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
- }
-
- return (ReturnCode);
-
-} /* SkAddrMcAdd */
-
-
-/******************************************************************************
- *
- * SkAddrXmacMcAdd - add a multicast address to a port
- *
- * Description:
- * This routine enables reception for a given address on the given port.
- *
- * Notes:
- * The return code is only valid for SK_PROM_MODE_NONE.
- *
- * The multicast bit is only checked if there are no free exact match
- * entries.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_DATA
- *
- * Returns:
- * SK_MC_FILTERING_EXACT
- * SK_MC_FILTERING_INEXACT
- * SK_MC_ILLEGAL_ADDRESS
- * SK_MC_RLMT_OVERFLOW
- */
-static int SkAddrXmacMcAdd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Port Number */
-SK_MAC_ADDR *pMc, /* multicast address to be added */
-int Flags) /* permanent/non-permanent */
-{
- int i;
- SK_U8 Inexact;
-#ifndef SK_ADDR_CHEAT
- SK_U32 HashBit;
-#endif /* !defined(SK_ADDR_CHEAT) */
-
- if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
-#ifdef xDEBUG
- if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
- SK_ADDR_FIRST_MATCH_RLMT) {
- Next0[PortNumber] |= 1;
- return (SK_MC_RLMT_OVERFLOW);
- }
-#endif /* DEBUG */
-
- if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
- SK_ADDR_LAST_MATCH_RLMT) {
- return (SK_MC_RLMT_OVERFLOW);
- }
-
- /* Set a RLMT multicast address. */
-
- pAC->Addr.Port[PortNumber].Exact[
- pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
-
- return (SK_MC_FILTERING_EXACT);
- }
-
-#ifdef xDEBUG
- if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
- SK_ADDR_FIRST_MATCH_DRV) {
- Next0[PortNumber] |= 2;
- return (SK_MC_RLMT_OVERFLOW);
- }
-#endif /* DEBUG */
-
- if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
-
- /* Set exact match entry. */
- pAC->Addr.Port[PortNumber].Exact[
- pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
-
- /* Clear InexactFilter */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
- }
- }
- else {
- if (!(pMc->a[0] & SK_MC_BIT)) {
- /* Hashing only possible with multicast addresses */
- return (SK_MC_ILLEGAL_ADDRESS);
- }
-#ifndef SK_ADDR_CHEAT
- /* Compute hash value of address. */
- HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
-
- /* Add bit to InexactFilter. */
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
- 1 << (HashBit % 8);
-#else /* SK_ADDR_CHEAT */
- /* Set all bits in InexactFilter. */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
- }
-#endif /* SK_ADDR_CHEAT */
- }
-
- for (Inexact = 0, i = 0; i < 8; i++) {
- Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
- }
-
- if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
- return (SK_MC_FILTERING_EXACT);
- }
- else {
- return (SK_MC_FILTERING_INEXACT);
- }
-
-} /* SkAddrXmacMcAdd */
-
-
-/******************************************************************************
- *
- * SkAddrGmacMcAdd - add a multicast address to a port
- *
- * Description:
- * This routine enables reception for a given address on the given port.
- *
- * Notes:
- * The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_DATA
- *
- * Returns:
- * SK_MC_FILTERING_INEXACT
- * SK_MC_ILLEGAL_ADDRESS
- */
-static int SkAddrGmacMcAdd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Port Number */
-SK_MAC_ADDR *pMc, /* multicast address to be added */
-int Flags) /* permanent/non-permanent */
-{
- int i;
-#ifndef SK_ADDR_CHEAT
- SK_U32 HashBit;
-#endif /* !defined(SK_ADDR_CHEAT) */
-
- if (!(pMc->a[0] & SK_MC_BIT)) {
- /* Hashing only possible with multicast addresses */
- return (SK_MC_ILLEGAL_ADDRESS);
- }
-
-#ifndef SK_ADDR_CHEAT
-
- /* Compute hash value of address. */
- HashBit = SkGmacMcHash(&pMc->a[0]);
-
- if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
-
- /* Add bit to InexactRlmtFilter. */
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
- 1 << (HashBit % 8);
-
- /* Copy bit to InexactFilter. */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
- }
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
- pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
-#endif /* DEBUG */
- }
- else { /* not permanent => DRV */
-
- /* Add bit to InexactDrvFilter. */
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
- 1 << (HashBit % 8);
-
- /* Copy bit to InexactFilter. */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
- }
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
- pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
-#endif /* DEBUG */
- }
-
-#else /* SK_ADDR_CHEAT */
-
- /* Set all bits in InexactFilter. */
- for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
- }
-#endif /* SK_ADDR_CHEAT */
-
- return (SK_MC_FILTERING_INEXACT);
-
-} /* SkAddrGmacMcAdd */
-
-#endif /* !SK_SLIM */
-
-/******************************************************************************
- *
- * SkAddrMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- * This routine enables reception of the addresses contained in a local
- * table for a given port.
- * It also programs the port's current physical MAC address.
- *
- * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
- * to the adapter in use. The real work is done there.
- *
- * Notes:
- * The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_MC_FILTERING_EXACT
- * SK_MC_FILTERING_INEXACT
- * SK_ADDR_ILLEGAL_PORT
- */
-int SkAddrMcUpdate(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber) /* Port Number */
-{
- int ReturnCode = 0;
-#if (!defined(SK_SLIM) || defined(DEBUG))
- if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-#endif /* !SK_SLIM || DEBUG */
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
- }
-#endif /* GENESIS */
-#ifdef YUKON
- if (!pAC->GIni.GIGenesis) {
- ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
- }
-#endif /* YUKON */
- return (ReturnCode);
-
-} /* SkAddrMcUpdate */
-
-
-#ifdef GENESIS
-
-/******************************************************************************
- *
- * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- * This routine enables reception of the addresses contained in a local
- * table for a given port.
- * It also programs the port's current physical MAC address.
- *
- * Notes:
- * The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_MC_FILTERING_EXACT
- * SK_MC_FILTERING_INEXACT
- * SK_ADDR_ILLEGAL_PORT
- */
-static int SkAddrXmacMcUpdate(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber) /* Port Number */
-{
- SK_U32 i;
- SK_U8 Inexact;
- SK_U16 *OutAddr;
- SK_ADDR_PORT *pAPort;
-
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
-
- pAPort = &pAC->Addr.Port[PortNumber];
-
-#ifdef DEBUG
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
-#endif /* DEBUG */
-
- /* Start with 0 to also program the logical MAC address. */
- for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
- /* Set exact match address i on XMAC */
- OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
- XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
- }
-
- /* Clear other permanent exact match addresses on XMAC */
- if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
-
- SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
- SK_ADDR_LAST_MATCH_RLMT);
- }
-
- for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
- OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
- XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
- }
-
- /* Clear other non-permanent exact match addresses on XMAC */
- if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
-
- SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
- SK_ADDR_LAST_MATCH_DRV);
- }
-
- for (Inexact = 0, i = 0; i < 8; i++) {
- Inexact |= pAPort->InexactFilter.Bytes[i];
- }
-
- if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
-
- /* Set all bits in 64-bit hash register. */
- XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- else if (Inexact != 0) {
-
- /* Set 64-bit hash register to InexactFilter. */
- XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- else {
- /* Disable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
- }
-
- if (pAPort->PromMode != SK_PROM_MODE_NONE) {
- (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
- }
-
- /* Set port's current physical MAC address. */
- OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
-
- XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
-
-#ifdef xDEBUG
- for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
- SK_U8 InAddr8[6];
- SK_U16 *InAddr;
-
- /* Get exact match address i from port PortNumber. */
- InAddr = (SK_U16 *) &InAddr8[0];
-
- XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
-
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
- "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
- i,
- PortNumber,
- InAddr8[0],
- InAddr8[1],
- InAddr8[2],
- InAddr8[3],
- InAddr8[4],
- InAddr8[5],
- pAPort->Exact[i].a[0],
- pAPort->Exact[i].a[1],
- pAPort->Exact[i].a[2],
- pAPort->Exact[i].a[3],
- pAPort->Exact[i].a[4],
- pAPort->Exact[i].a[5]))
- }
-#endif /* DEBUG */
-
- /* Determine return value. */
- if (Inexact == 0 && pAPort->PromMode == 0) {
- return (SK_MC_FILTERING_EXACT);
- }
- else {
- return (SK_MC_FILTERING_INEXACT);
- }
-
-} /* SkAddrXmacMcUpdate */
-
-#endif /* GENESIS */
-
-#ifdef YUKON
-
-/******************************************************************************
- *
- * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
- *
- * Description:
- * This routine enables reception of the addresses contained in a local
- * table for a given port.
- * It also programs the port's current physical MAC address.
- *
- * Notes:
- * The return code is only valid for SK_PROM_MODE_NONE.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_MC_FILTERING_EXACT
- * SK_MC_FILTERING_INEXACT
- * SK_ADDR_ILLEGAL_PORT
- */
-static int SkAddrGmacMcUpdate(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber) /* Port Number */
-{
-#ifndef SK_SLIM
- SK_U32 i;
- SK_U8 Inexact;
-#endif /* not SK_SLIM */
- SK_U16 *OutAddr;
- SK_ADDR_PORT *pAPort;
-
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
-
- pAPort = &pAC->Addr.Port[PortNumber];
-
-#ifdef DEBUG
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
-#endif /* DEBUG */
-
-#ifndef SK_SLIM
- for (Inexact = 0, i = 0; i < 8; i++) {
- Inexact |= pAPort->InexactFilter.Bytes[i];
- }
-
- /* Set 64-bit hash register to InexactFilter. */
- GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
- &pAPort->InexactFilter.Bytes[0]);
-
- if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
-
- /* Set all bits in 64-bit hash register. */
- GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- else {
- /* Enable Hashing. */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
-
- if (pAPort->PromMode != SK_PROM_MODE_NONE) {
- (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
- }
-#else /* SK_SLIM */
-
- /* Set all bits in 64-bit hash register. */
- GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
-
- (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
-
-#endif /* SK_SLIM */
-
- /* Set port's current physical MAC address. */
- OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
- GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
-
- /* Set port's current logical MAC address. */
- OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
- GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
-
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAPort->Exact[0].a[0],
- pAPort->Exact[0].a[1],
- pAPort->Exact[0].a[2],
- pAPort->Exact[0].a[3],
- pAPort->Exact[0].a[4],
- pAPort->Exact[0].a[5]))
-
- SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAPort->CurrentMacAddress.a[0],
- pAPort->CurrentMacAddress.a[1],
- pAPort->CurrentMacAddress.a[2],
- pAPort->CurrentMacAddress.a[3],
- pAPort->CurrentMacAddress.a[4],
- pAPort->CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-
-#ifndef SK_SLIM
- /* Determine return value. */
- if (Inexact == 0 && pAPort->PromMode == 0) {
- return (SK_MC_FILTERING_EXACT);
- }
- else {
- return (SK_MC_FILTERING_INEXACT);
- }
-#else /* SK_SLIM */
- return (SK_MC_FILTERING_INEXACT);
-#endif /* SK_SLIM */
-
-} /* SkAddrGmacMcUpdate */
-
-#endif /* YUKON */
-
-#ifndef SK_NO_MAO
-
-/******************************************************************************
- *
- * SkAddrOverride - override a port's MAC address
- *
- * Description:
- * This routine overrides the MAC address of one port.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_ADDR_SUCCESS if successful.
- * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
- * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
- * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
- */
-int SkAddrOverride(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* Port Number */
-SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */
-int Flags) /* logical/physical MAC address */
-{
-#ifndef SK_NO_RLMT
- SK_EVPARA Para;
-#endif /* !SK_NO_RLMT */
- SK_U32 NetNumber;
- SK_U32 i;
- SK_U16 SK_FAR *OutAddr;
-
-#ifndef SK_NO_RLMT
- NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
-#else
- NetNumber = 0;
-#endif /* SK_NO_RLMT */
-#if (!defined(SK_SLIM) || defined(DEBUG))
- if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-#endif /* !SK_SLIM || DEBUG */
- if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
- return (SK_ADDR_MULTICAST_ADDRESS);
- }
-
- if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
- return (SK_ADDR_TOO_EARLY);
- }
-
- if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */
- /* Parameter *pNewAddr is ignored. */
- for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
- if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
- return (SK_ADDR_TOO_EARLY);
- }
- }
-#ifndef SK_NO_RLMT
- /* Set PortNumber to number of net's active port. */
- PortNumber = pAC->Rlmt.Net[NetNumber].
- Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-#endif /* !SK_NO_RLMT */
- pAC->Addr.Port[PortNumber].Exact[0] =
- pAC->Addr.Net[NetNumber].CurrentMacAddress;
-
- /* Write address to first exact match entry of active port. */
- (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
- }
- else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
- /* Deactivate logical MAC address. */
- /* Parameter *pNewAddr is ignored. */
- for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
- if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
- return (SK_ADDR_TOO_EARLY);
- }
- }
-#ifndef SK_NO_RLMT
- /* Set PortNumber to number of net's active port. */
- PortNumber = pAC->Rlmt.Net[NetNumber].
- Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-#endif /* !SK_NO_RLMT */
- for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
- pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
- }
-
- /* Write address to first exact match entry of active port. */
- (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
- }
- else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */
- if (SK_ADDR_EQUAL(pNewAddr->a,
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
- return (SK_ADDR_DUPLICATE_ADDRESS);
- }
-
- for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
- if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
- return (SK_ADDR_TOO_EARLY);
- }
-
- if (SK_ADDR_EQUAL(pNewAddr->a,
- pAC->Addr.Port[i].CurrentMacAddress.a)) {
- if (i == PortNumber) {
- return (SK_ADDR_SUCCESS);
- }
- else {
- return (SK_ADDR_DUPLICATE_ADDRESS);
- }
- }
- }
-
- pAC->Addr.Port[PortNumber].PreviousMacAddress =
- pAC->Addr.Port[PortNumber].CurrentMacAddress;
- pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
-
- /* Change port's physical MAC address. */
- OutAddr = (SK_U16 SK_FAR *) pNewAddr;
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
- }
-#endif /* GENESIS */
-#ifdef YUKON
- if (!pAC->GIni.GIGenesis) {
- GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
- }
-#endif /* YUKON */
-
-#ifndef SK_NO_RLMT
- /* Report address change to RLMT. */
- Para.Para32[0] = PortNumber;
- Para.Para32[0] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
-#endif /* !SK_NO_RLMT */
- }
- else { /* Logical MAC address. */
- if (SK_ADDR_EQUAL(pNewAddr->a,
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
- return (SK_ADDR_SUCCESS);
- }
-
- for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
- if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
- return (SK_ADDR_TOO_EARLY);
- }
-
- if (SK_ADDR_EQUAL(pNewAddr->a,
- pAC->Addr.Port[i].CurrentMacAddress.a)) {
- return (SK_ADDR_DUPLICATE_ADDRESS);
- }
- }
-
- /*
- * In case that the physical and the logical MAC addresses are equal
- * we must also change the physical MAC address here.
- * In this case we have an adapter which initially was programmed with
- * two identical MAC addresses.
- */
- if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
- pAC->Addr.Port[PortNumber].Exact[0].a)) {
-
- pAC->Addr.Port[PortNumber].PreviousMacAddress =
- pAC->Addr.Port[PortNumber].CurrentMacAddress;
- pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
-
-#ifndef SK_NO_RLMT
- /* Report address change to RLMT. */
- Para.Para32[0] = PortNumber;
- Para.Para32[0] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
-#endif /* !SK_NO_RLMT */
- }
-
-#ifndef SK_NO_RLMT
- /* Set PortNumber to number of net's active port. */
- PortNumber = pAC->Rlmt.Net[NetNumber].
- Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
-#endif /* !SK_NO_RLMT */
- pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
- pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
-#ifdef DEBUG
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
- pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
- pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
- pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
- pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
- pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
-
- SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
- ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
- pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
-#endif /* DEBUG */
-
- /* Write address to first exact match entry of active port. */
- (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
- }
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrOverride */
-
-
-#endif /* SK_NO_MAO */
-
-/******************************************************************************
- *
- * SkAddrPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- * This routine manages promiscuous mode:
- * - none
- * - all LLC frames
- * - all MC frames
- *
- * It calls either SkAddrXmacPromiscuousChange or
- * SkAddrGmacPromiscuousChange, according to the adapter in use.
- * The real work is done there.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-int SkAddrPromiscuousChange(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* port whose promiscuous mode changes */
-int NewPromMode) /* new promiscuous mode */
-{
- int ReturnCode = 0;
-#if (!defined(SK_SLIM) || defined(DEBUG))
- if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-#endif /* !SK_SLIM || DEBUG */
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- ReturnCode =
- SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
- }
-#endif /* GENESIS */
-#ifdef YUKON
- if (!pAC->GIni.GIGenesis) {
- ReturnCode =
- SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
- }
-#endif /* YUKON */
-
- return (ReturnCode);
-
-} /* SkAddrPromiscuousChange */
-
-#ifdef GENESIS
-
-/******************************************************************************
- *
- * SkAddrXmacPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- * This routine manages promiscuous mode:
- * - none
- * - all LLC frames
- * - all MC frames
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-static int SkAddrXmacPromiscuousChange(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* port whose promiscuous mode changes */
-int NewPromMode) /* new promiscuous mode */
-{
- int i;
- SK_BOOL InexactModeBit;
- SK_U8 Inexact;
- SK_U8 HwInexact;
- SK_FILTER64 HwInexactFilter;
- SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */
- int CurPromMode = SK_PROM_MODE_NONE;
-
- /* Read CurPromMode from Hardware. */
- XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
-
- if ((LoMode & XM_MD_ENA_PROM) != 0) {
- /* Promiscuous mode! */
- CurPromMode |= SK_PROM_MODE_LLC;
- }
-
- for (Inexact = 0xFF, i = 0; i < 8; i++) {
- Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
- }
- if (Inexact == 0xFF) {
- CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
- }
- else {
- /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
- XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
-
- InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
-
- /* Read 64-bit hash register from XMAC */
- XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
-
- for (HwInexact = 0xFF, i = 0; i < 8; i++) {
- HwInexact &= HwInexactFilter.Bytes[i];
- }
-
- if (InexactModeBit && (HwInexact == 0xFF)) {
- CurPromMode |= SK_PROM_MODE_ALL_MC;
- }
- }
-
- pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
-
- if (NewPromMode == CurPromMode) {
- return (SK_ADDR_SUCCESS);
- }
-
- if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
- !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
-
- /* Set all bits in 64-bit hash register. */
- XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
- !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
- for (Inexact = 0, i = 0; i < 8; i++) {
- Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
- }
- if (Inexact == 0) {
- /* Disable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
- }
- else {
- /* Set 64-bit hash register to InexactFilter. */
- XM_OUTHASH(IoC, PortNumber, XM_HSM,
- &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- }
-
- if ((NewPromMode & SK_PROM_MODE_LLC) &&
- !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
- /* Set the MAC in Promiscuous Mode */
- SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- else if ((CurPromMode & SK_PROM_MODE_LLC) &&
- !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */
- /* Clear Promiscuous Mode */
- SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
- }
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrXmacPromiscuousChange */
-
-#endif /* GENESIS */
-
-#ifdef YUKON
-
-/******************************************************************************
- *
- * SkAddrGmacPromiscuousChange - set promiscuous mode for given port
- *
- * Description:
- * This routine manages promiscuous mode:
- * - none
- * - all LLC frames
- * - all MC frames
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-static int SkAddrGmacPromiscuousChange(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortNumber, /* port whose promiscuous mode changes */
-int NewPromMode) /* new promiscuous mode */
-{
- SK_U16 ReceiveControl; /* GMAC Receive Control Register */
- int CurPromMode = SK_PROM_MODE_NONE;
-
- /* Read CurPromMode from Hardware. */
- GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
-
- if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
- /* Promiscuous mode! */
- CurPromMode |= SK_PROM_MODE_LLC;
- }
-
- if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
- /* All Multicast mode! */
- CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
- }
-
- pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
-
- if (NewPromMode == CurPromMode) {
- return (SK_ADDR_SUCCESS);
- }
-
- if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
- !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
-
- /* Set all bits in 64-bit hash register. */
- GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
-
- /* Enable Hashing */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
-
- if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
- !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
-
- /* Set 64-bit hash register to InexactFilter. */
- GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
- &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
-
- /* Enable Hashing. */
- SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
-
- if ((NewPromMode & SK_PROM_MODE_LLC) &&
- !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
-
- /* Set the MAC to Promiscuous Mode. */
- SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
- }
- else if ((CurPromMode & SK_PROM_MODE_LLC) &&
- !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */
-
- /* Clear Promiscuous Mode. */
- SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
- }
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrGmacPromiscuousChange */
-
-#endif /* YUKON */
-
-#ifndef SK_SLIM
-
-/******************************************************************************
- *
- * SkAddrSwap - swap address info
- *
- * Description:
- * This routine swaps address info of two ports.
- *
- * Context:
- * runtime, pageable
- * may be called after SK_INIT_IO
- *
- * Returns:
- * SK_ADDR_SUCCESS
- * SK_ADDR_ILLEGAL_PORT
- */
-int SkAddrSwap(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 FromPortNumber, /* Port1 Index */
-SK_U32 ToPortNumber) /* Port2 Index */
-{
- int i;
- SK_U8 Byte;
- SK_MAC_ADDR MacAddr;
- SK_U32 DWord;
-
- if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-
- if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-
- if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
- return (SK_ADDR_ILLEGAL_PORT);
- }
-
- /*
- * Swap:
- * - Exact Match Entries (GEnesis and Yukon)
- * Yukon uses first entry for the logical MAC
- * address (stored in the second GMAC register).
- * - FirstExactMatchRlmt (GEnesis only)
- * - NextExactMatchRlmt (GEnesis only)
- * - FirstExactMatchDrv (GEnesis only)
- * - NextExactMatchDrv (GEnesis only)
- * - 64-bit filter (InexactFilter)
- * - Promiscuous Mode
- * of ports.
- */
-
- for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
- MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
- pAC->Addr.Port[FromPortNumber].Exact[i] =
- pAC->Addr.Port[ToPortNumber].Exact[i];
- pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
- }
-
- for (i = 0; i < 8; i++) {
- Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
- pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
- pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
- pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
- }
-
- i = pAC->Addr.Port[FromPortNumber].PromMode;
- pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
- pAC->Addr.Port[ToPortNumber].PromMode = i;
-
- if (pAC->GIni.GIGenesis) {
- DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
- pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
- pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
- pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
-
- DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
- pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
- pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
- pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
-
- DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
- pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
- pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
- pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
-
- DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
- pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
- pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
- pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
- }
-
- /* CAUTION: Solution works if only ports of one adapter are in use. */
- for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
- Net->NetNumber].NumPorts; i++) {
- if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
- Port[i]->PortNumber == ToPortNumber) {
- pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
- ActivePort = i;
- /* 20001207 RA: Was "ToPortNumber;". */
- }
- }
-
- (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
- (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
-
- return (SK_ADDR_SUCCESS);
-
-} /* SkAddrSwap */
-
-#endif /* !SK_SLIM */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
deleted file mode 100644
index 37ce03fb8de3..000000000000
--- a/drivers/net/sk98lin/skdim.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/******************************************************************************
- *
- * Name: skdim.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.5 $
- * Date: $Date: 2003/11/28 12:55:40 $
- * Purpose: All functions to maintain interrupt moderation
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage the dynamic interrupt moderation on both
- * GEnesis and Yukon adapters.
- *
- * Include File Hierarchy:
- *
- * "skdrv1st.h"
- * "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef lint
-static const char SysKonnectFileId[] =
- "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
-#endif
-
-#define __SKADDR_C
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif
-
-/*******************************************************************************
-**
-** Includes
-**
-*******************************************************************************/
-
-#ifndef __INC_SKDRV1ST_H
-#include "h/skdrv1st.h"
-#endif
-
-#ifndef __INC_SKDRV2ND_H
-#include "h/skdrv2nd.h"
-#endif
-
-#include <linux/kernel_stat.h>
-
-/*******************************************************************************
-**
-** Defines
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Typedefs
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Local function prototypes
-**
-*******************************************************************************/
-
-static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
-static SK_U64 GetIsrCalls(SK_AC *pAC);
-static SK_BOOL IsIntModEnabled(SK_AC *pAC);
-static void SetCurrIntCtr(SK_AC *pAC);
-static void EnableIntMod(SK_AC *pAC);
-static void DisableIntMod(SK_AC *pAC);
-static void ResizeDimTimerDuration(SK_AC *pAC);
-static void DisplaySelectedModerationType(SK_AC *pAC);
-static void DisplaySelectedModerationMask(SK_AC *pAC);
-static void DisplayDescrRatio(SK_AC *pAC);
-
-/*******************************************************************************
-**
-** Global variables
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Local variables
-**
-*******************************************************************************/
-
-/*******************************************************************************
-**
-** Global functions
-**
-*******************************************************************************/
-
-/*******************************************************************************
-** Function : SkDimModerate
-** Description : Called in every ISR to check if moderation is to be applied
-** or not for the current number of interrupts
-** Programmer : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns : void (!)
-** Notes : -
-*******************************************************************************/
-
-void
-SkDimModerate(SK_AC *pAC) {
- unsigned int CurrSysLoad = 0; /* expressed in percent */
- unsigned int LoadIncrease = 0; /* expressed in percent */
- SK_U64 ThresholdInts = 0;
- SK_U64 IsrCallsPerSec = 0;
-
-#define M_DIMINFO pAC->DynIrqModInfo
-
- if (!IsIntModEnabled(pAC)) {
- if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
- CurrSysLoad = GetCurrentSystemLoad(pAC);
- if (CurrSysLoad > 75) {
- /*
- ** More than 75% total system load! Enable the moderation
- ** to shield the system against too many interrupts.
- */
- EnableIntMod(pAC);
- } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
- LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
- if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
- C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
- if (CurrSysLoad > 10) {
- /*
- ** More than 50% increase with respect to the
- ** previous load of the system. Most likely this
- ** is due to our ISR-proc...
- */
- EnableIntMod(pAC);
- }
- }
- } else {
- /*
- ** Neither too much system load at all nor too much increase
- ** with respect to the previous system load. Hence, we can leave
- ** the ISR-handling like it is without enabling moderation.
- */
- }
- M_DIMINFO.PrevSysLoad = CurrSysLoad;
- }
- } else {
- if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
- ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
- C_INT_MOD_DISABLE_PERCENTAGE) / 100);
- IsrCallsPerSec = GetIsrCalls(pAC);
- if (IsrCallsPerSec <= ThresholdInts) {
- /*
- ** The number of interrupts within the last second is
- ** lower than the disable_percentage of the desried
- ** maxrate. Therefore we can disable the moderation.
- */
- DisableIntMod(pAC);
- M_DIMINFO.MaxModIntsPerSec =
- (M_DIMINFO.MaxModIntsPerSecUpperLimit +
- M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
- } else {
- /*
- ** The number of interrupts per sec is the same as expected.
- ** Evalulate the descriptor-ratio. If it has changed, a resize
- ** in the moderation timer might be useful
- */
- if (M_DIMINFO.AutoSizing) {
- ResizeDimTimerDuration(pAC);
- }
- }
- }
- }
-
- /*
- ** Some information to the log...
- */
- if (M_DIMINFO.DisplayStats) {
- DisplaySelectedModerationType(pAC);
- DisplaySelectedModerationMask(pAC);
- DisplayDescrRatio(pAC);
- }
-
- M_DIMINFO.NbrProcessedDescr = 0;
- SetCurrIntCtr(pAC);
-}
-
-/*******************************************************************************
-** Function : SkDimStartModerationTimer
-** Description : Starts the audit-timer for the dynamic interrupt moderation
-** Programmer : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns : void (!)
-** Notes : -
-*******************************************************************************/
-
-void
-SkDimStartModerationTimer(SK_AC *pAC) {
- SK_EVPARA EventParam; /* Event struct for timer event */
-
- SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
- EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
- SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
- SK_DRV_MODERATION_TIMER_LENGTH,
- SKGE_DRV, SK_DRV_TIMER, EventParam);
-}
-
-/*******************************************************************************
-** Function : SkDimEnableModerationIfNeeded
-** Description : Either enables or disables moderation
-** Programmer : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns : void (!)
-** Notes : This function is called when a particular adapter is opened
-** There is no Disable function, because when all interrupts
-** might be disable, the moderation timer has no meaning at all
-******************************************************************************/
-
-void
-SkDimEnableModerationIfNeeded(SK_AC *pAC) {
-
- if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
- EnableIntMod(pAC); /* notification print in this function */
- } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
- SkDimStartModerationTimer(pAC);
- if (M_DIMINFO.DisplayStats) {
- printk("Dynamic moderation has been enabled\n");
- }
- } else {
- if (M_DIMINFO.DisplayStats) {
- printk("No moderation has been enabled\n");
- }
- }
-}
-
-/*******************************************************************************
-** Function : SkDimDisplayModerationSettings
-** Description : Displays the current settings regarding interrupt moderation
-** Programmer : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns : void (!)
-** Notes : -
-*******************************************************************************/
-
-void
-SkDimDisplayModerationSettings(SK_AC *pAC) {
- DisplaySelectedModerationType(pAC);
- DisplaySelectedModerationMask(pAC);
-}
-
-/*******************************************************************************
-**
-** Local functions
-**
-*******************************************************************************/
-
-/*******************************************************************************
-** Function : GetCurrentSystemLoad
-** Description : Retrieves the current system load of the system. This load
-** is evaluated for all processors within the system.
-** Programmer : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns : unsigned int: load expressed in percentage
-** Notes : The possible range being returned is from 0 up to 100.
-** Whereas 0 means 'no load at all' and 100 'system fully loaded'
-** It is impossible to determine what actually causes the system
-** to be in 100%, but maybe that is due to too much interrupts.
-*******************************************************************************/
-
-static unsigned int
-GetCurrentSystemLoad(SK_AC *pAC) {
- unsigned long jif = jiffies;
- unsigned int UserTime = 0;
- unsigned int SystemTime = 0;
- unsigned int NiceTime = 0;
- unsigned int IdleTime = 0;
- unsigned int TotalTime = 0;
- unsigned int UsedTime = 0;
- unsigned int SystemLoad = 0;
-
- /* unsigned int NbrCpu = 0; */
-
- /*
- ** The following lines have been commented out, because
- ** from kernel 2.5.44 onwards, the kernel-owned structure
- **
- ** struct kernel_stat kstat
- **
- ** is not marked as an exported symbol in the file
- **
- ** kernel/ksyms.c
- **
- ** As a consequence, using this driver as KLM is not possible
- ** and any access of the structure kernel_stat via the
- ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
- **
- ** The kstat-information might be added again in future
- ** versions of the 2.5.xx kernel, but for the time being,
- ** number of interrupts will serve as indication how much
- ** load we currently have...
- **
- ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
- ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user;
- ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice;
- ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
- ** }
- */
- SK_U64 ThresholdInts = 0;
- SK_U64 IsrCallsPerSec = 0;
-
- ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
- C_INT_MOD_ENABLE_PERCENTAGE) + 100);
- IsrCallsPerSec = GetIsrCalls(pAC);
- if (IsrCallsPerSec >= ThresholdInts) {
- /*
- ** We do not know how much the real CPU-load is!
- ** Return 80% as a default in order to activate DIM
- */
- SystemLoad = 80;
- return (SystemLoad);
- }
-
- UsedTime = UserTime + NiceTime + SystemTime;
-
- IdleTime = jif * num_online_cpus() - UsedTime;
- TotalTime = UsedTime + IdleTime;
-
- SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) /
- (TotalTime - M_DIMINFO.PrevTotalTime);
-
- if (M_DIMINFO.DisplayStats) {
- printk("Current system load is: %u\n", SystemLoad);
- }
-
- M_DIMINFO.PrevTotalTime = TotalTime;
- M_DIMINFO.PrevUsedTime = UsedTime;
-
- return (SystemLoad);
-}
-
-/*******************************************************************************
-** Function : GetIsrCalls
-** Description : Depending on the selected moderation mask, this function will
-** return the number of interrupts handled in the previous time-
-** frame. This evaluated number is based on the current number
-** of interrupts stored in PNMI-context and the previous stored
-** interrupts.
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : int: the number of interrupts being executed in the last
-** timeframe
-** Notes : It makes only sense to call this function, when dynamic
-** interrupt moderation is applied
-*******************************************************************************/
-
-static SK_U64
-GetIsrCalls(SK_AC *pAC) {
- SK_U64 RxPort0IntDiff = 0;
- SK_U64 RxPort1IntDiff = 0;
- SK_U64 TxPort0IntDiff = 0;
- SK_U64 TxPort1IntDiff = 0;
-
- if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
- if (pAC->GIni.GIMacsFound == 2) {
- TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
- pAC->DynIrqModInfo.PrevPort1TxIntrCts;
- }
- TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
- pAC->DynIrqModInfo.PrevPort0TxIntrCts;
- } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
- if (pAC->GIni.GIMacsFound == 2) {
- RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
- pAC->DynIrqModInfo.PrevPort1RxIntrCts;
- }
- RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
- pAC->DynIrqModInfo.PrevPort0RxIntrCts;
- } else {
- if (pAC->GIni.GIMacsFound == 2) {
- RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
- pAC->DynIrqModInfo.PrevPort1RxIntrCts;
- TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
- pAC->DynIrqModInfo.PrevPort1TxIntrCts;
- }
- RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
- pAC->DynIrqModInfo.PrevPort0RxIntrCts;
- TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
- pAC->DynIrqModInfo.PrevPort0TxIntrCts;
- }
-
- return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
-}
-
-/*******************************************************************************
-** Function : GetRxCalls
-** Description : This function will return the number of times a receive inter-
-** rupt was processed. This is needed to evaluate any resizing
-** factor.
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : SK_U64: the number of RX-ints being processed
-** Notes : It makes only sense to call this function, when dynamic
-** interrupt moderation is applied
-*******************************************************************************/
-
-static SK_U64
-GetRxCalls(SK_AC *pAC) {
- SK_U64 RxPort0IntDiff = 0;
- SK_U64 RxPort1IntDiff = 0;
-
- if (pAC->GIni.GIMacsFound == 2) {
- RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
- pAC->DynIrqModInfo.PrevPort1RxIntrCts;
- }
- RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
- pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-
- return (RxPort0IntDiff + RxPort1IntDiff);
-}
-
-/*******************************************************************************
-** Function : SetCurrIntCtr
-** Description : Will store the current number orf occured interrupts in the
-** adapter context. This is needed to evaluated the number of
-** interrupts within a current timeframe.
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : void (!)
-** Notes : -
-*******************************************************************************/
-
-static void
-SetCurrIntCtr(SK_AC *pAC) {
- if (pAC->GIni.GIMacsFound == 2) {
- pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
- pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
- }
- pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
- pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
-}
-
-/*******************************************************************************
-** Function : IsIntModEnabled()
-** Description : Retrieves the current value of the interrupts moderation
-** command register. Its content determines whether any
-** moderation is running or not.
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : SK_TRUE : if mod timer running
-** SK_FALSE : if no moderation is being performed
-** Notes : -
-*******************************************************************************/
-
-static SK_BOOL
-IsIntModEnabled(SK_AC *pAC) {
- unsigned long CtrCmd;
-
- SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
- if ((CtrCmd & TIM_START) == TIM_START) {
- return SK_TRUE;
- } else {
- return SK_FALSE;
- }
-}
-
-/*******************************************************************************
-** Function : EnableIntMod()
-** Description : Enables the interrupt moderation using the values stored in
-** in the pAC->DynIntMod data structure
-** Programmer : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns : -
-** Notes : -
-*******************************************************************************/
-
-static void
-EnableIntMod(SK_AC *pAC) {
- unsigned long ModBase;
-
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
- ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
- } else {
- ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
- }
-
- SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
- SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration);
- SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
- if (M_DIMINFO.DisplayStats) {
- printk("Enabled interrupt moderation (%i ints/sec)\n",
- M_DIMINFO.MaxModIntsPerSec);
- }
-}
-
-/*******************************************************************************
-** Function : DisableIntMod()
-** Description : Disables the interrupt moderation independent of what inter-
-** rupts are running or not
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : -
-** Notes : -
-*******************************************************************************/
-
-static void
-DisableIntMod(SK_AC *pAC) {
-
- SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
- if (M_DIMINFO.DisplayStats) {
- printk("Disabled interrupt moderation\n");
- }
-}
-
-/*******************************************************************************
-** Function : ResizeDimTimerDuration();
-** Description : Checks the current used descriptor ratio and resizes the
-** duration timer (longer/smaller) if possible.
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : -
-** Notes : There are both maximum and minimum timer duration value.
-** This function assumes that interrupt moderation is already
-** enabled!
-*******************************************************************************/
-
-static void
-ResizeDimTimerDuration(SK_AC *pAC) {
- SK_BOOL IncreaseTimerDuration;
- int TotalMaxNbrDescr;
- int UsedDescrRatio;
- int RatioDiffAbs;
- int RatioDiffRel;
- int NewMaxModIntsPerSec;
- int ModAdjValue;
- long ModBase;
-
- /*
- ** Check first if we are allowed to perform any modification
- */
- if (IsIntModEnabled(pAC)) {
- if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
- return;
- } else {
- if (M_DIMINFO.ModJustEnabled) {
- M_DIMINFO.ModJustEnabled = SK_FALSE;
- return;
- }
- }
- }
-
- /*
- ** If we got until here, we have to evaluate the amount of the
- ** descriptor ratio change...
- */
- TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
- UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
-
- if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
- RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
- RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
- M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
- IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */
- } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
- RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
- RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
- M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
- IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
- } else {
- RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
- RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
- M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
- IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
- }
-
- /*
- ** Now we can determine the change in percent
- */
- if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
- ModAdjValue = 1; /* 1% change - maybe some other value in future */
- } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
- ModAdjValue = 1; /* 1% change - maybe some other value in future */
- } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
- ModAdjValue = 1; /* 1% change - maybe some other value in future */
- } else {
- ModAdjValue = 1; /* 1% change - maybe some other value in future */
- }
-
- if (IncreaseTimerDuration) {
- NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec +
- (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
- } else {
- NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec -
- (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
- }
-
- /*
- ** Check if we exceed boundaries...
- */
- if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
- (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
- if (M_DIMINFO.DisplayStats) {
- printk("Cannot change ModTim from %i to %i ints/sec\n",
- M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
- }
- return;
- } else {
- if (M_DIMINFO.DisplayStats) {
- printk("Resized ModTim from %i to %i ints/sec\n",
- M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
- }
- }
-
- M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
-
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
- ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
- } else {
- ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
- }
-
- /*
- ** We do not need to touch any other registers
- */
- SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
-}
-
-/*******************************************************************************
-** Function : DisplaySelectedModerationType()
-** Description : Displays what type of moderation we have
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : void!
-** Notes : -
-*******************************************************************************/
-
-static void
-DisplaySelectedModerationType(SK_AC *pAC) {
-
- if (pAC->DynIrqModInfo.DisplayStats) {
- if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
- printk("Static int moderation runs with %i INTS/sec\n",
- pAC->DynIrqModInfo.MaxModIntsPerSec);
- } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
- if (IsIntModEnabled(pAC)) {
- printk("Dynamic int moderation runs with %i INTS/sec\n",
- pAC->DynIrqModInfo.MaxModIntsPerSec);
- } else {
- printk("Dynamic int moderation currently not applied\n");
- }
- } else {
- printk("No interrupt moderation selected!\n");
- }
- }
-}
-
-/*******************************************************************************
-** Function : DisplaySelectedModerationMask()
-** Description : Displays what interrupts are moderated
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : void!
-** Notes : -
-*******************************************************************************/
-
-static void
-DisplaySelectedModerationMask(SK_AC *pAC) {
-
- if (pAC->DynIrqModInfo.DisplayStats) {
- if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
- switch (pAC->DynIrqModInfo.MaskIrqModeration) {
- case IRQ_MASK_TX_ONLY:
- printk("Only Tx-interrupts are moderated\n");
- break;
- case IRQ_MASK_RX_ONLY:
- printk("Only Rx-interrupts are moderated\n");
- break;
- case IRQ_MASK_SP_ONLY:
- printk("Only special-interrupts are moderated\n");
- break;
- case IRQ_MASK_TX_RX:
- printk("Tx- and Rx-interrupts are moderated\n");
- break;
- case IRQ_MASK_SP_RX:
- printk("Special- and Rx-interrupts are moderated\n");
- break;
- case IRQ_MASK_SP_TX:
- printk("Special- and Tx-interrupts are moderated\n");
- break;
- case IRQ_MASK_RX_TX_SP:
- printk("All Rx-, Tx and special-interrupts are moderated\n");
- break;
- default:
- printk("Don't know what is moderated\n");
- break;
- }
- } else {
- printk("No specific interrupts masked for moderation\n");
- }
- }
-}
-
-/*******************************************************************************
-** Function : DisplayDescrRatio
-** Description : Like the name states...
-** Programmer : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns : void!
-** Notes : -
-*******************************************************************************/
-
-static void
-DisplayDescrRatio(SK_AC *pAC) {
- int TotalMaxNbrDescr = 0;
-
- if (pAC->DynIrqModInfo.DisplayStats) {
- TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
- printk("Ratio descriptors: %i/%i\n",
- M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
- }
-}
-
-/*******************************************************************************
-**
-** End of file
-**
-*******************************************************************************/
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
deleted file mode 100644
index 36460694eb82..000000000000
--- a/drivers/net/sk98lin/skethtool.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/******************************************************************************
- *
- * Name: skethtool.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.7 $
- * Date: $Date: 2004/09/29 13:32:07 $
- * Purpose: All functions regarding ethtool handling
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2004 Marvell.
- *
- * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet
- * Server Adapters.
- *
- * Author: Ralph Roesler (rroesler@syskonnect.de)
- * Mirko Lindner (mlindner@syskonnect.de)
- *
- * Address all question to: linux@syskonnect.de
- *
- * The technical manual for the adapters is available from SysKonnect's
- * web pages: www.syskonnect.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- *****************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "h/skversion.h"
-
-#include <linux/ethtool.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-
-/******************************************************************************
- *
- * Defines
- *
- *****************************************************************************/
-
-#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
- SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
- SUPPORTED_TP)
-
-#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
- ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
- ADVERTISED_TP)
-
-#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \
- SUPPORTED_FIBRE | \
- SUPPORTED_Autoneg)
-
-#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \
- ADVERTISED_FIBRE | \
- ADVERTISED_Autoneg)
-
-
-/******************************************************************************
- *
- * Local Functions
- *
- *****************************************************************************/
-
-/*****************************************************************************
- *
- * getSettings - retrieves the current settings of the selected adapter
- *
- * Description:
- * The current configuration of the selected adapter is returned.
- * This configuration involves a)speed, b)duplex and c)autoneg plus
- * a number of other variables.
- *
- * Returns: always 0
- *
- */
-static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- const DEV_NET *pNet = netdev_priv(dev);
- int port = pNet->PortNr;
- const SK_AC *pAC = pNet->pAC;
- const SK_GEPORT *pPort = &pAC->GIni.GP[port];
-
- static int DuplexAutoNegConfMap[9][3]= {
- { -1 , -1 , -1 },
- { 0 , -1 , -1 },
- { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE },
- { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE },
- { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE },
- { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE },
- { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE },
- { SK_LMODE_AUTOSENSE , -1 , -1 },
- { SK_LMODE_INDETERMINATED, -1 , -1 }
- };
- static int SpeedConfMap[6][2] = {
- { 0 , -1 },
- { SK_LSPEED_AUTO , -1 },
- { SK_LSPEED_10MBPS , SPEED_10 },
- { SK_LSPEED_100MBPS , SPEED_100 },
- { SK_LSPEED_1000MBPS , SPEED_1000 },
- { SK_LSPEED_INDETERMINATED, -1 }
- };
- static int AdvSpeedMap[6][2] = {
- { 0 , -1 },
- { SK_LSPEED_AUTO , -1 },
- { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full },
- { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full },
- { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
- { SK_LSPEED_INDETERMINATED, -1 }
- };
-
- ecmd->phy_address = port;
- ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1];
- ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
- ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
- ecmd->transceiver = XCVR_INTERNAL;
-
- if (pAC->GIni.GICopperType) {
- ecmd->port = PORT_TP;
- ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
- if (pAC->GIni.GIGenesis) {
- ecmd->supported &= ~(SUPPORTED_10baseT_Half);
- ecmd->supported &= ~(SUPPORTED_10baseT_Full);
- ecmd->supported &= ~(SUPPORTED_100baseT_Half);
- ecmd->supported &= ~(SUPPORTED_100baseT_Full);
- } else {
- if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
- ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
- }
-#ifdef CHIP_ID_YUKON_FE
- if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
- ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
- ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
- }
-#endif
- }
- if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
- ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
- if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
- ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
- }
- } else {
- ecmd->advertising = ecmd->supported;
- }
-
- if (ecmd->autoneg == AUTONEG_ENABLE)
- ecmd->advertising |= ADVERTISED_Autoneg;
- } else {
- ecmd->port = PORT_FIBRE;
- ecmd->supported = SUPP_FIBRE_ALL;
- ecmd->advertising = ADV_FIBRE_ALL;
- }
- return 0;
-}
-
-/*
- * MIB infrastructure uses instance value starting at 1
- * based on board and port.
- */
-static inline u32 pnmiInstance(const DEV_NET *pNet)
-{
- return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
-}
-
-/*****************************************************************************
- *
- * setSettings - configures the settings of a selected adapter
- *
- * Description:
- * Possible settings that may be altered are a)speed, b)duplex or
- * c)autonegotiation.
- *
- * Returns:
- * 0: everything fine, no error
- * <0: the return value is the error code of the failure
- */
-static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- u32 instance;
- char buf[4];
- int len = 1;
-
- if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100
- && ecmd->speed != SPEED_1000)
- return -EINVAL;
-
- if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
- return -EINVAL;
-
- if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
- return -EINVAL;
-
- if (ecmd->autoneg == AUTONEG_DISABLE)
- *buf = (ecmd->duplex == DUPLEX_FULL)
- ? SK_LMODE_FULL : SK_LMODE_HALF;
- else
- *buf = (ecmd->duplex == DUPLEX_FULL)
- ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
-
- instance = pnmiInstance(pNet);
- if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
- &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
- return -EINVAL;
-
- switch(ecmd->speed) {
- case SPEED_1000:
- *buf = SK_LSPEED_1000MBPS;
- break;
- case SPEED_100:
- *buf = SK_LSPEED_100MBPS;
- break;
- case SPEED_10:
- *buf = SK_LSPEED_10MBPS;
- }
-
- if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
- &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
- return -EINVAL;
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * getDriverInfo - returns generic driver and adapter information
- *
- * Description:
- * Generic driver information is returned via this function, such as
- * the name of the driver, its version and and firmware version.
- * In addition to this, the location of the selected adapter is
- * returned as a bus info string (e.g. '01:05.0').
- *
- * Returns: N/A
- *
- */
-static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- const DEV_NET *pNet = netdev_priv(dev);
- const SK_AC *pAC = pNet->pAC;
- char vers[32];
-
- snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
- (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
-
- strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
- strcpy(info->version, vers);
- strcpy(info->fw_version, "N/A");
- strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN);
-}
-
-/*
- * Ethtool statistics support.
- */
-static const char StringsStats[][ETH_GSTRING_LEN] = {
- "rx_packets", "tx_packets",
- "rx_bytes", "tx_bytes",
- "rx_errors", "tx_errors",
- "rx_dropped", "tx_dropped",
- "multicasts", "collisions",
- "rx_length_errors", "rx_buffer_overflow_errors",
- "rx_crc_errors", "rx_frame_errors",
- "rx_too_short_errors", "rx_too_long_errors",
- "rx_carrier_extension_errors", "rx_symbol_errors",
- "rx_llc_mac_size_errors", "rx_carrier_errors",
- "rx_jabber_errors", "rx_missed_errors",
- "tx_abort_collision_errors", "tx_carrier_errors",
- "tx_buffer_underrun_errors", "tx_heartbeat_errors",
- "tx_window_errors",
-};
-
-static int getStatsCount(struct net_device *dev)
-{
- return ARRAY_SIZE(StringsStats);
-}
-
-static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
-{
- switch(stringset) {
- case ETH_SS_STATS:
- memcpy(data, *StringsStats, sizeof(StringsStats));
- break;
- }
-}
-
-static void getEthtoolStats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
-{
- const DEV_NET *pNet = netdev_priv(dev);
- const SK_AC *pAC = pNet->pAC;
- const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
-
- *data++ = pPnmiStruct->Stat[0].StatRxOkCts;
- *data++ = pPnmiStruct->Stat[0].StatTxOkCts;
- *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
- *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
- *data++ = pPnmiStruct->InErrorsCts;
- *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
- *data++ = pPnmiStruct->RxNoBufCts;
- *data++ = pPnmiStruct->TxNoBufCts;
- *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
- *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
- *data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
- *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
- *data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
- *data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
- *data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
- *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
- *data++ = pPnmiStruct->Stat[0].StatRxCextCts;
- *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
- *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
- *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
- *data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
- *data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
- *data++ = pAC->stats.tx_aborted_errors;
- *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
- *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
- *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
- *data++ = pAC->stats.tx_window_errors;
-}
-
-
-/*****************************************************************************
- *
- * toggleLeds - Changes the LED state of an adapter
- *
- * Description:
- * This function changes the current state of all LEDs of an adapter so
- * that it can be located by a user.
- *
- * Returns: N/A
- *
- */
-static void toggleLeds(DEV_NET *pNet, int on)
-{
- SK_AC *pAC = pNet->pAC;
- int port = pNet->PortNr;
- void __iomem *io = pAC->IoBase;
-
- if (pAC->GIni.GIGenesis) {
- SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
- on ? SK_LNK_ON : SK_LNK_OFF);
- SkGeYellowLED(pAC, io,
- on ? (LED_ON >> 1) : (LED_OFF >> 1));
- SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
- on ? SK_LED_TST : SK_LED_DIS);
-
- if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
- SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
- on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
- else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
- SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
- on ? 0x0800 : PHY_L_LC_LEDT);
- else
- SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
- on ? SK_LED_TST : SK_LED_DIS);
- } else {
- const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) |
- PHY_M_LED_MO_10(MO_LED_ON) |
- PHY_M_LED_MO_100(MO_LED_ON) |
- PHY_M_LED_MO_1000(MO_LED_ON) |
- PHY_M_LED_MO_RX(MO_LED_ON));
- const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) |
- PHY_M_LED_MO_10(MO_LED_OFF) |
- PHY_M_LED_MO_100(MO_LED_OFF) |
- PHY_M_LED_MO_1000(MO_LED_OFF) |
- PHY_M_LED_MO_RX(MO_LED_OFF));
-
-
- SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
- SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
- on ? YukLedOn : YukLedOff);
- }
-}
-
-/*****************************************************************************
- *
- * skGeBlinkTimer - Changes the LED state of an adapter
- *
- * Description:
- * This function changes the current state of all LEDs of an adapter so
- * that it can be located by a user. If the requested time interval for
- * this test has elapsed, this function cleans up everything that was
- * temporarily setup during the locate NIC test. This involves of course
- * also closing or opening any adapter so that the initial board state
- * is recovered.
- *
- * Returns: N/A
- *
- */
-void SkGeBlinkTimer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *) data;
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
-
- toggleLeds(pNet, pAC->LedsOn);
-
- pAC->LedsOn = !pAC->LedsOn;
- mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
-}
-
-/*****************************************************************************
- *
- * locateDevice - start the locate NIC feature of the elected adapter
- *
- * Description:
- * This function is used if the user want to locate a particular NIC.
- * All LEDs are regularly switched on and off, so the NIC can easily
- * be identified.
- *
- * Returns:
- * ==0: everything fine, no error, locateNIC test was started
- * !=0: one locateNIC test runs already
- *
- */
-static int locateDevice(struct net_device *dev, u32 data)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
-
- if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
- data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
-
- /* start blinking */
- pAC->LedsOn = 0;
- mod_timer(&pAC->BlinkTimer, jiffies);
- msleep_interruptible(data * 1000);
- del_timer_sync(&pAC->BlinkTimer);
- toggleLeds(pNet, 0);
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * getPauseParams - retrieves the pause parameters
- *
- * Description:
- * All current pause parameters of a selected adapter are placed
- * in the passed ethtool_pauseparam structure and are returned.
- *
- * Returns: N/A
- *
- */
-static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
-
- epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
- (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
-
- epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
- epause->autoneg = epause->rx_pause || epause->tx_pause;
-}
-
-/*****************************************************************************
- *
- * setPauseParams - configures the pause parameters of an adapter
- *
- * Description:
- * This function sets the Rx or Tx pause parameters
- *
- * Returns:
- * ==0: everything fine, no error
- * !=0: the return value is the error code of the failure
- */
-static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
- u32 instance = pnmiInstance(pNet);
- struct ethtool_pauseparam old;
- u8 oldspeed = pPort->PLinkSpeedUsed;
- char buf[4];
- int len = 1;
- int ret;
-
- /*
- ** we have to determine the current settings to see if
- ** the operator requested any modification of the flow
- ** control parameters...
- */
- getPauseParams(dev, &old);
-
- /*
- ** perform modifications regarding the changes
- ** requested by the operator
- */
- if (epause->autoneg != old.autoneg)
- *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
- else {
- if (epause->rx_pause && epause->tx_pause)
- *buf = SK_FLOW_MODE_SYMMETRIC;
- else if (epause->rx_pause && !epause->tx_pause)
- *buf = SK_FLOW_MODE_SYM_OR_REM;
- else if (!epause->rx_pause && epause->tx_pause)
- *buf = SK_FLOW_MODE_LOC_SEND;
- else
- *buf = SK_FLOW_MODE_NONE;
- }
-
- ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
- &buf, &len, instance, pNet->NetNr);
-
- if (ret != SK_PNMI_ERR_OK) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
- ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
- goto err;
- }
-
- /*
- ** It may be that autoneg has been disabled! Therefore
- ** set the speed to the previously used value...
- */
- if (!epause->autoneg) {
- len = 1;
- ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
- &oldspeed, &len, instance, pNet->NetNr);
- if (ret != SK_PNMI_ERR_OK)
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
- ("ethtool (sk98lin): error setting speed (%i)\n", ret));
- }
- err:
- return ret ? -EIO : 0;
-}
-
-/* Only Yukon supports checksum offload. */
-static int setScatterGather(struct net_device *dev, u32 data)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
-
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
- return -EOPNOTSUPP;
- return ethtool_op_set_sg(dev, data);
-}
-
-static int setTxCsum(struct net_device *dev, u32 data)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
-
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
- return -EOPNOTSUPP;
-
- return ethtool_op_set_tx_csum(dev, data);
-}
-
-static u32 getRxCsum(struct net_device *dev)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
-
- return pAC->RxPort[pNet->PortNr].RxCsum;
-}
-
-static int setRxCsum(struct net_device *dev, u32 data)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
-
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
- return -EOPNOTSUPP;
-
- pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
- return 0;
-}
-
-static int getRegsLen(struct net_device *dev)
-{
- return 0x4000;
-}
-
-/*
- * Returns copy of whole control register region
- * Note: skip RAM address register because accessing it will
- * cause bus hangs!
- */
-static void getRegs(struct net_device *dev, struct ethtool_regs *regs,
- void *p)
-{
- DEV_NET *pNet = netdev_priv(dev);
- const void __iomem *io = pNet->pAC->IoBase;
-
- regs->version = 1;
- memset(p, 0, regs->len);
- memcpy_fromio(p, io, B3_RAM_ADDR);
-
- memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
- regs->len - B3_RI_WTO_R1);
-}
-
-const struct ethtool_ops SkGeEthtoolOps = {
- .get_settings = getSettings,
- .set_settings = setSettings,
- .get_drvinfo = getDriverInfo,
- .get_strings = getStrings,
- .get_stats_count = getStatsCount,
- .get_ethtool_stats = getEthtoolStats,
- .phys_id = locateDevice,
- .get_pauseparam = getPauseParams,
- .set_pauseparam = setPauseParams,
- .get_link = ethtool_op_get_link,
- .get_perm_addr = ethtool_op_get_perm_addr,
- .get_sg = ethtool_op_get_sg,
- .set_sg = setScatterGather,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = setTxCsum,
- .get_rx_csum = getRxCsum,
- .set_rx_csum = setRxCsum,
- .get_regs = getRegs,
- .get_regs_len = getRegsLen,
-};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
deleted file mode 100644
index bf218621db16..000000000000
--- a/drivers/net/sk98lin/skge.c
+++ /dev/null
@@ -1,5211 +0,0 @@
-/******************************************************************************
- *
- * Name: skge.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.45 $
- * Date: $Date: 2004/02/12 14:41:02 $
- * Purpose: The main driver source module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet
- * Server Adapters.
- *
- * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
- * SysKonnects GEnesis Solaris driver
- * Author: Christoph Goos (cgoos@syskonnect.de)
- * Mirko Lindner (mlindner@syskonnect.de)
- *
- * Address all question to: linux@syskonnect.de
- *
- * The technical manual for the adapters is available from SysKonnect's
- * web pages: www.syskonnect.com
- * Goto "Support" and search Knowledge Base for "manual".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Possible compiler options (#define xxx / -Dxxx):
- *
- * debugging can be enable by changing SK_DEBUG_CHKMOD and
- * SK_DEBUG_CHKCAT in makefile (described there).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the main module of the Linux GE driver.
- *
- * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
- * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
- * Those are used for drivers on multiple OS', so some thing may seem
- * unnecessary complicated on Linux. Please do not try to 'clean up'
- * them without VERY good reasons, because this will make it more
- * difficult to keep the Linux driver in synchronisation with the
- * other versions.
- *
- * Include file hierarchy:
- *
- * <linux/module.h>
- *
- * "h/skdrv1st.h"
- * <linux/types.h>
- * <linux/kernel.h>
- * <linux/string.h>
- * <linux/errno.h>
- * <linux/ioport.h>
- * <linux/slab.h>
- * <linux/interrupt.h>
- * <linux/pci.h>
- * <linux/bitops.h>
- * <asm/byteorder.h>
- * <asm/io.h>
- * <linux/netdevice.h>
- * <linux/etherdevice.h>
- * <linux/skbuff.h>
- * those three depending on kernel version used:
- * <linux/bios32.h>
- * <linux/init.h>
- * <asm/uaccess.h>
- * <net/checksum.h>
- *
- * "h/skerror.h"
- * "h/skdebug.h"
- * "h/sktypes.h"
- * "h/lm80.h"
- * "h/xmac_ii.h"
- *
- * "h/skdrv2nd.h"
- * "h/skqueue.h"
- * "h/skgehwt.h"
- * "h/sktimer.h"
- * "h/ski2c.h"
- * "h/skgepnmi.h"
- * "h/skvpd.h"
- * "h/skgehw.h"
- * "h/skgeinit.h"
- * "h/skaddr.h"
- * "h/skgesirq.h"
- * "h/skrlmt.h"
- *
- ******************************************************************************/
-
-#include "h/skversion.h"
-
-#include <linux/in.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/ip.h>
-#include <linux/mii.h>
-#include <linux/mm.h>
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/*******************************************************************************
- *
- * Defines
- *
- ******************************************************************************/
-
-/* for debuging on x86 only */
-/* #define BREAKPOINT() asm(" int $3"); */
-
-/* use the transmit hw checksum driver functionality */
-#define USE_SK_TX_CHECKSUM
-
-/* use the receive hw checksum driver functionality */
-#define USE_SK_RX_CHECKSUM
-
-/* use the scatter-gather functionality with sendfile() */
-#define SK_ZEROCOPY
-
-/* use of a transmit complete interrupt */
-#define USE_TX_COMPLETE
-
-/*
- * threshold for copying small receive frames
- * set to 0 to avoid copying, set to 9001 to copy all frames
- */
-#define SK_COPY_THRESHOLD 50
-
-/* number of adapters that can be configured via command line params */
-#define SK_MAX_CARD_PARAM 16
-
-
-
-/*
- * use those defines for a compile-in version of the driver instead
- * of command line parameters
- */
-// #define LINK_SPEED_A {"Auto", }
-// #define LINK_SPEED_B {"Auto", }
-// #define AUTO_NEG_A {"Sense", }
-// #define AUTO_NEG_B {"Sense", }
-// #define DUP_CAP_A {"Both", }
-// #define DUP_CAP_B {"Both", }
-// #define FLOW_CTRL_A {"SymOrRem", }
-// #define FLOW_CTRL_B {"SymOrRem", }
-// #define ROLE_A {"Auto", }
-// #define ROLE_B {"Auto", }
-// #define PREF_PORT {"A", }
-// #define CON_TYPE {"Auto", }
-// #define RLMT_MODE {"CheckLinkState", }
-
-#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
-#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
-#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
-
-
-/* Set blink mode*/
-#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \
- SK_DUP_LED_NORMAL | \
- SK_LED_LINK100_ON)
-
-
-/* Isr return value */
-#define SkIsrRetVar irqreturn_t
-#define SkIsrRetNone IRQ_NONE
-#define SkIsrRetHandled IRQ_HANDLED
-
-
-/*******************************************************************************
- *
- * Local Function Prototypes
- *
- ******************************************************************************/
-
-static void FreeResources(struct SK_NET_DEVICE *dev);
-static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
-static SK_BOOL BoardAllocMem(SK_AC *pAC);
-static void BoardFreeMem(SK_AC *pAC);
-static void BoardInitMem(SK_AC *pAC);
-static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
-static SkIsrRetVar SkGeIsr(int irq, void *dev_id);
-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id);
-static int SkGeOpen(struct SK_NET_DEVICE *dev);
-static int SkGeClose(struct SK_NET_DEVICE *dev);
-static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
-static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
-static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
-static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
-static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
-static void GetConfiguration(SK_AC*);
-static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
-static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
-static void FillRxRing(SK_AC*, RX_PORT*);
-static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
-static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
-static void ClearAndStartRx(SK_AC*, int);
-static void ClearTxIrq(SK_AC*, int, int);
-static void ClearRxRing(SK_AC*, RX_PORT*);
-static void ClearTxRing(SK_AC*, TX_PORT*);
-static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
-static void PortReInitBmu(SK_AC*, int);
-static int SkGeIocMib(DEV_NET*, unsigned int, int);
-static int SkGeInitPCI(SK_AC *pAC);
-static void StartDrvCleanupTimer(SK_AC *pAC);
-static void StopDrvCleanupTimer(SK_AC *pAC);
-static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
-
-#ifdef SK_DIAG_SUPPORT
-static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName);
-static int SkDrvInitAdapter(SK_AC *pAC, int devNbr);
-static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
-#endif
-
-/*******************************************************************************
- *
- * Extern Function Prototypes
- *
- ******************************************************************************/
-extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
-extern void SkDimDisplayModerationSettings(SK_AC *pAC);
-extern void SkDimStartModerationTimer(SK_AC *pAC);
-extern void SkDimModerate(SK_AC *pAC);
-extern void SkGeBlinkTimer(unsigned long data);
-
-#ifdef DEBUG
-static void DumpMsg(struct sk_buff*, char*);
-static void DumpData(char*, int);
-static void DumpLong(char*, int);
-#endif
-
-/* global variables *********************************************************/
-static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
-extern const struct ethtool_ops SkGeEthtoolOps;
-
-/* local variables **********************************************************/
-static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
-static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
-
-/*****************************************************************************
- *
- * SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- * This routine writes a 32 bit value to the pci configuration
- * space.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-static inline int SkPciWriteCfgDWord(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U32 Val) /* pointer to store the read value */
-{
- pci_write_config_dword(pAC->PciDev, PciAddr, Val);
- return(0);
-} /* SkPciWriteCfgDWord */
-
-/*****************************************************************************
- *
- * SkGeInitPCI - Init the PCI resources
- *
- * Description:
- * This function initialize the PCI resources and IO
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-static __devinit int SkGeInitPCI(SK_AC *pAC)
-{
- struct SK_NET_DEVICE *dev = pAC->dev[0];
- struct pci_dev *pdev = pAC->PciDev;
- int retval;
-
- dev->mem_start = pci_resource_start (pdev, 0);
- pci_set_master(pdev);
-
- retval = pci_request_regions(pdev, "sk98lin");
- if (retval)
- goto out;
-
-#ifdef SK_BIG_ENDIAN
- /*
- * On big endian machines, we use the adapter's aibility of
- * reading the descriptors as big endian.
- */
- {
- SK_U32 our2;
- SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
- our2 |= PCI_REV_DESC;
- SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
- }
-#endif
-
- /*
- * Remap the regs into kernel space.
- */
- pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
- if (!pAC->IoBase) {
- retval = -EIO;
- goto out_release;
- }
-
- return 0;
-
- out_release:
- pci_release_regions(pdev);
- out:
- return retval;
-}
-
-
-/*****************************************************************************
- *
- * FreeResources - release resources allocated for adapter
- *
- * Description:
- * This function releases the IRQ, unmaps the IO and
- * frees the desriptor ring.
- *
- * Returns: N/A
- *
- */
-static void FreeResources(struct SK_NET_DEVICE *dev)
-{
-SK_U32 AllocFlag;
-DEV_NET *pNet;
-SK_AC *pAC;
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
- AllocFlag = pAC->AllocFlag;
- if (pAC->PciDev) {
- pci_release_regions(pAC->PciDev);
- }
- if (AllocFlag & SK_ALLOC_IRQ) {
- free_irq(dev->irq, dev);
- }
- if (pAC->IoBase) {
- iounmap(pAC->IoBase);
- }
- if (pAC->pDescrMem) {
- BoardFreeMem(pAC);
- }
-
-} /* FreeResources */
-
-MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
-MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
-MODULE_LICENSE("GPL");
-
-#ifdef LINK_SPEED_A
-static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
-#else
-static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef LINK_SPEED_B
-static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
-#else
-static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef AUTO_NEG_A
-static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
-#else
-static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef DUP_CAP_A
-static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
-#else
-static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef FLOW_CTRL_A
-static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
-#else
-static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef ROLE_A
-static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
-#else
-static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef AUTO_NEG_B
-static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
-#else
-static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef DUP_CAP_B
-static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
-#else
-static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef FLOW_CTRL_B
-static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
-#else
-static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef ROLE_B
-static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
-#else
-static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef CON_TYPE
-static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
-#else
-static char *ConType[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef PREF_PORT
-static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
-#else
-static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-#ifdef RLMT_MODE
-static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
-#else
-static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
-#endif
-
-static int IntsPerSec[SK_MAX_CARD_PARAM];
-static char *Moderation[SK_MAX_CARD_PARAM];
-static char *ModerationMask[SK_MAX_CARD_PARAM];
-static char *AutoSizing[SK_MAX_CARD_PARAM];
-static char *Stats[SK_MAX_CARD_PARAM];
-
-module_param_array(Speed_A, charp, NULL, 0);
-module_param_array(Speed_B, charp, NULL, 0);
-module_param_array(AutoNeg_A, charp, NULL, 0);
-module_param_array(AutoNeg_B, charp, NULL, 0);
-module_param_array(DupCap_A, charp, NULL, 0);
-module_param_array(DupCap_B, charp, NULL, 0);
-module_param_array(FlowCtrl_A, charp, NULL, 0);
-module_param_array(FlowCtrl_B, charp, NULL, 0);
-module_param_array(Role_A, charp, NULL, 0);
-module_param_array(Role_B, charp, NULL, 0);
-module_param_array(ConType, charp, NULL, 0);
-module_param_array(PrefPort, charp, NULL, 0);
-module_param_array(RlmtMode, charp, NULL, 0);
-/* used for interrupt moderation */
-module_param_array(IntsPerSec, int, NULL, 0);
-module_param_array(Moderation, charp, NULL, 0);
-module_param_array(Stats, charp, NULL, 0);
-module_param_array(ModerationMask, charp, NULL, 0);
-module_param_array(AutoSizing, charp, NULL, 0);
-
-/*****************************************************************************
- *
- * SkGeBoardInit - do level 0 and 1 initialization
- *
- * Description:
- * This function prepares the board hardware for running. The desriptor
- * ring is set up, the IRQ is allocated and the configuration settings
- * are examined.
- *
- * Returns:
- * 0, if everything is ok
- * !=0, on error
- */
-static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
-{
-short i;
-unsigned long Flags;
-char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
-char *VerStr = VER_STRING;
-int Ret; /* return code of request_irq */
-SK_BOOL DualNet;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
- for (i=0; i<SK_MAX_MACS; i++) {
- pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
- pAC->TxPort[i][0].PortIndex = i;
- pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
- pAC->RxPort[i].PortIndex = i;
- }
-
- /* Initialize the mutexes */
- for (i=0; i<SK_MAX_MACS; i++) {
- spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
- spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
- }
- spin_lock_init(&pAC->SlowPathLock);
-
- /* setup phy_id blink timer */
- pAC->BlinkTimer.function = SkGeBlinkTimer;
- pAC->BlinkTimer.data = (unsigned long) dev;
- init_timer(&pAC->BlinkTimer);
-
- /* level 0 init common modules here */
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- /* Does a RESET on board ...*/
- if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
- printk("HWInit (0) failed.\n");
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return -EIO;
- }
- SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
- SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
- SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
- SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
- SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
- SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
-
- pAC->BoardLevel = SK_INIT_DATA;
- pAC->RxBufSize = ETH_BUF_SIZE;
-
- SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
- SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
-
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- /* level 1 init common modules here (HW init) */
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
- printk("sk98lin: HWInit (1) failed.\n");
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return -EIO;
- }
- SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
- SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
-
- /* Set chipset type support */
- pAC->ChipsetType = 0;
- if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
- (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
- pAC->ChipsetType = 1;
- }
-
- GetConfiguration(pAC);
- if (pAC->RlmtNets == 2) {
- pAC->GIni.GIPortUsage = SK_MUL_LINK;
- }
-
- pAC->BoardLevel = SK_INIT_IO;
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- if (pAC->GIni.GIMacsFound == 2) {
- Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
- } else if (pAC->GIni.GIMacsFound == 1) {
- Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED,
- "sk98lin", dev);
- } else {
- printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
- pAC->GIni.GIMacsFound);
- return -EIO;
- }
-
- if (Ret) {
- printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
- dev->irq);
- return Ret;
- }
- pAC->AllocFlag |= SK_ALLOC_IRQ;
-
- /* Alloc memory for this board (Mem for RxD/TxD) : */
- if(!BoardAllocMem(pAC)) {
- printk("No memory for descriptor rings.\n");
- return -ENOMEM;
- }
-
- BoardInitMem(pAC);
- /* tschilling: New common function with minimum size check. */
- DualNet = SK_FALSE;
- if (pAC->RlmtNets == 2) {
- DualNet = SK_TRUE;
- }
-
- if (SkGeInitAssignRamToQueues(
- pAC,
- pAC->ActivePort,
- DualNet)) {
- BoardFreeMem(pAC);
- printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
- return -EIO;
- }
-
- return (0);
-} /* SkGeBoardInit */
-
-
-/*****************************************************************************
- *
- * BoardAllocMem - allocate the memory for the descriptor rings
- *
- * Description:
- * This function allocates the memory for all descriptor rings.
- * Each ring is aligned for the desriptor alignment and no ring
- * has a 4 GByte boundary in it (because the upper 32 bit must
- * be constant for all descriptiors in one rings).
- *
- * Returns:
- * SK_TRUE, if all memory could be allocated
- * SK_FALSE, if not
- */
-static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC)
-{
-caddr_t pDescrMem; /* pointer to descriptor memory area */
-size_t AllocLength; /* length of complete descriptor area */
-int i; /* loop counter */
-unsigned long BusAddr;
-
-
- /* rings plus one for alignment (do not cross 4 GB boundary) */
- /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
-#if (BITS_PER_LONG == 32)
- AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
-#else
- AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
- + RX_RING_SIZE + 8;
-#endif
-
- pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
- &pAC->pDescrMemDMA);
-
- if (pDescrMem == NULL) {
- return (SK_FALSE);
- }
- pAC->pDescrMem = pDescrMem;
- BusAddr = (unsigned long) pAC->pDescrMemDMA;
-
- /* Descriptors need 8 byte alignment, and this is ensured
- * by pci_alloc_consistent.
- */
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
- ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n",
- i, (unsigned long) pDescrMem,
- BusAddr));
- pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
- pAC->TxPort[i][0].VTxDescrRing = BusAddr;
- pDescrMem += TX_RING_SIZE;
- BusAddr += TX_RING_SIZE;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
- ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n",
- i, (unsigned long) pDescrMem,
- (unsigned long)BusAddr));
- pAC->RxPort[i].pRxDescrRing = pDescrMem;
- pAC->RxPort[i].VRxDescrRing = BusAddr;
- pDescrMem += RX_RING_SIZE;
- BusAddr += RX_RING_SIZE;
- } /* for */
-
- return (SK_TRUE);
-} /* BoardAllocMem */
-
-
-/****************************************************************************
- *
- * BoardFreeMem - reverse of BoardAllocMem
- *
- * Description:
- * Free all memory allocated in BoardAllocMem: adapter context,
- * descriptor rings, locks.
- *
- * Returns: N/A
- */
-static void BoardFreeMem(
-SK_AC *pAC)
-{
-size_t AllocLength; /* length of complete descriptor area */
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("BoardFreeMem\n"));
-#if (BITS_PER_LONG == 32)
- AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
-#else
- AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
- + RX_RING_SIZE + 8;
-#endif
-
- pci_free_consistent(pAC->PciDev, AllocLength,
- pAC->pDescrMem, pAC->pDescrMemDMA);
- pAC->pDescrMem = NULL;
-} /* BoardFreeMem */
-
-
-/*****************************************************************************
- *
- * BoardInitMem - initiate the descriptor rings
- *
- * Description:
- * This function sets the descriptor rings up in memory.
- * The adapter is initialized with the descriptor start addresses.
- *
- * Returns: N/A
- */
-static __devinit void BoardInitMem(SK_AC *pAC)
-{
-int i; /* loop counter */
-int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
-int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("BoardInitMem\n"));
-
- RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
- pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
- TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
- pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
-
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- SetupRing(
- pAC,
- pAC->TxPort[i][0].pTxDescrRing,
- pAC->TxPort[i][0].VTxDescrRing,
- (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
- (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
- (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
- &pAC->TxPort[i][0].TxdRingFree,
- SK_TRUE);
- SetupRing(
- pAC,
- pAC->RxPort[i].pRxDescrRing,
- pAC->RxPort[i].VRxDescrRing,
- &pAC->RxPort[i].pRxdRingHead,
- &pAC->RxPort[i].pRxdRingTail,
- &pAC->RxPort[i].pRxdRingPrev,
- &pAC->RxPort[i].RxdRingFree,
- SK_FALSE);
- }
-} /* BoardInitMem */
-
-
-/*****************************************************************************
- *
- * SetupRing - create one descriptor ring
- *
- * Description:
- * This function creates one descriptor ring in the given memory area.
- * The head, tail and number of free descriptors in the ring are set.
- *
- * Returns:
- * none
- */
-static void SetupRing(
-SK_AC *pAC,
-void *pMemArea, /* a pointer to the memory area for the ring */
-uintptr_t VMemArea, /* the virtual bus address of the memory area */
-RXD **ppRingHead, /* address where the head should be written */
-RXD **ppRingTail, /* address where the tail should be written */
-RXD **ppRingPrev, /* address where the tail should be written */
-int *pRingFree, /* address where the # of free descr. goes */
-SK_BOOL IsTx) /* flag: is this a tx ring */
-{
-int i; /* loop counter */
-int DescrSize; /* the size of a descriptor rounded up to alignment*/
-int DescrNum; /* number of descriptors per ring */
-RXD *pDescr; /* pointer to a descriptor (receive or transmit) */
-RXD *pNextDescr; /* pointer to the next descriptor */
-RXD *pPrevDescr; /* pointer to the previous descriptor */
-uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
-
- if (IsTx == SK_TRUE) {
- DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
- DESCR_ALIGN;
- DescrNum = TX_RING_SIZE / DescrSize;
- } else {
- DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
- DESCR_ALIGN;
- DescrNum = RX_RING_SIZE / DescrSize;
- }
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
- ("Descriptor size: %d Descriptor Number: %d\n",
- DescrSize,DescrNum));
-
- pDescr = (RXD*) pMemArea;
- pPrevDescr = NULL;
- pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
- VNextDescr = VMemArea + DescrSize;
- for(i=0; i<DescrNum; i++) {
- /* set the pointers right */
- pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
- pDescr->pNextRxd = pNextDescr;
- if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
-
- /* advance one step */
- pPrevDescr = pDescr;
- pDescr = pNextDescr;
- pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
- VNextDescr += DescrSize;
- }
- pPrevDescr->pNextRxd = (RXD*) pMemArea;
- pPrevDescr->VNextRxd = VMemArea;
- pDescr = (RXD*) pMemArea;
- *ppRingHead = (RXD*) pMemArea;
- *ppRingTail = *ppRingHead;
- *ppRingPrev = pPrevDescr;
- *pRingFree = DescrNum;
-} /* SetupRing */
-
-
-/*****************************************************************************
- *
- * PortReInitBmu - re-initiate the descriptor rings for one port
- *
- * Description:
- * This function reinitializes the descriptor rings of one port
- * in memory. The port must be stopped before.
- * The HW is initialized with the descriptor start addresses.
- *
- * Returns:
- * none
- */
-static void PortReInitBmu(
-SK_AC *pAC, /* pointer to adapter context */
-int PortIndex) /* index of the port for which to re-init */
-{
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("PortReInitBmu "));
-
- /* set address of first descriptor of ring in BMU */
- SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
- (uint32_t)(((caddr_t)
- (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
- pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
- pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
- 0xFFFFFFFF));
- SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
- (uint32_t)(((caddr_t)
- (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
- pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
- pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
- SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
- (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
- pAC->RxPort[PortIndex].pRxDescrRing +
- pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
- SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
- (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
- pAC->RxPort[PortIndex].pRxDescrRing +
- pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
-} /* PortReInitBmu */
-
-
-/****************************************************************************
- *
- * SkGeIsr - handle adapter interrupts
- *
- * Description:
- * The interrupt routine is called when the network adapter
- * generates an interrupt. It may also be called if another device
- * shares this interrupt vector with the driver.
- *
- * Returns: N/A
- *
- */
-static SkIsrRetVar SkGeIsr(int irq, void *dev_id)
-{
-struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
-DEV_NET *pNet;
-SK_AC *pAC;
-SK_U32 IntSrc; /* interrupts source register contents */
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
- /*
- * Check and process if its our interrupt
- */
- SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
- if (IntSrc == 0) {
- return SkIsrRetNone;
- }
-
- while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
-#if 0 /* software irq currently not used */
- if (IntSrc & IS_IRQ_SW) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("Software IRQ\n"));
- }
-#endif
- if (IntSrc & IS_R1_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF RX1 IRQ\n"));
- ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
- SK_PNMI_CNT_RX_INTR(pAC, 0);
- }
- if (IntSrc & IS_R2_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF RX2 IRQ\n"));
- ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
- SK_PNMI_CNT_RX_INTR(pAC, 1);
- }
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
- if (IntSrc & IS_XA1_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF AS TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC, 0);
- spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
- FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
- spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
- }
- if (IntSrc & IS_XA2_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF AS TX2 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC, 1);
- spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
- FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
- spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
- }
-#if 0 /* only if sync. queues used */
- if (IntSrc & IS_XS1_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF SY TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC, 1);
- spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
- FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
- spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
- ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
- }
- if (IntSrc & IS_XS2_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF SY TX2 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC, 1);
- spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
- FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
- spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
- ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
- }
-#endif
-#endif
-
- /* do all IO at once */
- if (IntSrc & IS_R1_F)
- ClearAndStartRx(pAC, 0);
- if (IntSrc & IS_R2_F)
- ClearAndStartRx(pAC, 1);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
- if (IntSrc & IS_XA1_F)
- ClearTxIrq(pAC, 0, TX_PRIO_LOW);
- if (IntSrc & IS_XA2_F)
- ClearTxIrq(pAC, 1, TX_PRIO_LOW);
-#endif
- SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
- } /* while (IntSrc & IRQ_MASK != 0) */
-
- IntSrc &= pAC->GIni.GIValIrqMask;
- if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
- ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
- pAC->CheckQueue = SK_FALSE;
- spin_lock(&pAC->SlowPathLock);
- if (IntSrc & SPECIAL_IRQS)
- SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
-
- SkEventDispatcher(pAC, pAC->IoBase);
- spin_unlock(&pAC->SlowPathLock);
- }
- /*
- * do it all again is case we cleared an interrupt that
- * came in after handling the ring (OUTs may be delayed
- * in hardware buffers, but are through after IN)
- *
- * rroesler: has been commented out and shifted to
- * SkGeDrvEvent(), because it is timer
- * guarded now
- *
- ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
- ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
- */
-
- if (pAC->CheckQueue) {
- pAC->CheckQueue = SK_FALSE;
- spin_lock(&pAC->SlowPathLock);
- SkEventDispatcher(pAC, pAC->IoBase);
- spin_unlock(&pAC->SlowPathLock);
- }
-
- /* IRQ is processed - Enable IRQs again*/
- SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
-
- return SkIsrRetHandled;
-} /* SkGeIsr */
-
-
-/****************************************************************************
- *
- * SkGeIsrOnePort - handle adapter interrupts for single port adapter
- *
- * Description:
- * The interrupt routine is called when the network adapter
- * generates an interrupt. It may also be called if another device
- * shares this interrupt vector with the driver.
- * This is the same as above, but handles only one port.
- *
- * Returns: N/A
- *
- */
-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id)
-{
-struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
-DEV_NET *pNet;
-SK_AC *pAC;
-SK_U32 IntSrc; /* interrupts source register contents */
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
- /*
- * Check and process if its our interrupt
- */
- SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
- if (IntSrc == 0) {
- return SkIsrRetNone;
- }
-
- while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
-#if 0 /* software irq currently not used */
- if (IntSrc & IS_IRQ_SW) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("Software IRQ\n"));
- }
-#endif
- if (IntSrc & IS_R1_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF RX1 IRQ\n"));
- ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
- SK_PNMI_CNT_RX_INTR(pAC, 0);
- }
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
- if (IntSrc & IS_XA1_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF AS TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC, 0);
- spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
- FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
- spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
- }
-#if 0 /* only if sync. queues used */
- if (IntSrc & IS_XS1_F) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_INT_SRC,
- ("EOF SY TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC, 0);
- spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
- FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
- spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
- ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
- }
-#endif
-#endif
-
- /* do all IO at once */
- if (IntSrc & IS_R1_F)
- ClearAndStartRx(pAC, 0);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
- if (IntSrc & IS_XA1_F)
- ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-#endif
- SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
- } /* while (IntSrc & IRQ_MASK != 0) */
-
- IntSrc &= pAC->GIni.GIValIrqMask;
- if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
- ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
- pAC->CheckQueue = SK_FALSE;
- spin_lock(&pAC->SlowPathLock);
- if (IntSrc & SPECIAL_IRQS)
- SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
-
- SkEventDispatcher(pAC, pAC->IoBase);
- spin_unlock(&pAC->SlowPathLock);
- }
- /*
- * do it all again is case we cleared an interrupt that
- * came in after handling the ring (OUTs may be delayed
- * in hardware buffers, but are through after IN)
- *
- * rroesler: has been commented out and shifted to
- * SkGeDrvEvent(), because it is timer
- * guarded now
- *
- ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
- */
-
- /* IRQ is processed - Enable IRQs again*/
- SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
-
- return SkIsrRetHandled;
-} /* SkGeIsrOnePort */
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/****************************************************************************
- *
- * SkGePollController - polling receive, for netconsole
- *
- * Description:
- * Polling receive - used by netconsole and other diagnostic tools
- * to allow network i/o with interrupts disabled.
- *
- * Returns: N/A
- */
-static void SkGePollController(struct net_device *dev)
-{
- disable_irq(dev->irq);
- SkGeIsr(dev->irq, dev);
- enable_irq(dev->irq);
-}
-#endif
-
-/****************************************************************************
- *
- * SkGeOpen - handle start of initialized adapter
- *
- * Description:
- * This function starts the initialized adapter.
- * The board level variable is set and the adapter is
- * brought to full functionality.
- * The device flags are set for operation.
- * Do all necessary level 2 initialization, enable interrupts and
- * give start command to RLMT.
- *
- * Returns:
- * 0 on success
- * != 0 on error
- */
-static int SkGeOpen(
-struct SK_NET_DEVICE *dev)
-{
- DEV_NET *pNet;
- SK_AC *pAC;
- unsigned long Flags; /* for spin lock */
- int i;
- SK_EVPARA EvPara; /* an event parameter union */
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
-
-#ifdef SK_DIAG_SUPPORT
- if (pAC->DiagModeActive == DIAG_ACTIVE) {
- if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
- return (-1); /* still in use by diag; deny actions */
- }
- }
-#endif
-
- /* Set blink mode */
- if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
- pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
-
- if (pAC->BoardLevel == SK_INIT_DATA) {
- /* level 1 init common modules here */
- if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
- printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
- return (-1);
- }
- SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO);
- SkEventInit (pAC, pAC->IoBase, SK_INIT_IO);
- SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO);
- SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO);
- SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO);
- SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO);
- pAC->BoardLevel = SK_INIT_IO;
- }
-
- if (pAC->BoardLevel != SK_INIT_RUN) {
- /* tschilling: Level 2 init modules here, check return value. */
- if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
- printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
- return (-1);
- }
- SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN);
- SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN);
- SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN);
- SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN);
- SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN);
- SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN);
- pAC->BoardLevel = SK_INIT_RUN;
- }
-
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- /* Enable transmit descriptor polling. */
- SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
- FillRxRing(pAC, &pAC->RxPort[i]);
- }
- SkGeYellowLED(pAC, pAC->IoBase, 1);
-
- StartDrvCleanupTimer(pAC);
- SkDimEnableModerationIfNeeded(pAC);
- SkDimDisplayModerationSettings(pAC);
-
- pAC->GIni.GIValIrqMask &= IRQ_MASK;
-
- /* enable Interrupts */
- SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
- SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
- if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
- EvPara.Para32[0] = pAC->RlmtNets;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
- EvPara);
- EvPara.Para32[0] = pAC->RlmtMode;
- EvPara.Para32[1] = 0;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
- EvPara);
- }
-
- EvPara.Para32[0] = pNet->NetNr;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
- SkEventDispatcher(pAC, pAC->IoBase);
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- pAC->MaxPorts++;
-
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeOpen suceeded\n"));
-
- return (0);
-} /* SkGeOpen */
-
-
-/****************************************************************************
- *
- * SkGeClose - Stop initialized adapter
- *
- * Description:
- * Close initialized adapter.
- *
- * Returns:
- * 0 - on success
- * error code - on error
- */
-static int SkGeClose(
-struct SK_NET_DEVICE *dev)
-{
- DEV_NET *pNet;
- DEV_NET *newPtrNet;
- SK_AC *pAC;
-
- unsigned long Flags; /* for spin lock */
- int i;
- int PortIdx;
- SK_EVPARA EvPara;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
-#ifdef SK_DIAG_SUPPORT
- if (pAC->DiagModeActive == DIAG_ACTIVE) {
- if (pAC->DiagFlowCtrl == SK_FALSE) {
- /*
- ** notify that the interface which has been closed
- ** by operator interaction must not be started up
- ** again when the DIAG has finished.
- */
- newPtrNet = netdev_priv(pAC->dev[0]);
- if (newPtrNet == pNet) {
- pAC->WasIfUp[0] = SK_FALSE;
- } else {
- pAC->WasIfUp[1] = SK_FALSE;
- }
- return 0; /* return to system everything is fine... */
- } else {
- pAC->DiagFlowCtrl = SK_FALSE;
- }
- }
-#endif
-
- netif_stop_queue(dev);
-
- if (pAC->RlmtNets == 1)
- PortIdx = pAC->ActivePort;
- else
- PortIdx = pNet->NetNr;
-
- StopDrvCleanupTimer(pAC);
-
- /*
- * Clear multicast table, promiscuous mode ....
- */
- SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
- SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
- SK_PROM_MODE_NONE);
-
- if (pAC->MaxPorts == 1) {
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- /* disable interrupts */
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- EvPara.Para32[0] = pNet->NetNr;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- SkEventDispatcher(pAC, pAC->IoBase);
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- /* stop the hardware */
- SkGeDeInit(pAC, pAC->IoBase);
- pAC->BoardLevel = SK_INIT_DATA;
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- } else {
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- EvPara.Para32[0] = pNet->NetNr;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
- SkEventDispatcher(pAC, pAC->IoBase);
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- /* Stop port */
- spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
- [TX_PRIO_LOW].TxDesRingLock, Flags);
- SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
- SK_STOP_ALL, SK_HARD_RST);
- spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
- [TX_PRIO_LOW].TxDesRingLock, Flags);
- }
-
- if (pAC->RlmtNets == 1) {
- /* clear all descriptor rings */
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
- ClearRxRing(pAC, &pAC->RxPort[i]);
- ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
- }
- } else {
- /* clear port descriptor rings */
- ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
- ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
- ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
- }
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeClose: done "));
-
- SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
- SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct),
- sizeof(SK_PNMI_STRUCT_DATA));
-
- pAC->MaxPorts--;
-
- return (0);
-} /* SkGeClose */
-
-
-/*****************************************************************************
- *
- * SkGeXmit - Linux frame transmit function
- *
- * Description:
- * The system calls this function to send frames onto the wire.
- * It puts the frame in the tx descriptor ring. If the ring is
- * full then, the 'tbusy' flag is set.
- *
- * Returns:
- * 0, if everything is ok
- * !=0, on error
- * WARNING: returning 1 in 'tbusy' case caused system crashes (double
- * allocated skb's) !!!
- */
-static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
-{
-DEV_NET *pNet;
-SK_AC *pAC;
-int Rc; /* return code of XmitFrame */
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
- if ((!skb_shinfo(skb)->nr_frags) ||
- (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
- /* Don't activate scatter-gather and hardware checksum */
-
- if (pAC->RlmtNets == 2)
- Rc = XmitFrame(
- pAC,
- &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
- skb);
- else
- Rc = XmitFrame(
- pAC,
- &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
- skb);
- } else {
- /* scatter-gather and hardware TCP checksumming anabled*/
- if (pAC->RlmtNets == 2)
- Rc = XmitFrameSG(
- pAC,
- &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
- skb);
- else
- Rc = XmitFrameSG(
- pAC,
- &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
- skb);
- }
-
- /* Transmitter out of resources? */
- if (Rc <= 0) {
- netif_stop_queue(dev);
- }
-
- /* If not taken, give buffer ownership back to the
- * queueing layer.
- */
- if (Rc < 0)
- return (1);
-
- dev->trans_start = jiffies;
- return (0);
-} /* SkGeXmit */
-
-
-/*****************************************************************************
- *
- * XmitFrame - fill one socket buffer into the transmit ring
- *
- * Description:
- * This function puts a message into the transmit descriptor ring
- * if there is a descriptors left.
- * Linux skb's consist of only one continuous buffer.
- * The first step locks the ring. It is held locked
- * all time to avoid problems with SWITCH_../PORT_RESET.
- * Then the descriptoris allocated.
- * The second part is linking the buffer to the descriptor.
- * At the very last, the Control field of the descriptor
- * is made valid for the BMU and a start TX command is given
- * if necessary.
- *
- * Returns:
- * > 0 - on succes: the number of bytes in the message
- * = 0 - on resource shortage: this frame sent or dropped, now
- * the ring is full ( -> set tbusy)
- * < 0 - on failure: other problems ( -> return failure to upper layers)
- */
-static int XmitFrame(
-SK_AC *pAC, /* pointer to adapter context */
-TX_PORT *pTxPort, /* pointer to struct of port to send to */
-struct sk_buff *pMessage) /* pointer to send-message */
-{
- TXD *pTxd; /* the rxd to fill */
- TXD *pOldTxd;
- unsigned long Flags;
- SK_U64 PhysAddr;
- int BytesSend = pMessage->len;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
-
- spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-#ifndef USE_TX_COMPLETE
- FreeTxDescriptors(pAC, pTxPort);
-#endif
- if (pTxPort->TxdRingFree == 0) {
- /*
- ** no enough free descriptors in ring at the moment.
- ** Maybe free'ing some old one help?
- */
- FreeTxDescriptors(pAC, pTxPort);
- if (pTxPort->TxdRingFree == 0) {
- spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
- SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_TX_PROGRESS,
- ("XmitFrame failed\n"));
- /*
- ** the desired message can not be sent
- ** Because tbusy seems to be set, the message
- ** should not be freed here. It will be used
- ** by the scheduler of the ethernet handler
- */
- return (-1);
- }
- }
-
- /*
- ** If the passed socket buffer is of smaller MTU-size than 60,
- ** copy everything into new buffer and fill all bytes between
- ** the original packet end and the new packet end of 60 with 0x00.
- ** This is to resolve faulty padding by the HW with 0xaa bytes.
- */
- if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
- if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) {
- spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
- return 0;
- }
- pMessage->len = C_LEN_ETHERNET_MINSIZE;
- }
-
- /*
- ** advance head counter behind descriptor needed for this frame,
- ** so that needed descriptor is reserved from that on. The next
- ** action will be to add the passed buffer to the TX-descriptor
- */
- pTxd = pTxPort->pTxdRingHead;
- pTxPort->pTxdRingHead = pTxd->pNextTxd;
- pTxPort->TxdRingFree--;
-
-#ifdef SK_DUMP_TX
- DumpMsg(pMessage, "XmitFrame");
-#endif
-
- /*
- ** First step is to map the data to be sent via the adapter onto
- ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
- ** and 2.6 need to use pci_map_page() for that mapping.
- */
- PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
- virt_to_page(pMessage->data),
- ((unsigned long) pMessage->data & ~PAGE_MASK),
- pMessage->len,
- PCI_DMA_TODEVICE);
- pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
- pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
- pTxd->pMBuf = pMessage;
-
- if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
- u16 hdrlen = skb_transport_offset(pMessage);
- u16 offset = hdrlen + pMessage->csum_offset;
-
- if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
- (pAC->GIni.GIChipRev == 0) &&
- (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
- pTxd->TBControl = BMU_TCP_CHECK;
- } else {
- pTxd->TBControl = BMU_UDP_CHECK;
- }
-
- pTxd->TcpSumOfs = 0;
- pTxd->TcpSumSt = hdrlen;
- pTxd->TcpSumWr = offset;
-
- pTxd->TBControl |= BMU_OWN | BMU_STF |
- BMU_SW | BMU_EOF |
-#ifdef USE_TX_COMPLETE
- BMU_IRQ_EOF |
-#endif
- pMessage->len;
- } else {
- pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK |
- BMU_SW | BMU_EOF |
-#ifdef USE_TX_COMPLETE
- BMU_IRQ_EOF |
-#endif
- pMessage->len;
- }
-
- /*
- ** If previous descriptor already done, give TX start cmd
- */
- pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
- if ((pOldTxd->TBControl & BMU_OWN) == 0) {
- SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
- }
-
- /*
- ** after releasing the lock, the skb may immediately be free'd
- */
- spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
- if (pTxPort->TxdRingFree != 0) {
- return (BytesSend);
- } else {
- return (0);
- }
-
-} /* XmitFrame */
-
-/*****************************************************************************
- *
- * XmitFrameSG - fill one socket buffer into the transmit ring
- * (use SG and TCP/UDP hardware checksumming)
- *
- * Description:
- * This function puts a message into the transmit descriptor ring
- * if there is a descriptors left.
- *
- * Returns:
- * > 0 - on succes: the number of bytes in the message
- * = 0 - on resource shortage: this frame sent or dropped, now
- * the ring is full ( -> set tbusy)
- * < 0 - on failure: other problems ( -> return failure to upper layers)
- */
-static int XmitFrameSG(
-SK_AC *pAC, /* pointer to adapter context */
-TX_PORT *pTxPort, /* pointer to struct of port to send to */
-struct sk_buff *pMessage) /* pointer to send-message */
-{
-
- TXD *pTxd;
- TXD *pTxdFst;
- TXD *pTxdLst;
- int CurrFrag;
- int BytesSend;
- skb_frag_t *sk_frag;
- SK_U64 PhysAddr;
- unsigned long Flags;
- SK_U32 Control;
-
- spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
-#ifndef USE_TX_COMPLETE
- FreeTxDescriptors(pAC, pTxPort);
-#endif
- if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
- FreeTxDescriptors(pAC, pTxPort);
- if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
- spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
- SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_TX_PROGRESS,
- ("XmitFrameSG failed - Ring full\n"));
- /* this message can not be sent now */
- return(-1);
- }
- }
-
- pTxd = pTxPort->pTxdRingHead;
- pTxdFst = pTxd;
- pTxdLst = pTxd;
- BytesSend = 0;
-
- /*
- ** Map the first fragment (header) into the DMA-space
- */
- PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
- virt_to_page(pMessage->data),
- ((unsigned long) pMessage->data & ~PAGE_MASK),
- skb_headlen(pMessage),
- PCI_DMA_TODEVICE);
-
- pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
- pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
-
- /*
- ** Does the HW need to evaluate checksum for TCP or UDP packets?
- */
- if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
- u16 hdrlen = skb_transport_offset(pMessage);
- u16 offset = hdrlen + pMessage->csum_offset;
-
- Control = BMU_STFWD;
-
- /*
- ** We have to use the opcode for tcp here, because the
- ** opcode for udp is not working in the hardware yet
- ** (Revision 2.0)
- */
- if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
- (pAC->GIni.GIChipRev == 0) &&
- (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
- Control |= BMU_TCP_CHECK;
- } else {
- Control |= BMU_UDP_CHECK;
- }
-
- pTxd->TcpSumOfs = 0;
- pTxd->TcpSumSt = hdrlen;
- pTxd->TcpSumWr = offset;
- } else
- Control = BMU_CHECK | BMU_SW;
-
- pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage);
-
- pTxd = pTxd->pNextTxd;
- pTxPort->TxdRingFree--;
- BytesSend += skb_headlen(pMessage);
-
- /*
- ** Browse over all SG fragments and map each of them into the DMA space
- */
- for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
- sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
- /*
- ** we already have the proper value in entry
- */
- PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
- sk_frag->page,
- sk_frag->page_offset,
- sk_frag->size,
- PCI_DMA_TODEVICE);
-
- pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
- pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
- pTxd->pMBuf = pMessage;
-
- pTxd->TBControl = Control | BMU_OWN | sk_frag->size;
-
- /*
- ** Do we have the last fragment?
- */
- if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) {
-#ifdef USE_TX_COMPLETE
- pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF;
-#else
- pTxd->TBControl |= BMU_EOF;
-#endif
- pTxdFst->TBControl |= BMU_OWN | BMU_SW;
- }
- pTxdLst = pTxd;
- pTxd = pTxd->pNextTxd;
- pTxPort->TxdRingFree--;
- BytesSend += sk_frag->size;
- }
-
- /*
- ** If previous descriptor already done, give TX start cmd
- */
- if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
- SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
- }
-
- pTxPort->pTxdRingPrev = pTxdLst;
- pTxPort->pTxdRingHead = pTxd;
-
- spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-
- if (pTxPort->TxdRingFree > 0) {
- return (BytesSend);
- } else {
- return (0);
- }
-}
-
-/*****************************************************************************
- *
- * FreeTxDescriptors - release descriptors from the descriptor ring
- *
- * Description:
- * This function releases descriptors from a transmit ring if they
- * have been sent by the BMU.
- * If a descriptors is sent, it can be freed and the message can
- * be freed, too.
- * The SOFTWARE controllable bit is used to prevent running around a
- * completely free ring for ever. If this bit is no set in the
- * frame (by XmitFrame), this frame has never been sent or is
- * already freed.
- * The Tx descriptor ring lock must be held while calling this function !!!
- *
- * Returns:
- * none
- */
-static void FreeTxDescriptors(
-SK_AC *pAC, /* pointer to the adapter context */
-TX_PORT *pTxPort) /* pointer to destination port structure */
-{
-TXD *pTxd; /* pointer to the checked descriptor */
-TXD *pNewTail; /* pointer to 'end' of the ring */
-SK_U32 Control; /* TBControl field of descriptor */
-SK_U64 PhysAddr; /* address of DMA mapping */
-
- pNewTail = pTxPort->pTxdRingTail;
- pTxd = pNewTail;
- /*
- ** loop forever; exits if BMU_SW bit not set in start frame
- ** or BMU_OWN bit set in any frame
- */
- while (1) {
- Control = pTxd->TBControl;
- if ((Control & BMU_SW) == 0) {
- /*
- ** software controllable bit is set in first
- ** fragment when given to BMU. Not set means that
- ** this fragment was never sent or is already
- ** freed ( -> ring completely free now).
- */
- pTxPort->pTxdRingTail = pTxd;
- netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
- return;
- }
- if (Control & BMU_OWN) {
- pTxPort->pTxdRingTail = pTxd;
- if (pTxPort->TxdRingFree > 0) {
- netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
- }
- return;
- }
-
- /*
- ** release the DMA mapping, because until not unmapped
- ** this buffer is considered being under control of the
- ** adapter card!
- */
- PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
- PhysAddr |= (SK_U64) pTxd->VDataLow;
- pci_unmap_page(pAC->PciDev, PhysAddr,
- pTxd->pMBuf->len,
- PCI_DMA_TODEVICE);
-
- if (Control & BMU_EOF)
- DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
-
- pTxPort->TxdRingFree++;
- pTxd->TBControl &= ~BMU_SW;
- pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
- } /* while(forever) */
-} /* FreeTxDescriptors */
-
-/*****************************************************************************
- *
- * FillRxRing - fill the receive ring with valid descriptors
- *
- * Description:
- * This function fills the receive ring descriptors with data
- * segments and makes them valid for the BMU.
- * The active ring is filled completely, if possible.
- * The non-active ring is filled only partial to save memory.
- *
- * Description of rx ring structure:
- * head - points to the descriptor which will be used next by the BMU
- * tail - points to the next descriptor to give to the BMU
- *
- * Returns: N/A
- */
-static void FillRxRing(
-SK_AC *pAC, /* pointer to the adapter context */
-RX_PORT *pRxPort) /* ptr to port struct for which the ring
- should be filled */
-{
-unsigned long Flags;
-
- spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
- while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
- if(!FillRxDescriptor(pAC, pRxPort))
- break;
- }
- spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
-} /* FillRxRing */
-
-
-/*****************************************************************************
- *
- * FillRxDescriptor - fill one buffer into the receive ring
- *
- * Description:
- * The function allocates a new receive buffer and
- * puts it into the next descriptor.
- *
- * Returns:
- * SK_TRUE - a buffer was added to the ring
- * SK_FALSE - a buffer could not be added
- */
-static SK_BOOL FillRxDescriptor(
-SK_AC *pAC, /* pointer to the adapter context struct */
-RX_PORT *pRxPort) /* ptr to port struct of ring to fill */
-{
-struct sk_buff *pMsgBlock; /* pointer to a new message block */
-RXD *pRxd; /* the rxd to fill */
-SK_U16 Length; /* data fragment length */
-SK_U64 PhysAddr; /* physical address of a rx buffer */
-
- pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
- if (pMsgBlock == NULL) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_ENTRY,
- ("%s: Allocation of rx buffer failed !\n",
- pAC->dev[pRxPort->PortIndex]->name));
- SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
- return(SK_FALSE);
- }
- skb_reserve(pMsgBlock, 2); /* to align IP frames */
- /* skb allocated ok, so add buffer */
- pRxd = pRxPort->pRxdRingTail;
- pRxPort->pRxdRingTail = pRxd->pNextRxd;
- pRxPort->RxdRingFree--;
- Length = pAC->RxBufSize;
- PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
- virt_to_page(pMsgBlock->data),
- ((unsigned long) pMsgBlock->data &
- ~PAGE_MASK),
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
-
- pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
- pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
- pRxd->pMBuf = pMsgBlock;
- pRxd->RBControl = BMU_OWN |
- BMU_STF |
- BMU_IRQ_EOF |
- BMU_TCP_CHECK |
- Length;
- return (SK_TRUE);
-
-} /* FillRxDescriptor */
-
-
-/*****************************************************************************
- *
- * ReQueueRxBuffer - fill one buffer back into the receive ring
- *
- * Description:
- * Fill a given buffer back into the rx ring. The buffer
- * has been previously allocated and aligned, and its phys.
- * address calculated, so this is no more necessary.
- *
- * Returns: N/A
- */
-static void ReQueueRxBuffer(
-SK_AC *pAC, /* pointer to the adapter context struct */
-RX_PORT *pRxPort, /* ptr to port struct of ring to fill */
-struct sk_buff *pMsg, /* pointer to the buffer */
-SK_U32 PhysHigh, /* phys address high dword */
-SK_U32 PhysLow) /* phys address low dword */
-{
-RXD *pRxd; /* the rxd to fill */
-SK_U16 Length; /* data fragment length */
-
- pRxd = pRxPort->pRxdRingTail;
- pRxPort->pRxdRingTail = pRxd->pNextRxd;
- pRxPort->RxdRingFree--;
- Length = pAC->RxBufSize;
-
- pRxd->VDataLow = PhysLow;
- pRxd->VDataHigh = PhysHigh;
- pRxd->pMBuf = pMsg;
- pRxd->RBControl = BMU_OWN |
- BMU_STF |
- BMU_IRQ_EOF |
- BMU_TCP_CHECK |
- Length;
- return;
-} /* ReQueueRxBuffer */
-
-/*****************************************************************************
- *
- * ReceiveIrq - handle a receive IRQ
- *
- * Description:
- * This function is called when a receive IRQ is set.
- * It walks the receive descriptor ring and sends up all
- * frames that are complete.
- *
- * Returns: N/A
- */
-static void ReceiveIrq(
- SK_AC *pAC, /* pointer to adapter context */
- RX_PORT *pRxPort, /* pointer to receive port struct */
- SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */
-{
-RXD *pRxd; /* pointer to receive descriptors */
-SK_U32 Control; /* control field of descriptor */
-struct sk_buff *pMsg; /* pointer to message holding frame */
-struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */
-int FrameLength; /* total length of received frame */
-SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */
-SK_EVPARA EvPara; /* an event parameter union */
-unsigned long Flags; /* for spin lock */
-int PortIndex = pRxPort->PortIndex;
-unsigned int Offset;
-unsigned int NumBytes;
-unsigned int ForRlmt;
-SK_BOOL IsBc;
-SK_BOOL IsMc;
-SK_BOOL IsBadFrame; /* Bad frame */
-
-SK_U32 FrameStat;
-SK_U64 PhysAddr;
-
-rx_start:
- /* do forever; exit if BMU_OWN found */
- for ( pRxd = pRxPort->pRxdRingHead ;
- pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
- pRxd = pRxd->pNextRxd,
- pRxPort->pRxdRingHead = pRxd,
- pRxPort->RxdRingFree ++) {
-
- /*
- * For a better understanding of this loop
- * Go through every descriptor beginning at the head
- * Please note: the ring might be completely received so the OWN bit
- * set is not a good crirteria to leave that loop.
- * Therefore the RingFree counter is used.
- * On entry of this loop pRxd is a pointer to the Rxd that needs
- * to be checked next.
- */
-
- Control = pRxd->RBControl;
-
- /* check if this descriptor is ready */
- if ((Control & BMU_OWN) != 0) {
- /* this descriptor is not yet ready */
- /* This is the usual end of the loop */
- /* We don't need to start the ring again */
- FillRxRing(pAC, pRxPort);
- return;
- }
- pAC->DynIrqModInfo.NbrProcessedDescr++;
-
- /* get length of frame and check it */
- FrameLength = Control & BMU_BBC;
- if (FrameLength > pAC->RxBufSize) {
- goto rx_failed;
- }
-
- /* check for STF and EOF */
- if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
- goto rx_failed;
- }
-
- /* here we have a complete frame in the ring */
- pMsg = pRxd->pMBuf;
-
- FrameStat = pRxd->FrameStat;
-
- /* check for frame length mismatch */
-#define XMR_FS_LEN_SHIFT 18
-#define GMR_FS_LEN_SHIFT 16
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
- if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("skge: Frame length mismatch (%u/%u).\n",
- FrameLength,
- (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
- goto rx_failed;
- }
- }
- else {
- if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("skge: Frame length mismatch (%u/%u).\n",
- FrameLength,
- (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
- goto rx_failed;
- }
- }
-
- /* Set Rx Status */
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
- IsBc = (FrameStat & XMR_FS_BC) != 0;
- IsMc = (FrameStat & XMR_FS_MC) != 0;
- IsBadFrame = (FrameStat &
- (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
- } else {
- IsBc = (FrameStat & GMR_FS_BC) != 0;
- IsMc = (FrameStat & GMR_FS_MC) != 0;
- IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
- ((FrameStat & GMR_FS_RX_OK) == 0));
- }
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
- ("Received frame of length %d on port %d\n",
- FrameLength, PortIndex));
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
- ("Number of free rx descriptors: %d\n",
- pRxPort->RxdRingFree));
-/* DumpMsg(pMsg, "Rx"); */
-
- if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
-#if 0
- (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
-#endif
- /* there is a receive error in this frame */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("skge: Error in received frame, dropped!\n"
- "Control: %x\nRxStat: %x\n",
- Control, FrameStat));
-
- ReQueueRxBuffer(pAC, pRxPort, pMsg,
- pRxd->VDataHigh, pRxd->VDataLow);
-
- continue;
- }
-
- /*
- * if short frame then copy data to reduce memory waste
- */
- if ((FrameLength < SK_COPY_THRESHOLD) &&
- ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
- /*
- * Short frame detected and allocation successfull
- */
- /* use new skb and copy data */
- skb_reserve(pNewMsg, 2);
- skb_put(pNewMsg, FrameLength);
- PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
- PhysAddr |= (SK_U64) pRxd->VDataLow;
-
- pci_dma_sync_single_for_cpu(pAC->PciDev,
- (dma_addr_t) PhysAddr,
- FrameLength,
- PCI_DMA_FROMDEVICE);
- skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength);
-
- pci_dma_sync_single_for_device(pAC->PciDev,
- (dma_addr_t) PhysAddr,
- FrameLength,
- PCI_DMA_FROMDEVICE);
- ReQueueRxBuffer(pAC, pRxPort, pMsg,
- pRxd->VDataHigh, pRxd->VDataLow);
-
- pMsg = pNewMsg;
-
- }
- else {
- /*
- * if large frame, or SKB allocation failed, pass
- * the SKB directly to the networking
- */
-
- PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
- PhysAddr |= (SK_U64) pRxd->VDataLow;
-
- /* release the DMA mapping */
- pci_unmap_single(pAC->PciDev,
- PhysAddr,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
-
- /* set length in message */
- skb_put(pMsg, FrameLength);
- } /* frame > SK_COPY_TRESHOLD */
-
-#ifdef USE_SK_RX_CHECKSUM
- pMsg->csum = pRxd->TcpSums & 0xffff;
- pMsg->ip_summed = CHECKSUM_COMPLETE;
-#else
- pMsg->ip_summed = CHECKSUM_NONE;
-#endif
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
- ForRlmt = SK_RLMT_RX_PROTOCOL;
-#if 0
- IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
-#endif
- SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
- IsBc, &Offset, &NumBytes);
- if (NumBytes != 0) {
-#if 0
- IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
-#endif
- SK_RLMT_LOOKAHEAD(pAC, PortIndex,
- &pMsg->data[Offset],
- IsBc, IsMc, &ForRlmt);
- }
- if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
- /* send up only frames from active port */
- if ((PortIndex == pAC->ActivePort) ||
- (pAC->RlmtNets == 2)) {
- /* frame for upper layer */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
-#ifdef xDEBUG
- DumpMsg(pMsg, "Rx");
-#endif
- SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
- FrameLength, pRxPort->PortIndex);
-
- pMsg->protocol = eth_type_trans(pMsg,
- pAC->dev[pRxPort->PortIndex]);
- netif_rx(pMsg);
- pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
- }
- else {
- /* drop frame */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("D"));
- DEV_KFREE_SKB(pMsg);
- }
-
- } /* if not for rlmt */
- else {
- /* packet for rlmt */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
- pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
- pAC->IoBase, FrameLength);
- if (pRlmtMbuf != NULL) {
- pRlmtMbuf->pNext = NULL;
- pRlmtMbuf->Length = FrameLength;
- pRlmtMbuf->PortIdx = PortIndex;
- EvPara.pParaPtr = pRlmtMbuf;
- memcpy((char*)(pRlmtMbuf->pData),
- (char*)(pMsg->data),
- FrameLength);
-
- /* SlowPathLock needed? */
- if (SlowPathLock == SK_TRUE) {
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- SkEventQueue(pAC, SKGE_RLMT,
- SK_RLMT_PACKET_RECEIVED,
- EvPara);
- pAC->CheckQueue = SK_TRUE;
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- } else {
- SkEventQueue(pAC, SKGE_RLMT,
- SK_RLMT_PACKET_RECEIVED,
- EvPara);
- pAC->CheckQueue = SK_TRUE;
- }
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("Q"));
- }
- if ((pAC->dev[pRxPort->PortIndex]->flags &
- (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
- (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
- SK_RLMT_RX_PROTOCOL) {
- pMsg->protocol = eth_type_trans(pMsg,
- pAC->dev[pRxPort->PortIndex]);
- netif_rx(pMsg);
- pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
- }
- else {
- DEV_KFREE_SKB(pMsg);
- }
-
- } /* if packet for rlmt */
- } /* for ... scanning the RXD ring */
-
- /* RXD ring is empty -> fill and restart */
- FillRxRing(pAC, pRxPort);
- /* do not start if called from Close */
- if (pAC->BoardLevel > SK_INIT_DATA) {
- ClearAndStartRx(pAC, PortIndex);
- }
- return;
-
-rx_failed:
- /* remove error frame */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
- ("Schrottdescriptor, length: 0x%x\n", FrameLength));
-
- /* release the DMA mapping */
-
- PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
- PhysAddr |= (SK_U64) pRxd->VDataLow;
- pci_unmap_page(pAC->PciDev,
- PhysAddr,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
- DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
- pRxd->pMBuf = NULL;
- pRxPort->RxdRingFree++;
- pRxPort->pRxdRingHead = pRxd->pNextRxd;
- goto rx_start;
-
-} /* ReceiveIrq */
-
-
-/*****************************************************************************
- *
- * ClearAndStartRx - give a start receive command to BMU, clear IRQ
- *
- * Description:
- * This function sends a start command and a clear interrupt
- * command for one receive queue to the BMU.
- *
- * Returns: N/A
- * none
- */
-static void ClearAndStartRx(
-SK_AC *pAC, /* pointer to the adapter context */
-int PortIndex) /* index of the receive port (XMAC) */
-{
- SK_OUT8(pAC->IoBase,
- RxQueueAddr[PortIndex]+Q_CSR,
- CSR_START | CSR_IRQ_CL_F);
-} /* ClearAndStartRx */
-
-
-/*****************************************************************************
- *
- * ClearTxIrq - give a clear transmit IRQ command to BMU
- *
- * Description:
- * This function sends a clear tx IRQ command for one
- * transmit queue to the BMU.
- *
- * Returns: N/A
- */
-static void ClearTxIrq(
-SK_AC *pAC, /* pointer to the adapter context */
-int PortIndex, /* index of the transmit port (XMAC) */
-int Prio) /* priority or normal queue */
-{
- SK_OUT8(pAC->IoBase,
- TxQueueAddr[PortIndex][Prio]+Q_CSR,
- CSR_IRQ_CL_F);
-} /* ClearTxIrq */
-
-
-/*****************************************************************************
- *
- * ClearRxRing - remove all buffers from the receive ring
- *
- * Description:
- * This function removes all receive buffers from the ring.
- * The receive BMU must be stopped before calling this function.
- *
- * Returns: N/A
- */
-static void ClearRxRing(
-SK_AC *pAC, /* pointer to adapter context */
-RX_PORT *pRxPort) /* pointer to rx port struct */
-{
-RXD *pRxd; /* pointer to the current descriptor */
-unsigned long Flags;
-SK_U64 PhysAddr;
-
- if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
- return;
- }
- spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
- pRxd = pRxPort->pRxdRingHead;
- do {
- if (pRxd->pMBuf != NULL) {
-
- PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
- PhysAddr |= (SK_U64) pRxd->VDataLow;
- pci_unmap_page(pAC->PciDev,
- PhysAddr,
- pAC->RxBufSize - 2,
- PCI_DMA_FROMDEVICE);
- DEV_KFREE_SKB(pRxd->pMBuf);
- pRxd->pMBuf = NULL;
- }
- pRxd->RBControl &= BMU_OWN;
- pRxd = pRxd->pNextRxd;
- pRxPort->RxdRingFree++;
- } while (pRxd != pRxPort->pRxdRingTail);
- pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
- spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
-} /* ClearRxRing */
-
-/*****************************************************************************
- *
- * ClearTxRing - remove all buffers from the transmit ring
- *
- * Description:
- * This function removes all transmit buffers from the ring.
- * The transmit BMU must be stopped before calling this function
- * and transmitting at the upper level must be disabled.
- * The BMU own bit of all descriptors is cleared, the rest is
- * done by calling FreeTxDescriptors.
- *
- * Returns: N/A
- */
-static void ClearTxRing(
-SK_AC *pAC, /* pointer to adapter context */
-TX_PORT *pTxPort) /* pointer to tx prt struct */
-{
-TXD *pTxd; /* pointer to the current descriptor */
-int i;
-unsigned long Flags;
-
- spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
- pTxd = pTxPort->pTxdRingHead;
- for (i=0; i<pAC->TxDescrPerRing; i++) {
- pTxd->TBControl &= ~BMU_OWN;
- pTxd = pTxd->pNextTxd;
- }
- FreeTxDescriptors(pAC, pTxPort);
- spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
-} /* ClearTxRing */
-
-/*****************************************************************************
- *
- * SkGeSetMacAddr - Set the hardware MAC address
- *
- * Description:
- * This function sets the MAC address used by the adapter.
- *
- * Returns:
- * 0, if everything is ok
- * !=0, on error
- */
-static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
-{
-
-DEV_NET *pNet = netdev_priv(dev);
-SK_AC *pAC = pNet->pAC;
-
-struct sockaddr *addr = p;
-unsigned long Flags;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeSetMacAddr starts now...\n"));
- if(netif_running(dev))
- return -EBUSY;
-
- memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
- if (pAC->RlmtNets == 2)
- SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
- (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
- else
- SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
- (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
-
-
-
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return 0;
-} /* SkGeSetMacAddr */
-
-
-/*****************************************************************************
- *
- * SkGeSetRxMode - set receive mode
- *
- * Description:
- * This function sets the receive mode of an adapter. The adapter
- * supports promiscuous mode, allmulticast mode and a number of
- * multicast addresses. If more multicast addresses the available
- * are selected, a hash function in the hardware is used.
- *
- * Returns:
- * 0, if everything is ok
- * !=0, on error
- */
-static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
-{
-
-DEV_NET *pNet;
-SK_AC *pAC;
-
-struct dev_mc_list *pMcList;
-int i;
-int PortIdx;
-unsigned long Flags;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeSetRxMode starts now... "));
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
- if (pAC->RlmtNets == 1)
- PortIdx = pAC->ActivePort;
- else
- PortIdx = pNet->NetNr;
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- if (dev->flags & IFF_PROMISC) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("PROMISCUOUS mode\n"));
- SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
- SK_PROM_MODE_LLC);
- } else if (dev->flags & IFF_ALLMULTI) {
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("ALLMULTI mode\n"));
- SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
- SK_PROM_MODE_ALL_MC);
- } else {
- SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
- SK_PROM_MODE_NONE);
- SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("Number of MC entries: %d ", dev->mc_count));
-
- pMcList = dev->mc_list;
- for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
- SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
- (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
- ("%02x:%02x:%02x:%02x:%02x:%02x\n",
- pMcList->dmi_addr[0],
- pMcList->dmi_addr[1],
- pMcList->dmi_addr[2],
- pMcList->dmi_addr[3],
- pMcList->dmi_addr[4],
- pMcList->dmi_addr[5]));
- }
- SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
- }
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- return;
-} /* SkGeSetRxMode */
-
-
-/*****************************************************************************
- *
- * SkGeChangeMtu - set the MTU to another value
- *
- * Description:
- * This function sets is called whenever the MTU size is changed
- * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
- * ethernet MTU size, long frame support is activated.
- *
- * Returns:
- * 0, if everything is ok
- * !=0, on error
- */
-static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
-{
-DEV_NET *pNet;
-struct net_device *pOtherDev;
-SK_AC *pAC;
-unsigned long Flags;
-int i;
-SK_EVPARA EvPara;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeChangeMtu starts now...\n"));
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
- if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
- return -EINVAL;
- }
-
- if(pAC->BoardLevel != SK_INIT_RUN) {
- return -EINVAL;
- }
-
-#ifdef SK_DIAG_SUPPORT
- if (pAC->DiagModeActive == DIAG_ACTIVE) {
- if (pAC->DiagFlowCtrl == SK_FALSE) {
- return -1; /* still in use, deny any actions of MTU */
- } else {
- pAC->DiagFlowCtrl = SK_FALSE;
- }
- }
-#endif
-
- pOtherDev = pAC->dev[1 - pNet->NetNr];
-
- if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
- && (NewMtu <= 1500))
- return 0;
-
- pAC->RxBufSize = NewMtu + 32;
- dev->mtu = NewMtu;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("New MTU: %d\n", NewMtu));
-
- /*
- ** Prevent any reconfiguration while changing the MTU
- ** by disabling any interrupts
- */
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-
- /*
- ** Notify RLMT that any ports are to be stopped
- */
- EvPara.Para32[0] = 0;
- EvPara.Para32[1] = -1;
- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- EvPara.Para32[0] = 1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- } else {
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- }
-
- /*
- ** After calling the SkEventDispatcher(), RLMT is aware about
- ** the stopped ports -> configuration can take place!
- */
- SkEventDispatcher(pAC, pAC->IoBase);
-
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
- netif_stop_queue(pAC->dev[i]);
-
- }
-
- /*
- ** Depending on the desired MTU size change, a different number of
- ** RX buffers need to be allocated
- */
- if (NewMtu > 1500) {
- /*
- ** Use less rx buffers
- */
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
- (pAC->RxDescrPerRing / 4);
- } else {
- if (i == pAC->ActivePort) {
- pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
- (pAC->RxDescrPerRing / 4);
- } else {
- pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
- (pAC->RxDescrPerRing / 10);
- }
- }
- }
- } else {
- /*
- ** Use the normal amount of rx buffers
- */
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- pAC->RxPort[i].RxFillLimit = 1;
- } else {
- if (i == pAC->ActivePort) {
- pAC->RxPort[i].RxFillLimit = 1;
- } else {
- pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
- (pAC->RxDescrPerRing / 4);
- }
- }
- }
- }
-
- SkGeDeInit(pAC, pAC->IoBase);
-
- /*
- ** enable/disable hardware support for long frames
- */
- if (NewMtu > 1500) {
-// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
- pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
- } else {
- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- pAC->GIni.GIPortUsage = SK_MUL_LINK;
- } else {
- pAC->GIni.GIPortUsage = SK_RED_LINK;
- }
- }
-
- SkGeInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
- SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
- SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
-
- /*
- ** tschilling:
- ** Speed and others are set back to default in level 1 init!
- */
- GetConfiguration(pAC);
-
- SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN);
- SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN);
- SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
- SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
- SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
- SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
- SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
-
- /*
- ** clear and reinit the rx rings here
- */
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
- ClearRxRing(pAC, &pAC->RxPort[i]);
- FillRxRing(pAC, &pAC->RxPort[i]);
-
- /*
- ** Enable transmit descriptor polling
- */
- SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
- FillRxRing(pAC, &pAC->RxPort[i]);
- };
-
- SkGeYellowLED(pAC, pAC->IoBase, 1);
- SkDimEnableModerationIfNeeded(pAC);
- SkDimDisplayModerationSettings(pAC);
-
- netif_start_queue(pAC->dev[pNet->PortNr]);
- for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
- spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
- }
-
- /*
- ** Enable Interrupts again
- */
- SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
- SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
-
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
- SkEventDispatcher(pAC, pAC->IoBase);
-
- /*
- ** Notify RLMT about the changing and restarting one (or more) ports
- */
- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- EvPara.Para32[0] = pAC->RlmtNets;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
- EvPara.Para32[0] = pNet->PortNr;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
-
- if (netif_running(pOtherDev)) {
- DEV_NET *pOtherNet = netdev_priv(pOtherDev);
- EvPara.Para32[0] = pOtherNet->PortNr;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
- }
- } else {
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
- }
-
- SkEventDispatcher(pAC, pAC->IoBase);
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- /*
- ** While testing this driver with latest kernel 2.5 (2.5.70), it
- ** seems as if upper layers have a problem to handle a successful
- ** return value of '0'. If such a zero is returned, the complete
- ** system hangs for several minutes (!), which is in acceptable.
- **
- ** Currently it is not clear, what the exact reason for this problem
- ** is. The implemented workaround for 2.5 is to return the desired
- ** new MTU size if all needed changes for the new MTU size where
- ** performed. In kernels 2.2 and 2.4, a zero value is returned,
- ** which indicates the successful change of the mtu-size.
- */
- return NewMtu;
-
-} /* SkGeChangeMtu */
-
-
-/*****************************************************************************
- *
- * SkGeStats - return ethernet device statistics
- *
- * Description:
- * This function return statistic data about the ethernet device
- * to the operating system.
- *
- * Returns:
- * pointer to the statistic structure.
- */
-static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
-{
-DEV_NET *pNet = netdev_priv(dev);
-SK_AC *pAC = pNet->pAC;
-SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
-SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */
-SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */
-unsigned int Size; /* size of pnmi struct */
-unsigned long Flags; /* for spin lock */
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeStats starts now...\n"));
- pPnmiStruct = &pAC->PnmiStruct;
-
-#ifdef SK_DIAG_SUPPORT
- if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
- (pAC->BoardLevel == SK_INIT_RUN)) {
-#endif
- SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- Size = SK_PNMI_STRUCT_SIZE;
- SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-#ifdef SK_DIAG_SUPPORT
- }
-#endif
-
- pPnmiStat = &pPnmiStruct->Stat[0];
- pPnmiConf = &pPnmiStruct->Conf[0];
-
- pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
- pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
- pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
- pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
-
- if (dev->mtu <= 1500) {
- pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
- } else {
- pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
- pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
- }
-
-
- if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
- pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
-
- pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
- pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
- pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
- pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
- pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
-
- /* detailed rx_errors: */
- pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
- pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
- pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
- pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
- pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
- pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
-
- /* detailed tx_errors */
- pAC->stats.tx_aborted_errors = (SK_U32) 0;
- pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
- pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
- pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
- pAC->stats.tx_window_errors = (SK_U32) 0;
-
- return(&pAC->stats);
-} /* SkGeStats */
-
-/*
- * Basic MII register access
- */
-static int SkGeMiiIoctl(struct net_device *dev,
- struct mii_ioctl_data *data, int cmd)
-{
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- SK_IOC IoC = pAC->IoBase;
- int Port = pNet->PortNr;
- SK_GEPORT *pPrt = &pAC->GIni.GP[Port];
- unsigned long Flags;
- int err = 0;
- int reg = data->reg_num & 0x1f;
- SK_U16 val = data->val_in;
-
- if (!netif_running(dev))
- return -ENODEV; /* Phy still in reset */
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- switch(cmd) {
- case SIOCGMIIPHY:
- data->phy_id = pPrt->PhyAddr;
-
- /* fallthru */
- case SIOCGMIIREG:
- if (pAC->GIni.GIGenesis)
- SkXmPhyRead(pAC, IoC, Port, reg, &val);
- else
- SkGmPhyRead(pAC, IoC, Port, reg, &val);
-
- data->val_out = val;
- break;
-
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- err = -EPERM;
-
- else if (pAC->GIni.GIGenesis)
- SkXmPhyWrite(pAC, IoC, Port, reg, val);
- else
- SkGmPhyWrite(pAC, IoC, Port, reg, val);
- break;
- default:
- err = -EOPNOTSUPP;
- }
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return err;
-}
-
-
-/*****************************************************************************
- *
- * SkGeIoctl - IO-control function
- *
- * Description:
- * This function is called if an ioctl is issued on the device.
- * There are three subfunction for reading, writing and test-writing
- * the private MIB data structure (useful for SysKonnect-internal tools).
- *
- * Returns:
- * 0, if everything is ok
- * !=0, on error
- */
-static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
-{
-DEV_NET *pNet;
-SK_AC *pAC;
-void *pMemBuf;
-struct pci_dev *pdev = NULL;
-SK_GE_IOCTL Ioctl;
-unsigned int Err = 0;
-int Size = 0;
-int Ret = 0;
-unsigned int Length = 0;
-int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeIoctl starts now...\n"));
-
- pNet = netdev_priv(dev);
- pAC = pNet->pAC;
-
- if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG)
- return SkGeMiiIoctl(dev, if_mii(rq), cmd);
-
- if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
- return -EFAULT;
- }
-
- switch(cmd) {
- case SK_IOCTL_SETMIB:
- case SK_IOCTL_PRESETMIB:
- if (!capable(CAP_NET_ADMIN)) return -EPERM;
- case SK_IOCTL_GETMIB:
- if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
- Ioctl.Len<sizeof(pAC->PnmiStruct)?
- Ioctl.Len : sizeof(pAC->PnmiStruct))) {
- return -EFAULT;
- }
- Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
- if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
- Ioctl.Len<Size? Ioctl.Len : Size)) {
- return -EFAULT;
- }
- Ioctl.Len = Size;
- if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
- return -EFAULT;
- }
- break;
- case SK_IOCTL_GEN:
- if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
- Length = Ioctl.Len;
- } else {
- Length = sizeof(pAC->PnmiStruct) + HeaderLength;
- }
- if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
- return -ENOMEM;
- }
- if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
- Err = -EFAULT;
- goto fault_gen;
- }
- if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
- Err = -EFAULT;
- goto fault_gen;
- }
- if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
- Err = -EFAULT;
- goto fault_gen;
- }
- Ioctl.Len = Length;
- if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
- Err = -EFAULT;
- goto fault_gen;
- }
-fault_gen:
- kfree(pMemBuf); /* cleanup everything */
- break;
-#ifdef SK_DIAG_SUPPORT
- case SK_IOCTL_DIAG:
- if (!capable(CAP_NET_ADMIN)) return -EPERM;
- if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
- Length = Ioctl.Len;
- } else {
- Length = sizeof(pAC->PnmiStruct) + HeaderLength;
- }
- if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
- return -ENOMEM;
- }
- if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
- Err = -EFAULT;
- goto fault_diag;
- }
- pdev = pAC->PciDev;
- Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */
- /*
- ** While coding this new IOCTL interface, only a few lines of code
- ** are to to be added. Therefore no dedicated function has been
- ** added. If more functionality is added, a separate function
- ** should be used...
- */
- * ((SK_U32 *)pMemBuf) = 0;
- * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
- * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
- if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
- Err = -EFAULT;
- goto fault_diag;
- }
- Ioctl.Len = Length;
- if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
- Err = -EFAULT;
- goto fault_diag;
- }
-fault_diag:
- kfree(pMemBuf); /* cleanup everything */
- break;
-#endif
- default:
- Err = -EOPNOTSUPP;
- }
-
- return(Err);
-
-} /* SkGeIoctl */
-
-
-/*****************************************************************************
- *
- * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
- *
- * Description:
- * This function reads/writes the MIB data using PNMI (Private Network
- * Management Interface).
- * The destination for the data must be provided with the
- * ioctl call and is given to the driver in the form of
- * a user space address.
- * Copying from the user-provided data area into kernel messages
- * and back is done by copy_from_user and copy_to_user calls in
- * SkGeIoctl.
- *
- * Returns:
- * returned size from PNMI call
- */
-static int SkGeIocMib(
-DEV_NET *pNet, /* pointer to the adapter context */
-unsigned int Size, /* length of ioctl data */
-int mode) /* flag for set/preset */
-{
-unsigned long Flags; /* for spin lock */
-SK_AC *pAC;
-
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("SkGeIocMib starts now...\n"));
- pAC = pNet->pAC;
- /* access MIB */
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- switch(mode) {
- case SK_IOCTL_GETMIB:
- SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
- pNet->NetNr);
- break;
- case SK_IOCTL_PRESETMIB:
- SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
- pNet->NetNr);
- break;
- case SK_IOCTL_SETMIB:
- SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
- pNet->NetNr);
- break;
- default:
- break;
- }
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
- ("MIB data access succeeded\n"));
- return (Size);
-} /* SkGeIocMib */
-
-
-/*****************************************************************************
- *
- * GetConfiguration - read configuration information
- *
- * Description:
- * This function reads per-adapter configuration information from
- * the options provided on the command line.
- *
- * Returns:
- * none
- */
-static void GetConfiguration(
-SK_AC *pAC) /* pointer to the adapter context structure */
-{
-SK_I32 Port; /* preferred port */
-SK_BOOL AutoSet;
-SK_BOOL DupSet;
-int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */
-int AutoNeg = 1; /* autoneg off (0) or on (1) */
-int DuplexCap = 0; /* 0=both,1=full,2=half */
-int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */
-int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */
-
-SK_BOOL IsConTypeDefined = SK_TRUE;
-SK_BOOL IsLinkSpeedDefined = SK_TRUE;
-SK_BOOL IsFlowCtrlDefined = SK_TRUE;
-SK_BOOL IsRoleDefined = SK_TRUE;
-SK_BOOL IsModeDefined = SK_TRUE;
-/*
- * The two parameters AutoNeg. and DuplexCap. map to one configuration
- * parameter. The mapping is described by this table:
- * DuplexCap -> | both | full | half |
- * AutoNeg | | | |
- * -----------------------------------------------------------------
- * Off | illegal | Full | Half |
- * -----------------------------------------------------------------
- * On | AutoBoth | AutoFull | AutoHalf |
- * -----------------------------------------------------------------
- * Sense | AutoSense | AutoSense | AutoSense |
- */
-int Capabilities[3][3] =
- { { -1, SK_LMODE_FULL , SK_LMODE_HALF },
- {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
- {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
-
-#define DC_BOTH 0
-#define DC_FULL 1
-#define DC_HALF 2
-#define AN_OFF 0
-#define AN_ON 1
-#define AN_SENS 2
-#define M_CurrPort pAC->GIni.GP[Port]
-
-
- /*
- ** Set the default values first for both ports!
- */
- for (Port = 0; Port < SK_MAX_MACS; Port++) {
- M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
- M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
- M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
- M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
- }
-
- /*
- ** Check merged parameter ConType. If it has not been used,
- ** verify any other parameter (e.g. AutoNeg) and use default values.
- **
- ** Stating both ConType and other lowlevel link parameters is also
- ** possible. If this is the case, the passed ConType-parameter is
- ** overwritten by the lowlevel link parameter.
- **
- ** The following settings are used for a merged ConType-parameter:
- **
- ** ConType DupCap AutoNeg FlowCtrl Role Speed
- ** ------- ------ ------- -------- ---------- -----
- ** Auto Both On SymOrRem Auto Auto
- ** 100FD Full Off None <ignored> 100
- ** 100HD Half Off None <ignored> 100
- ** 10FD Full Off None <ignored> 10
- ** 10HD Half Off None <ignored> 10
- **
- ** This ConType parameter is used for all ports of the adapter!
- */
- if ( (ConType != NULL) &&
- (pAC->Index < SK_MAX_CARD_PARAM) &&
- (ConType[pAC->Index] != NULL) ) {
-
- /* Check chipset family */
- if ((!pAC->ChipsetType) &&
- (strcmp(ConType[pAC->Index],"Auto")!=0) &&
- (strcmp(ConType[pAC->Index],"")!=0)) {
- /* Set the speed parameter back */
- printk("sk98lin: Illegal value \"%s\" "
- "for ConType."
- " Using Auto.\n",
- ConType[pAC->Index]);
-
- sprintf(ConType[pAC->Index], "Auto");
- }
-
- if (strcmp(ConType[pAC->Index],"")==0) {
- IsConTypeDefined = SK_FALSE; /* No ConType defined */
- } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
- for (Port = 0; Port < SK_MAX_MACS; Port++) {
- M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
- M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
- M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
- M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
- }
- } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
- for (Port = 0; Port < SK_MAX_MACS; Port++) {
- M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
- M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
- M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
- M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
- }
- } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
- for (Port = 0; Port < SK_MAX_MACS; Port++) {
- M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
- M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
- M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
- M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
- }
- } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
- for (Port = 0; Port < SK_MAX_MACS; Port++) {
- M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
- M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
- M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
- M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
- }
- } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
- for (Port = 0; Port < SK_MAX_MACS; Port++) {
- M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
- M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
- M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
- M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
- }
- } else {
- printk("sk98lin: Illegal value \"%s\" for ConType\n",
- ConType[pAC->Index]);
- IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
- }
- } else {
- IsConTypeDefined = SK_FALSE; /* No ConType defined */
- }
-
- /*
- ** Parse any parameter settings for port A:
- ** a) any LinkSpeed stated?
- */
- if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- Speed_A[pAC->Index] != NULL) {
- if (strcmp(Speed_A[pAC->Index],"")==0) {
- IsLinkSpeedDefined = SK_FALSE;
- } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
- LinkSpeed = SK_LSPEED_AUTO;
- } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
- LinkSpeed = SK_LSPEED_10MBPS;
- } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
- LinkSpeed = SK_LSPEED_100MBPS;
- } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
- LinkSpeed = SK_LSPEED_1000MBPS;
- } else {
- printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
- Speed_A[pAC->Index]);
- IsLinkSpeedDefined = SK_FALSE;
- }
- } else {
- IsLinkSpeedDefined = SK_FALSE;
- }
-
- /*
- ** Check speed parameter:
- ** Only copper type adapter and GE V2 cards
- */
- if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
- ((LinkSpeed != SK_LSPEED_AUTO) &&
- (LinkSpeed != SK_LSPEED_1000MBPS))) {
- printk("sk98lin: Illegal value for Speed_A. "
- "Not a copper card or GE V2 card\n Using "
- "speed 1000\n");
- LinkSpeed = SK_LSPEED_1000MBPS;
- }
-
- /*
- ** Decide whether to set new config value if somethig valid has
- ** been received.
- */
- if (IsLinkSpeedDefined) {
- pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
- }
-
- /*
- ** b) Any Autonegotiation and DuplexCapabilities set?
- ** Please note that both belong together...
- */
- AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
- AutoSet = SK_FALSE;
- if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- AutoNeg_A[pAC->Index] != NULL) {
- AutoSet = SK_TRUE;
- if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
- AutoSet = SK_FALSE;
- } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
- AutoNeg = AN_ON;
- } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
- AutoNeg = AN_OFF;
- } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
- AutoNeg = AN_SENS;
- } else {
- printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
- AutoNeg_A[pAC->Index]);
- }
- }
-
- DuplexCap = DC_BOTH;
- DupSet = SK_FALSE;
- if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- DupCap_A[pAC->Index] != NULL) {
- DupSet = SK_TRUE;
- if (strcmp(DupCap_A[pAC->Index],"")==0) {
- DupSet = SK_FALSE;
- } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
- DuplexCap = DC_BOTH;
- } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
- DuplexCap = DC_FULL;
- } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
- DuplexCap = DC_HALF;
- } else {
- printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
- DupCap_A[pAC->Index]);
- }
- }
-
- /*
- ** Check for illegal combinations
- */
- if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
- ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
- (DuplexCap == SK_LMODE_STAT_HALF)) &&
- (pAC->ChipsetType)) {
- printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
- " Using Full Duplex.\n");
- DuplexCap = DC_FULL;
- }
-
- if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
- printk("sk98lin, Port A: DuplexCapabilities"
- " ignored using Sense mode\n");
- }
-
- if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
- printk("sk98lin: Port A: Illegal combination"
- " of values AutoNeg. and DuplexCap.\n Using "
- "Full Duplex\n");
- DuplexCap = DC_FULL;
- }
-
- if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
- DuplexCap = DC_FULL;
- }
-
- if (!AutoSet && DupSet) {
- printk("sk98lin: Port A: Duplex setting not"
- " possible in\n default AutoNegotiation mode"
- " (Sense).\n Using AutoNegotiation On\n");
- AutoNeg = AN_ON;
- }
-
- /*
- ** set the desired mode
- */
- if (AutoSet || DupSet) {
- pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
- }
-
- /*
- ** c) Any Flowcontrol-parameter set?
- */
- if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- FlowCtrl_A[pAC->Index] != NULL) {
- if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
- IsFlowCtrlDefined = SK_FALSE;
- } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
- FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
- } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
- FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
- } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
- FlowCtrl = SK_FLOW_MODE_LOC_SEND;
- } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
- FlowCtrl = SK_FLOW_MODE_NONE;
- } else {
- printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
- FlowCtrl_A[pAC->Index]);
- IsFlowCtrlDefined = SK_FALSE;
- }
- } else {
- IsFlowCtrlDefined = SK_FALSE;
- }
-
- if (IsFlowCtrlDefined) {
- if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
- printk("sk98lin: Port A: FlowControl"
- " impossible without AutoNegotiation,"
- " disabled\n");
- FlowCtrl = SK_FLOW_MODE_NONE;
- }
- pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
- }
-
- /*
- ** d) What is with the RoleParameter?
- */
- if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- Role_A[pAC->Index] != NULL) {
- if (strcmp(Role_A[pAC->Index],"")==0) {
- IsRoleDefined = SK_FALSE;
- } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
- MSMode = SK_MS_MODE_AUTO;
- } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
- MSMode = SK_MS_MODE_MASTER;
- } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
- MSMode = SK_MS_MODE_SLAVE;
- } else {
- printk("sk98lin: Illegal value \"%s\" for Role_A\n",
- Role_A[pAC->Index]);
- IsRoleDefined = SK_FALSE;
- }
- } else {
- IsRoleDefined = SK_FALSE;
- }
-
- if (IsRoleDefined == SK_TRUE) {
- pAC->GIni.GP[0].PMSMode = MSMode;
- }
-
-
-
- /*
- ** Parse any parameter settings for port B:
- ** a) any LinkSpeed stated?
- */
- IsConTypeDefined = SK_TRUE;
- IsLinkSpeedDefined = SK_TRUE;
- IsFlowCtrlDefined = SK_TRUE;
- IsModeDefined = SK_TRUE;
-
- if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- Speed_B[pAC->Index] != NULL) {
- if (strcmp(Speed_B[pAC->Index],"")==0) {
- IsLinkSpeedDefined = SK_FALSE;
- } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
- LinkSpeed = SK_LSPEED_AUTO;
- } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
- LinkSpeed = SK_LSPEED_10MBPS;
- } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
- LinkSpeed = SK_LSPEED_100MBPS;
- } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
- LinkSpeed = SK_LSPEED_1000MBPS;
- } else {
- printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
- Speed_B[pAC->Index]);
- IsLinkSpeedDefined = SK_FALSE;
- }
- } else {
- IsLinkSpeedDefined = SK_FALSE;
- }
-
- /*
- ** Check speed parameter:
- ** Only copper type adapter and GE V2 cards
- */
- if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
- ((LinkSpeed != SK_LSPEED_AUTO) &&
- (LinkSpeed != SK_LSPEED_1000MBPS))) {
- printk("sk98lin: Illegal value for Speed_B. "
- "Not a copper card or GE V2 card\n Using "
- "speed 1000\n");
- LinkSpeed = SK_LSPEED_1000MBPS;
- }
-
- /*
- ** Decide whether to set new config value if somethig valid has
- ** been received.
- */
- if (IsLinkSpeedDefined) {
- pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
- }
-
- /*
- ** b) Any Autonegotiation and DuplexCapabilities set?
- ** Please note that both belong together...
- */
- AutoNeg = AN_SENS; /* default: do auto Sense */
- AutoSet = SK_FALSE;
- if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- AutoNeg_B[pAC->Index] != NULL) {
- AutoSet = SK_TRUE;
- if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
- AutoSet = SK_FALSE;
- } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
- AutoNeg = AN_ON;
- } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
- AutoNeg = AN_OFF;
- } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
- AutoNeg = AN_SENS;
- } else {
- printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
- AutoNeg_B[pAC->Index]);
- }
- }
-
- DuplexCap = DC_BOTH;
- DupSet = SK_FALSE;
- if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- DupCap_B[pAC->Index] != NULL) {
- DupSet = SK_TRUE;
- if (strcmp(DupCap_B[pAC->Index],"")==0) {
- DupSet = SK_FALSE;
- } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
- DuplexCap = DC_BOTH;
- } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
- DuplexCap = DC_FULL;
- } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
- DuplexCap = DC_HALF;
- } else {
- printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
- DupCap_B[pAC->Index]);
- }
- }
-
-
- /*
- ** Check for illegal combinations
- */
- if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
- ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
- (DuplexCap == SK_LMODE_STAT_HALF)) &&
- (pAC->ChipsetType)) {
- printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
- " Using Full Duplex.\n");
- DuplexCap = DC_FULL;
- }
-
- if (AutoSet && AutoNeg==AN_SENS && DupSet) {
- printk("sk98lin, Port B: DuplexCapabilities"
- " ignored using Sense mode\n");
- }
-
- if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
- printk("sk98lin: Port B: Illegal combination"
- " of values AutoNeg. and DuplexCap.\n Using "
- "Full Duplex\n");
- DuplexCap = DC_FULL;
- }
-
- if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
- DuplexCap = DC_FULL;
- }
-
- if (!AutoSet && DupSet) {
- printk("sk98lin: Port B: Duplex setting not"
- " possible in\n default AutoNegotiation mode"
- " (Sense).\n Using AutoNegotiation On\n");
- AutoNeg = AN_ON;
- }
-
- /*
- ** set the desired mode
- */
- if (AutoSet || DupSet) {
- pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
- }
-
- /*
- ** c) Any FlowCtrl parameter set?
- */
- if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- FlowCtrl_B[pAC->Index] != NULL) {
- if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
- IsFlowCtrlDefined = SK_FALSE;
- } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
- FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
- } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
- FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
- } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
- FlowCtrl = SK_FLOW_MODE_LOC_SEND;
- } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
- FlowCtrl = SK_FLOW_MODE_NONE;
- } else {
- printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
- FlowCtrl_B[pAC->Index]);
- IsFlowCtrlDefined = SK_FALSE;
- }
- } else {
- IsFlowCtrlDefined = SK_FALSE;
- }
-
- if (IsFlowCtrlDefined) {
- if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
- printk("sk98lin: Port B: FlowControl"
- " impossible without AutoNegotiation,"
- " disabled\n");
- FlowCtrl = SK_FLOW_MODE_NONE;
- }
- pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
- }
-
- /*
- ** d) What is the RoleParameter?
- */
- if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- Role_B[pAC->Index] != NULL) {
- if (strcmp(Role_B[pAC->Index],"")==0) {
- IsRoleDefined = SK_FALSE;
- } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
- MSMode = SK_MS_MODE_AUTO;
- } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
- MSMode = SK_MS_MODE_MASTER;
- } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
- MSMode = SK_MS_MODE_SLAVE;
- } else {
- printk("sk98lin: Illegal value \"%s\" for Role_B\n",
- Role_B[pAC->Index]);
- IsRoleDefined = SK_FALSE;
- }
- } else {
- IsRoleDefined = SK_FALSE;
- }
-
- if (IsRoleDefined) {
- pAC->GIni.GP[1].PMSMode = MSMode;
- }
-
- /*
- ** Evaluate settings for both ports
- */
- pAC->ActivePort = 0;
- if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- PrefPort[pAC->Index] != NULL) {
- if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
- pAC->ActivePort = 0;
- pAC->Rlmt.Net[0].Preference = -1; /* auto */
- pAC->Rlmt.Net[0].PrefPort = 0;
- } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
- /*
- ** do not set ActivePort here, thus a port
- ** switch is issued after net up.
- */
- Port = 0;
- pAC->Rlmt.Net[0].Preference = Port;
- pAC->Rlmt.Net[0].PrefPort = Port;
- } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
- /*
- ** do not set ActivePort here, thus a port
- ** switch is issued after net up.
- */
- if (pAC->GIni.GIMacsFound == 1) {
- printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
- " Port B not available on single port adapters.\n");
-
- pAC->ActivePort = 0;
- pAC->Rlmt.Net[0].Preference = -1; /* auto */
- pAC->Rlmt.Net[0].PrefPort = 0;
- } else {
- Port = 1;
- pAC->Rlmt.Net[0].Preference = Port;
- pAC->Rlmt.Net[0].PrefPort = Port;
- }
- } else {
- printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
- PrefPort[pAC->Index]);
- }
- }
-
- pAC->RlmtNets = 1;
-
- if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
- RlmtMode[pAC->Index] != NULL) {
- if (strcmp(RlmtMode[pAC->Index], "") == 0) {
- pAC->RlmtMode = 0;
- } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
- pAC->RlmtMode = SK_RLMT_CHECK_LINK;
- } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
- pAC->RlmtMode = SK_RLMT_CHECK_LINK |
- SK_RLMT_CHECK_LOC_LINK;
- } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
- pAC->RlmtMode = SK_RLMT_CHECK_LINK |
- SK_RLMT_CHECK_LOC_LINK |
- SK_RLMT_CHECK_SEG;
- } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
- (pAC->GIni.GIMacsFound == 2)) {
- pAC->RlmtMode = SK_RLMT_CHECK_LINK;
- pAC->RlmtNets = 2;
- } else {
- printk("sk98lin: Illegal value \"%s\" for"
- " RlmtMode, using default\n",
- RlmtMode[pAC->Index]);
- pAC->RlmtMode = 0;
- }
- } else {
- pAC->RlmtMode = 0;
- }
-
- /*
- ** Check the interrupt moderation parameters
- */
- if (Moderation[pAC->Index] != NULL) {
- if (strcmp(Moderation[pAC->Index], "") == 0) {
- pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
- } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
- pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
- } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
- pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
- } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
- pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
- } else {
- printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
- " Disable interrupt moderation.\n",
- Moderation[pAC->Index]);
- pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
- }
- } else {
- pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
- }
-
- if (Stats[pAC->Index] != NULL) {
- if (strcmp(Stats[pAC->Index], "Yes") == 0) {
- pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
- } else {
- pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
- }
- } else {
- pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
- }
-
- if (ModerationMask[pAC->Index] != NULL) {
- if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
- } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
- } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
- } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
- } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
- } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
- } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
- } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
- } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
- } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
- } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
- } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
- } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
- } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
- } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
- } else { /* some rubbish */
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
- }
- } else { /* operator has stated nothing */
- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
- }
-
- if (AutoSizing[pAC->Index] != NULL) {
- if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
- pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
- } else {
- pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
- }
- } else { /* operator has stated nothing */
- pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
- }
-
- if (IntsPerSec[pAC->Index] != 0) {
- if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) ||
- (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
- printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
- " Using default value of %i.\n",
- IntsPerSec[pAC->Index],
- C_INT_MOD_IPS_LOWER_RANGE,
- C_INT_MOD_IPS_UPPER_RANGE,
- C_INTS_PER_SEC_DEFAULT);
- pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
- } else {
- pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
- }
- } else {
- pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
- }
-
- /*
- ** Evaluate upper and lower moderation threshold
- */
- pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
- pAC->DynIrqModInfo.MaxModIntsPerSec +
- (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
-
- pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
- pAC->DynIrqModInfo.MaxModIntsPerSec -
- (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
-
- pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */
-
-
-} /* GetConfiguration */
-
-
-/*****************************************************************************
- *
- * ProductStr - return a adapter identification string from vpd
- *
- * Description:
- * This function reads the product name string from the vpd area
- * and puts it the field pAC->DeviceString.
- *
- * Returns: N/A
- */
-static inline int ProductStr(
- SK_AC *pAC, /* pointer to adapter context */
- char *DeviceStr, /* result string */
- int StrLen /* length of the string */
-)
-{
-char Keyword[] = VPD_NAME; /* vpd productname identifier */
-int ReturnCode; /* return code from vpd_read */
-unsigned long Flags;
-
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- return ReturnCode;
-} /* ProductStr */
-
-/*****************************************************************************
- *
- * StartDrvCleanupTimer - Start timer to check for descriptors which
- * might be placed in descriptor ring, but
- * havent been handled up to now
- *
- * Description:
- * This function requests a HW-timer fo the Yukon card. The actions to
- * perform when this timer expires, are located in the SkDrvEvent().
- *
- * Returns: N/A
- */
-static void
-StartDrvCleanupTimer(SK_AC *pAC) {
- SK_EVPARA EventParam; /* Event struct for timer event */
-
- SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
- EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
- SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
- SK_DRV_RX_CLEANUP_TIMER_LENGTH,
- SKGE_DRV, SK_DRV_TIMER, EventParam);
-}
-
-/*****************************************************************************
- *
- * StopDrvCleanupTimer - Stop timer to check for descriptors
- *
- * Description:
- * This function requests a HW-timer fo the Yukon card. The actions to
- * perform when this timer expires, are located in the SkDrvEvent().
- *
- * Returns: N/A
- */
-static void
-StopDrvCleanupTimer(SK_AC *pAC) {
- SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
- SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
-}
-
-/****************************************************************************/
-/* functions for common modules *********************************************/
-/****************************************************************************/
-
-
-/*****************************************************************************
- *
- * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
- *
- * Description:
- * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
- * is embedded into a socket buff data area.
- *
- * Context:
- * runtime
- *
- * Returns:
- * NULL or pointer to Mbuf.
- */
-SK_MBUF *SkDrvAllocRlmtMbuf(
-SK_AC *pAC, /* pointer to adapter context */
-SK_IOC IoC, /* the IO-context */
-unsigned BufferSize) /* size of the requested buffer */
-{
-SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */
-struct sk_buff *pMsgBlock; /* pointer to a new message block */
-
- pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
- if (pMsgBlock == NULL) {
- return (NULL);
- }
- pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
- skb_reserve(pMsgBlock, sizeof(SK_MBUF));
- pRlmtMbuf->pNext = NULL;
- pRlmtMbuf->pOs = pMsgBlock;
- pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */
- pRlmtMbuf->Size = BufferSize; /* Data buffer size. */
- pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */
- return (pRlmtMbuf);
-
-} /* SkDrvAllocRlmtMbuf */
-
-
-/*****************************************************************************
- *
- * SkDrvFreeRlmtMbuf - free an RLMT mbuf
- *
- * Description:
- * This routine frees one or more RLMT mbuf(s).
- *
- * Context:
- * runtime
- *
- * Returns:
- * Nothing
- */
-void SkDrvFreeRlmtMbuf(
-SK_AC *pAC, /* pointer to adapter context */
-SK_IOC IoC, /* the IO-context */
-SK_MBUF *pMbuf) /* size of the requested buffer */
-{
-SK_MBUF *pFreeMbuf;
-SK_MBUF *pNextMbuf;
-
- pFreeMbuf = pMbuf;
- do {
- pNextMbuf = pFreeMbuf->pNext;
- DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
- pFreeMbuf = pNextMbuf;
- } while ( pFreeMbuf != NULL );
-} /* SkDrvFreeRlmtMbuf */
-
-
-/*****************************************************************************
- *
- * SkOsGetTime - provide a time value
- *
- * Description:
- * This routine provides a time value. The unit is 1/HZ (defined by Linux).
- * It is not used for absolute time, but only for time differences.
- *
- *
- * Returns:
- * Time value
- */
-SK_U64 SkOsGetTime(SK_AC *pAC)
-{
- SK_U64 PrivateJiffies;
- SkOsGetTimeCurrent(pAC, &PrivateJiffies);
- return PrivateJiffies;
-} /* SkOsGetTime */
-
-
-/*****************************************************************************
- *
- * SkPciReadCfgDWord - read a 32 bit value from pci config space
- *
- * Description:
- * This routine reads a 32 bit value from the pci configuration
- * space.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-int SkPciReadCfgDWord(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U32 *pVal) /* pointer to store the read value */
-{
- pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
- return(0);
-} /* SkPciReadCfgDWord */
-
-
-/*****************************************************************************
- *
- * SkPciReadCfgWord - read a 16 bit value from pci config space
- *
- * Description:
- * This routine reads a 16 bit value from the pci configuration
- * space.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-int SkPciReadCfgWord(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U16 *pVal) /* pointer to store the read value */
-{
- pci_read_config_word(pAC->PciDev, PciAddr, pVal);
- return(0);
-} /* SkPciReadCfgWord */
-
-
-/*****************************************************************************
- *
- * SkPciReadCfgByte - read a 8 bit value from pci config space
- *
- * Description:
- * This routine reads a 8 bit value from the pci configuration
- * space.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-int SkPciReadCfgByte(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U8 *pVal) /* pointer to store the read value */
-{
- pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
- return(0);
-} /* SkPciReadCfgByte */
-
-
-/*****************************************************************************
- *
- * SkPciWriteCfgWord - write a 16 bit value to pci config space
- *
- * Description:
- * This routine writes a 16 bit value to the pci configuration
- * space. The flag PciConfigUp indicates whether the config space
- * is accesible or must be set up first.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-int SkPciWriteCfgWord(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U16 Val) /* pointer to store the read value */
-{
- pci_write_config_word(pAC->PciDev, PciAddr, Val);
- return(0);
-} /* SkPciWriteCfgWord */
-
-
-/*****************************************************************************
- *
- * SkPciWriteCfgWord - write a 8 bit value to pci config space
- *
- * Description:
- * This routine writes a 8 bit value to the pci configuration
- * space. The flag PciConfigUp indicates whether the config space
- * is accesible or must be set up first.
- *
- * Returns:
- * 0 - indicate everything worked ok.
- * != 0 - error indication
- */
-int SkPciWriteCfgByte(
-SK_AC *pAC, /* Adapter Control structure pointer */
-int PciAddr, /* PCI register address */
-SK_U8 Val) /* pointer to store the read value */
-{
- pci_write_config_byte(pAC->PciDev, PciAddr, Val);
- return(0);
-} /* SkPciWriteCfgByte */
-
-
-/*****************************************************************************
- *
- * SkDrvEvent - handle driver events
- *
- * Description:
- * This function handles events from all modules directed to the driver
- *
- * Context:
- * Is called under protection of slow path lock.
- *
- * Returns:
- * 0 if everything ok
- * < 0 on error
- *
- */
-int SkDrvEvent(
-SK_AC *pAC, /* pointer to adapter context */
-SK_IOC IoC, /* io-context */
-SK_U32 Event, /* event-id */
-SK_EVPARA Param) /* event-parameter */
-{
-SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */
-struct sk_buff *pMsg; /* pointer to a message block */
-int FromPort; /* the port from which we switch away */
-int ToPort; /* the port we switch to */
-SK_EVPARA NewPara; /* parameter for further events */
-int Stat;
-unsigned long Flags;
-SK_BOOL DualNet;
-
- switch (Event) {
- case SK_DRV_ADAP_FAIL:
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("ADAPTER FAIL EVENT\n"));
- printk("%s: Adapter failed.\n", pAC->dev[0]->name);
- /* disable interrupts */
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- /* cgoos */
- break;
- case SK_DRV_PORT_FAIL:
- FromPort = Param.Para32[0];
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("PORT FAIL EVENT, Port: %d\n", FromPort));
- if (FromPort == 0) {
- printk("%s: Port A failed.\n", pAC->dev[0]->name);
- } else {
- printk("%s: Port B failed.\n", pAC->dev[1]->name);
- }
- /* cgoos */
- break;
- case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */
- /* action list 4 */
- FromPort = Param.Para32[0];
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("PORT RESET EVENT, Port: %d ", FromPort));
- NewPara.Para64 = FromPort;
- SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
- spin_lock_irqsave(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
-
- SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
- netif_carrier_off(pAC->dev[Param.Para32[0]]);
- spin_unlock_irqrestore(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
-
- /* clear rx ring from received frames */
- ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
-
- ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
- spin_lock_irqsave(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
-
- /* tschilling: Handling of return value inserted. */
- if (SkGeInitPort(pAC, IoC, FromPort)) {
- if (FromPort == 0) {
- printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
- } else {
- printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
- }
- }
- SkAddrMcUpdate(pAC,IoC, FromPort);
- PortReInitBmu(pAC, FromPort);
- SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
- ClearAndStartRx(pAC, FromPort);
- spin_unlock_irqrestore(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
- break;
- case SK_DRV_NET_UP: /* SK_U32 PortIdx */
- { struct net_device *dev = pAC->dev[Param.Para32[0]];
- /* action list 5 */
- FromPort = Param.Para32[0];
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("NET UP EVENT, Port: %d ", Param.Para32[0]));
- /* Mac update */
- SkAddrMcUpdate(pAC,IoC, FromPort);
-
- if (DoPrintInterfaceChange) {
- printk("%s: network connection up using"
- " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
-
- /* tschilling: Values changed according to LinkSpeedUsed. */
- Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
- if (Stat == SK_LSPEED_STAT_10MBPS) {
- printk(" speed: 10\n");
- } else if (Stat == SK_LSPEED_STAT_100MBPS) {
- printk(" speed: 100\n");
- } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
- printk(" speed: 1000\n");
- } else {
- printk(" speed: unknown\n");
- }
-
-
- Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
- if (Stat == SK_LMODE_STAT_AUTOHALF ||
- Stat == SK_LMODE_STAT_AUTOFULL) {
- printk(" autonegotiation: yes\n");
- }
- else {
- printk(" autonegotiation: no\n");
- }
- if (Stat == SK_LMODE_STAT_AUTOHALF ||
- Stat == SK_LMODE_STAT_HALF) {
- printk(" duplex mode: half\n");
- }
- else {
- printk(" duplex mode: full\n");
- }
- Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
- if (Stat == SK_FLOW_STAT_REM_SEND ) {
- printk(" flowctrl: remote send\n");
- }
- else if (Stat == SK_FLOW_STAT_LOC_SEND ){
- printk(" flowctrl: local send\n");
- }
- else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
- printk(" flowctrl: symmetric\n");
- }
- else {
- printk(" flowctrl: none\n");
- }
-
- /* tschilling: Check against CopperType now. */
- if ((pAC->GIni.GICopperType == SK_TRUE) &&
- (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
- SK_LSPEED_STAT_1000MBPS)) {
- Stat = pAC->GIni.GP[FromPort].PMSStatus;
- if (Stat == SK_MS_STAT_MASTER ) {
- printk(" role: master\n");
- }
- else if (Stat == SK_MS_STAT_SLAVE ) {
- printk(" role: slave\n");
- }
- else {
- printk(" role: ???\n");
- }
- }
-
- /*
- Display dim (dynamic interrupt moderation)
- informations
- */
- if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
- printk(" irq moderation: static (%d ints/sec)\n",
- pAC->DynIrqModInfo.MaxModIntsPerSec);
- else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
- printk(" irq moderation: dynamic (%d ints/sec)\n",
- pAC->DynIrqModInfo.MaxModIntsPerSec);
- else
- printk(" irq moderation: disabled\n");
-
-
- printk(" scatter-gather: %s\n",
- (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
- printk(" tx-checksum: %s\n",
- (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
- printk(" rx-checksum: %s\n",
- pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
-
- } else {
- DoPrintInterfaceChange = SK_TRUE;
- }
-
- if ((Param.Para32[0] != pAC->ActivePort) &&
- (pAC->RlmtNets == 1)) {
- NewPara.Para32[0] = pAC->ActivePort;
- NewPara.Para32[1] = Param.Para32[0];
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
- NewPara);
- }
-
- /* Inform the world that link protocol is up. */
- netif_carrier_on(dev);
- break;
- }
- case SK_DRV_NET_DOWN: /* SK_U32 Reason */
- /* action list 7 */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("NET DOWN EVENT "));
- if (DoPrintInterfaceChange) {
- printk("%s: network connection down\n",
- pAC->dev[Param.Para32[1]]->name);
- } else {
- DoPrintInterfaceChange = SK_TRUE;
- }
- netif_carrier_off(pAC->dev[Param.Para32[1]]);
- break;
- case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("PORT SWITCH HARD "));
- case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
- /* action list 6 */
- printk("%s: switching to port %c\n", pAC->dev[0]->name,
- 'A'+Param.Para32[1]);
- case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
- FromPort = Param.Para32[0];
- ToPort = Param.Para32[1];
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ",
- FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
- NewPara.Para64 = FromPort;
- SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
- NewPara.Para64 = ToPort;
- SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
- spin_lock_irqsave(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
- spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
- SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
- SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
- spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
- spin_unlock_irqrestore(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
-
- ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
- ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
-
- ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
- ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
- spin_lock_irqsave(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
- spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
- pAC->ActivePort = ToPort;
-#if 0
- SetQueueSizes(pAC);
-#else
- /* tschilling: New common function with minimum size check. */
- DualNet = SK_FALSE;
- if (pAC->RlmtNets == 2) {
- DualNet = SK_TRUE;
- }
-
- if (SkGeInitAssignRamToQueues(
- pAC,
- pAC->ActivePort,
- DualNet)) {
- spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
- spin_unlock_irqrestore(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
- printk("SkGeInitAssignRamToQueues failed.\n");
- break;
- }
-#endif
- /* tschilling: Handling of return values inserted. */
- if (SkGeInitPort(pAC, IoC, FromPort) ||
- SkGeInitPort(pAC, IoC, ToPort)) {
- printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
- }
- if (Event == SK_DRV_SWITCH_SOFT) {
- SkMacRxTxEnable(pAC, IoC, FromPort);
- }
- SkMacRxTxEnable(pAC, IoC, ToPort);
- SkAddrSwap(pAC, IoC, FromPort, ToPort);
- SkAddrMcUpdate(pAC, IoC, FromPort);
- SkAddrMcUpdate(pAC, IoC, ToPort);
- PortReInitBmu(pAC, FromPort);
- PortReInitBmu(pAC, ToPort);
- SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
- SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
- ClearAndStartRx(pAC, FromPort);
- ClearAndStartRx(pAC, ToPort);
- spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
- spin_unlock_irqrestore(
- &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
- Flags);
- break;
- case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("RLS "));
- pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
- pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
- skb_put(pMsg, pRlmtMbuf->Length);
- if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
- pMsg) < 0)
-
- DEV_KFREE_SKB_ANY(pMsg);
- break;
- case SK_DRV_TIMER:
- if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
- /*
- ** expiration of the moderation timer implies that
- ** dynamic moderation is to be applied
- */
- SkDimStartModerationTimer(pAC);
- SkDimModerate(pAC);
- if (pAC->DynIrqModInfo.DisplayStats) {
- SkDimDisplayModerationSettings(pAC);
- }
- } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
- /*
- ** check if we need to check for descriptors which
- ** haven't been handled the last millisecs
- */
- StartDrvCleanupTimer(pAC);
- if (pAC->GIni.GIMacsFound == 2) {
- ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
- }
- ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
- } else {
- printk("Expiration of unknown timer\n");
- }
- break;
- default:
- break;
- }
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
- ("END EVENT "));
-
- return (0);
-} /* SkDrvEvent */
-
-
-/*****************************************************************************
- *
- * SkErrorLog - log errors
- *
- * Description:
- * This function logs errors to the system buffer and to the console
- *
- * Returns:
- * 0 if everything ok
- * < 0 on error
- *
- */
-void SkErrorLog(
-SK_AC *pAC,
-int ErrClass,
-int ErrNum,
-char *pErrorMsg)
-{
-char ClassStr[80];
-
- switch (ErrClass) {
- case SK_ERRCL_OTHER:
- strcpy(ClassStr, "Other error");
- break;
- case SK_ERRCL_CONFIG:
- strcpy(ClassStr, "Configuration error");
- break;
- case SK_ERRCL_INIT:
- strcpy(ClassStr, "Initialization error");
- break;
- case SK_ERRCL_NORES:
- strcpy(ClassStr, "Out of resources error");
- break;
- case SK_ERRCL_SW:
- strcpy(ClassStr, "internal Software error");
- break;
- case SK_ERRCL_HW:
- strcpy(ClassStr, "Hardware failure");
- break;
- case SK_ERRCL_COMM:
- strcpy(ClassStr, "Communication error");
- break;
- }
- printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n"
- " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name,
- ClassStr, ErrNum, pErrorMsg);
-
-} /* SkErrorLog */
-
-#ifdef SK_DIAG_SUPPORT
-
-/*****************************************************************************
- *
- * SkDrvEnterDiagMode - handles DIAG attach request
- *
- * Description:
- * Notify the kernel to NOT access the card any longer due to DIAG
- * Deinitialize the Card
- *
- * Returns:
- * int
- */
-int SkDrvEnterDiagMode(
-SK_AC *pAc) /* pointer to adapter context */
-{
- DEV_NET *pNet = netdev_priv(pAc->dev[0]);
- SK_AC *pAC = pNet->pAC;
-
- SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct),
- sizeof(SK_PNMI_STRUCT_DATA));
-
- pAC->DiagModeActive = DIAG_ACTIVE;
- if (pAC->BoardLevel > SK_INIT_DATA) {
- if (netif_running(pAC->dev[0])) {
- pAC->WasIfUp[0] = SK_TRUE;
- pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
- } else {
- pAC->WasIfUp[0] = SK_FALSE;
- }
- if (pNet != netdev_priv(pAC->dev[1])) {
- pNet = netdev_priv(pAC->dev[1]);
- if (netif_running(pAC->dev[1])) {
- pAC->WasIfUp[1] = SK_TRUE;
- pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */
- } else {
- pAC->WasIfUp[1] = SK_FALSE;
- }
- }
- pAC->BoardLevel = SK_INIT_DATA;
- }
- return(0);
-}
-
-/*****************************************************************************
- *
- * SkDrvLeaveDiagMode - handles DIAG detach request
- *
- * Description:
- * Notify the kernel to may access the card again after use by DIAG
- * Initialize the Card
- *
- * Returns:
- * int
- */
-int SkDrvLeaveDiagMode(
-SK_AC *pAc) /* pointer to adapter control context */
-{
- SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup),
- sizeof(SK_PNMI_STRUCT_DATA));
- pAc->DiagModeActive = DIAG_NOTACTIVE;
- pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
- if (pAc->WasIfUp[0] == SK_TRUE) {
- pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvInitAdapter(pAc, 0); /* first device */
- }
- if (pAc->WasIfUp[1] == SK_TRUE) {
- pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvInitAdapter(pAc, 1); /* second device */
- }
- return(0);
-}
-
-/*****************************************************************************
- *
- * ParseDeviceNbrFromSlotName - Evaluate PCI device number
- *
- * Description:
- * This function parses the PCI slot name information string and will
- * retrieve the devcie number out of it. The slot_name maintianed by
- * linux is in the form of '02:0a.0', whereas the first two characters
- * represent the bus number in hex (in the sample above this is
- * pci bus 0x02) and the next two characters the device number (0x0a).
- *
- * Returns:
- * SK_U32: The device number from the PCI slot name
- */
-
-static SK_U32 ParseDeviceNbrFromSlotName(
-const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */
-{
- char *CurrCharPos = (char *) SlotName;
- int FirstNibble = -1;
- int SecondNibble = -1;
- SK_U32 Result = 0;
-
- while (*CurrCharPos != '\0') {
- if (*CurrCharPos == ':') {
- while (*CurrCharPos != '.') {
- CurrCharPos++;
- if ( (*CurrCharPos >= '0') &&
- (*CurrCharPos <= '9')) {
- if (FirstNibble == -1) {
- /* dec. value for '0' */
- FirstNibble = *CurrCharPos - 48;
- } else {
- SecondNibble = *CurrCharPos - 48;
- }
- } else if ( (*CurrCharPos >= 'a') &&
- (*CurrCharPos <= 'f') ) {
- if (FirstNibble == -1) {
- FirstNibble = *CurrCharPos - 87;
- } else {
- SecondNibble = *CurrCharPos - 87;
- }
- } else {
- Result = 0;
- }
- }
-
- Result = FirstNibble;
- Result = Result << 4; /* first nibble is higher one */
- Result = Result | SecondNibble;
- }
- CurrCharPos++; /* next character */
- }
- return (Result);
-}
-
-/****************************************************************************
- *
- * SkDrvDeInitAdapter - deinitialize adapter (this function is only
- * called if Diag attaches to that card)
- *
- * Description:
- * Close initialized adapter.
- *
- * Returns:
- * 0 - on success
- * error code - on error
- */
-static int SkDrvDeInitAdapter(
-SK_AC *pAC, /* pointer to adapter context */
-int devNbr) /* what device is to be handled */
-{
- struct SK_NET_DEVICE *dev;
-
- dev = pAC->dev[devNbr];
-
- /* On Linux 2.6 the network driver does NOT mess with reference
- ** counts. The driver MUST be able to be unloaded at any time
- ** due to the possibility of hotplug.
- */
- if (SkGeClose(dev) != 0) {
- return (-1);
- }
- return (0);
-
-} /* SkDrvDeInitAdapter() */
-
-/****************************************************************************
- *
- * SkDrvInitAdapter - Initialize adapter (this function is only
- * called if Diag deattaches from that card)
- *
- * Description:
- * Close initialized adapter.
- *
- * Returns:
- * 0 - on success
- * error code - on error
- */
-static int SkDrvInitAdapter(
-SK_AC *pAC, /* pointer to adapter context */
-int devNbr) /* what device is to be handled */
-{
- struct SK_NET_DEVICE *dev;
-
- dev = pAC->dev[devNbr];
-
- if (SkGeOpen(dev) != 0) {
- return (-1);
- }
-
- /*
- ** Use correct MTU size and indicate to kernel TX queue can be started
- */
- if (SkGeChangeMtu(dev, dev->mtu) != 0) {
- return (-1);
- }
- return (0);
-
-} /* SkDrvInitAdapter */
-
-#endif
-
-#ifdef DEBUG
-/****************************************************************************/
-/* "debug only" section *****************************************************/
-/****************************************************************************/
-
-
-/*****************************************************************************
- *
- * DumpMsg - print a frame
- *
- * Description:
- * This function prints frames to the system logfile/to the console.
- *
- * Returns: N/A
- *
- */
-static void DumpMsg(struct sk_buff *skb, char *str)
-{
- int msglen;
-
- if (skb == NULL) {
- printk("DumpMsg(): NULL-Message\n");
- return;
- }
-
- if (skb->data == NULL) {
- printk("DumpMsg(): Message empty\n");
- return;
- }
-
- msglen = skb->len;
- if (msglen > 64)
- msglen = 64;
-
- printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
-
- DumpData((char *)skb->data, msglen);
-
- printk("------- End of message ---------\n");
-} /* DumpMsg */
-
-
-
-/*****************************************************************************
- *
- * DumpData - print a data area
- *
- * Description:
- * This function prints a area of data to the system logfile/to the
- * console.
- *
- * Returns: N/A
- *
- */
-static void DumpData(char *p, int size)
-{
-register int i;
-int haddr, addr;
-char hex_buffer[180];
-char asc_buffer[180];
-char HEXCHAR[] = "0123456789ABCDEF";
-
- addr = 0;
- haddr = 0;
- hex_buffer[0] = 0;
- asc_buffer[0] = 0;
- for (i=0; i < size; ) {
- if (*p >= '0' && *p <='z')
- asc_buffer[addr] = *p;
- else
- asc_buffer[addr] = '.';
- addr++;
- asc_buffer[addr] = 0;
- hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
- haddr++;
- hex_buffer[haddr] = ' ';
- haddr++;
- hex_buffer[haddr] = 0;
- p++;
- i++;
- if (i%16 == 0) {
- printk("%s %s\n", hex_buffer, asc_buffer);
- addr = 0;
- haddr = 0;
- }
- }
-} /* DumpData */
-
-
-/*****************************************************************************
- *
- * DumpLong - print a data area as long values
- *
- * Description:
- * This function prints a area of data to the system logfile/to the
- * console.
- *
- * Returns: N/A
- *
- */
-static void DumpLong(char *pc, int size)
-{
-register int i;
-int haddr, addr;
-char hex_buffer[180];
-char asc_buffer[180];
-char HEXCHAR[] = "0123456789ABCDEF";
-long *p;
-int l;
-
- addr = 0;
- haddr = 0;
- hex_buffer[0] = 0;
- asc_buffer[0] = 0;
- p = (long*) pc;
- for (i=0; i < size; ) {
- l = (long) *p;
- hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
- haddr++;
- hex_buffer[haddr] = HEXCHAR[l & 0x0f];
- haddr++;
- hex_buffer[haddr] = ' ';
- haddr++;
- hex_buffer[haddr] = 0;
- p++;
- i++;
- if (i%8 == 0) {
- printk("%4x %s\n", (i-8)*4, hex_buffer);
- haddr = 0;
- }
- }
- printk("------------------------\n");
-} /* DumpLong */
-
-#endif
-
-static int __devinit skge_probe_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- SK_AC *pAC;
- DEV_NET *pNet = NULL;
- struct net_device *dev = NULL;
- static int boards_found = 0;
- int error = -ENODEV;
- int using_dac = 0;
- char DeviceStr[80];
-
- if (pci_enable_device(pdev))
- goto out;
-
- /* Configure DMA attributes. */
- if (sizeof(dma_addr_t) > sizeof(u32) &&
- !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
- using_dac = 1;
- error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
- if (error < 0) {
- printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
- "for consistent allocations\n", pci_name(pdev));
- goto out_disable_device;
- }
- } else {
- error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (error) {
- printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
- pci_name(pdev));
- goto out_disable_device;
- }
- }
-
- error = -ENOMEM;
- dev = alloc_etherdev(sizeof(DEV_NET));
- if (!dev) {
- printk(KERN_ERR "sk98lin: unable to allocate etherdev "
- "structure!\n");
- goto out_disable_device;
- }
-
- pNet = netdev_priv(dev);
- pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
- if (!pNet->pAC) {
- printk(KERN_ERR "sk98lin: unable to allocate adapter "
- "structure!\n");
- goto out_free_netdev;
- }
-
- pAC = pNet->pAC;
- pAC->PciDev = pdev;
-
- pAC->dev[0] = dev;
- pAC->dev[1] = dev;
- pAC->CheckQueue = SK_FALSE;
-
- dev->irq = pdev->irq;
-
- error = SkGeInitPCI(pAC);
- if (error) {
- printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
- goto out_free_netdev;
- }
-
- SET_MODULE_OWNER(dev);
- dev->open = &SkGeOpen;
- dev->stop = &SkGeClose;
- dev->hard_start_xmit = &SkGeXmit;
- dev->get_stats = &SkGeStats;
- dev->set_multicast_list = &SkGeSetRxMode;
- dev->set_mac_address = &SkGeSetMacAddr;
- dev->do_ioctl = &SkGeIoctl;
- dev->change_mtu = &SkGeChangeMtu;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = &SkGePollController;
-#endif
- SET_NETDEV_DEV(dev, &pdev->dev);
- SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
-
- /* Use only if yukon hardware */
- if (pAC->ChipsetType) {
-#ifdef USE_SK_TX_CHECKSUM
- dev->features |= NETIF_F_IP_CSUM;
-#endif
-#ifdef SK_ZEROCOPY
- dev->features |= NETIF_F_SG;
-#endif
-#ifdef USE_SK_RX_CHECKSUM
- pAC->RxPort[0].RxCsum = 1;
-#endif
- }
-
- if (using_dac)
- dev->features |= NETIF_F_HIGHDMA;
-
- pAC->Index = boards_found++;
-
- error = SkGeBoardInit(dev, pAC);
- if (error)
- goto out_free_netdev;
-
- /* Read Adapter name from VPD */
- if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
- error = -EIO;
- printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
- goto out_free_resources;
- }
-
- /* Register net device */
- error = register_netdev(dev);
- if (error) {
- printk(KERN_ERR "sk98lin: Could not register device.\n");
- goto out_free_resources;
- }
-
- /* Print adapter specific string from vpd */
- printk("%s: %s\n", dev->name, DeviceStr);
-
- /* Print configuration settings */
- printk(" PrefPort:%c RlmtMode:%s\n",
- 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
- (pAC->RlmtMode==0) ? "Check Link State" :
- ((pAC->RlmtMode==1) ? "Check Link State" :
- ((pAC->RlmtMode==3) ? "Check Local Port" :
- ((pAC->RlmtMode==7) ? "Check Segmentation" :
- ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
-
- SkGeYellowLED(pAC, pAC->IoBase, 1);
-
- memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
- pNet->PortNr = 0;
- pNet->NetNr = 0;
-
- boards_found++;
-
- pci_set_drvdata(pdev, dev);
-
- /* More then one port found */
- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- dev = alloc_etherdev(sizeof(DEV_NET));
- if (!dev) {
- printk(KERN_ERR "sk98lin: unable to allocate etherdev "
- "structure!\n");
- goto single_port;
- }
-
- pNet = netdev_priv(dev);
- pNet->PortNr = 1;
- pNet->NetNr = 1;
- pNet->pAC = pAC;
-
- dev->open = &SkGeOpen;
- dev->stop = &SkGeClose;
- dev->hard_start_xmit = &SkGeXmit;
- dev->get_stats = &SkGeStats;
- dev->set_multicast_list = &SkGeSetRxMode;
- dev->set_mac_address = &SkGeSetMacAddr;
- dev->do_ioctl = &SkGeIoctl;
- dev->change_mtu = &SkGeChangeMtu;
- SET_NETDEV_DEV(dev, &pdev->dev);
- SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
-
- if (pAC->ChipsetType) {
-#ifdef USE_SK_TX_CHECKSUM
- dev->features |= NETIF_F_IP_CSUM;
-#endif
-#ifdef SK_ZEROCOPY
- dev->features |= NETIF_F_SG;
-#endif
-#ifdef USE_SK_RX_CHECKSUM
- pAC->RxPort[1].RxCsum = 1;
-#endif
- }
-
- if (using_dac)
- dev->features |= NETIF_F_HIGHDMA;
-
- error = register_netdev(dev);
- if (error) {
- printk(KERN_ERR "sk98lin: Could not register device"
- " for second port. (%d)\n", error);
- free_netdev(dev);
- goto single_port;
- }
-
- pAC->dev[1] = dev;
- memcpy(&dev->dev_addr,
- &pAC->Addr.Net[1].CurrentMacAddress, 6);
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
- printk("%s: %s\n", dev->name, DeviceStr);
- printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
- }
-
-single_port:
-
- /* Save the hardware revision */
- pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
- (pAC->GIni.GIPciHwRev & 0x0F);
-
- /* Set driver globals */
- pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME;
- pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
-
- memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
- memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
-
- return 0;
-
- out_free_resources:
- FreeResources(dev);
- out_free_netdev:
- free_netdev(dev);
- out_disable_device:
- pci_disable_device(pdev);
- out:
- return error;
-}
-
-static void __devexit skge_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- struct net_device *otherdev = pAC->dev[1];
-
- unregister_netdev(dev);
-
- SkGeYellowLED(pAC, pAC->IoBase, 0);
-
- if (pAC->BoardLevel == SK_INIT_RUN) {
- SK_EVPARA EvPara;
- unsigned long Flags;
-
- /* board is still alive */
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- EvPara.Para32[0] = 0;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- EvPara.Para32[0] = 1;
- EvPara.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- SkEventDispatcher(pAC, pAC->IoBase);
- /* disable interrupts */
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- SkGeDeInit(pAC, pAC->IoBase);
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- pAC->BoardLevel = SK_INIT_DATA;
- /* We do NOT check here, if IRQ was pending, of course*/
- }
-
- if (pAC->BoardLevel == SK_INIT_IO) {
- /* board is still alive */
- SkGeDeInit(pAC, pAC->IoBase);
- pAC->BoardLevel = SK_INIT_DATA;
- }
-
- FreeResources(dev);
- free_netdev(dev);
- if (otherdev != dev)
- free_netdev(otherdev);
- kfree(pAC);
-}
-
-#ifdef CONFIG_PM
-static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- struct net_device *otherdev = pAC->dev[1];
-
- if (netif_running(dev)) {
- netif_carrier_off(dev);
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
- netif_device_detach(dev);
- }
- if (otherdev != dev) {
- if (netif_running(otherdev)) {
- netif_carrier_off(otherdev);
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */
- netif_device_detach(otherdev);
- }
- }
-
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
- if (pAC->AllocFlag & SK_ALLOC_IRQ) {
- free_irq(dev->irq, dev);
- }
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static int skge_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- DEV_NET *pNet = netdev_priv(dev);
- SK_AC *pAC = pNet->pAC;
- struct net_device *otherdev = pAC->dev[1];
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
- if (ret) {
- printk(KERN_WARNING "sk98lin: unable to enable device %s "
- "in resume\n", dev->name);
- goto err_out;
- }
- pci_set_master(pdev);
- if (pAC->GIni.GIMacsFound == 2)
- ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
- else
- ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev);
- if (ret) {
- printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
- ret = -EBUSY;
- goto err_out_disable_pdev;
- }
-
- netif_device_attach(dev);
- if (netif_running(dev)) {
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvInitAdapter(pAC, 0); /* first device */
- }
- if (otherdev != dev) {
- netif_device_attach(otherdev);
- if (netif_running(otherdev)) {
- DoPrintInterfaceChange = SK_FALSE;
- SkDrvInitAdapter(pAC, 1); /* second device */
- }
- }
-
- return 0;
-
-err_out_disable_pdev:
- pci_disable_device(pdev);
-err_out:
- pAC->AllocFlag &= ~SK_ALLOC_IRQ;
- dev->irq = 0;
- return ret;
-}
-#else
-#define skge_suspend NULL
-#define skge_resume NULL
-#endif
-
-static struct pci_device_id skge_pci_tbl[] = {
- { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-/* DLink card does not have valid VPD so this driver gags
- * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- */
- { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
- { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
-
-static struct pci_driver skge_driver = {
- .name = "sk98lin",
- .id_table = skge_pci_tbl,
- .probe = skge_probe_one,
- .remove = __devexit_p(skge_remove_one),
- .suspend = skge_suspend,
- .resume = skge_resume,
-};
-
-static int __init skge_init(void)
-{
- printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver"
- " and is scheduled for removal\n");
-
- return pci_register_driver(&skge_driver);
-}
-
-static void __exit skge_exit(void)
-{
- pci_unregister_driver(&skge_driver);
-}
-
-module_init(skge_init);
-module_exit(skge_exit);
diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
deleted file mode 100644
index db670993c2df..000000000000
--- a/drivers/net/sk98lin/skgehwt.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/******************************************************************************
- *
- * Name: skgehwt.c
- * Project: Gigabit Ethernet Adapters, Event Scheduler Module
- * Version: $Revision: 1.15 $
- * Date: $Date: 2003/09/16 13:41:23 $
- * Purpose: Hardware Timer
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * Event queue and dispatcher
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h" /* Driver Specific Definitions */
-#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
- * Hardware Timer function queue management.
- */
-intro()
-{}
-#endif
-
-/*
- * Prototypes of local functions.
- */
-#define SK_HWT_MAX (65000)
-
-/* correction factor */
-#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
-
-/*
- * Initialize hardware timer.
- *
- * Must be called during init level 1.
- */
-void SkHwtInit(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc) /* IoContext */
-{
- pAC->Hwt.TStart = 0 ;
- pAC->Hwt.TStop = 0 ;
- pAC->Hwt.TActive = SK_FALSE;
-
- SkHwtStop(pAC, Ioc);
-}
-
-/*
- *
- * Start hardware timer (clock ticks are 16us).
- *
- */
-void SkHwtStart(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc, /* IoContext */
-SK_U32 Time) /* Time in units of 16us to load the timer with. */
-{
- SK_U32 Cnt;
-
- if (Time > SK_HWT_MAX)
- Time = SK_HWT_MAX;
-
- pAC->Hwt.TStart = Time;
- pAC->Hwt.TStop = 0L;
-
- Cnt = Time;
-
- /*
- * if time < 16 us
- * time = 16 us
- */
- if (!Cnt) {
- Cnt++;
- }
-
- SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
-
- SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */
-
- pAC->Hwt.TActive = SK_TRUE;
-}
-
-/*
- * Stop hardware timer.
- * and clear the timer IRQ
- */
-void SkHwtStop(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc) /* IoContext */
-{
- SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
-
- SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
-
- pAC->Hwt.TActive = SK_FALSE;
-}
-
-
-/*
- * Stop hardware timer and read time elapsed since last start.
- *
- * returns
- * The elapsed time since last start in units of 16us.
- *
- */
-SK_U32 SkHwtRead(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc) /* IoContext */
-{
- SK_U32 TRead;
- SK_U32 IStatus;
-
- if (pAC->Hwt.TActive) {
-
- SkHwtStop(pAC, Ioc);
-
- SK_IN32(Ioc, B2_TI_VAL, &TRead);
- TRead /= SK_HWT_FAC;
-
- SK_IN32(Ioc, B0_ISRC, &IStatus);
-
- /* Check if timer expired (or wraped around) */
- if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
-
- SkHwtStop(pAC, Ioc);
-
- pAC->Hwt.TStop = pAC->Hwt.TStart;
- }
- else {
-
- pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
- }
- }
- return(pAC->Hwt.TStop);
-}
-
-/*
- * interrupt source= timer
- */
-void SkHwtIsr(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc) /* IoContext */
-{
- SkHwtStop(pAC, Ioc);
-
- pAC->Hwt.TStop = pAC->Hwt.TStart;
-
- SkTimerDone(pAC, Ioc);
-}
-
-/* End of file */
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
deleted file mode 100644
index 67f1d6a5c15d..000000000000
--- a/drivers/net/sk98lin/skgeinit.c
+++ /dev/null
@@ -1,2005 +0,0 @@
-/******************************************************************************
- *
- * Name: skgeinit.c
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.97 $
- * Date: $Date: 2003/10/02 16:45:31 $
- * Purpose: Contains functions to initialize the adapter
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* global variables ***********************************************************/
-
-/* local variables ************************************************************/
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
-#endif
-
-struct s_QOffTab {
- int RxQOff; /* Receive Queue Address Offset */
- int XsQOff; /* Sync Tx Queue Address Offset */
- int XaQOff; /* Async Tx Queue Address Offset */
-};
-static struct s_QOffTab QOffTab[] = {
- {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
-};
-
-struct s_Config {
- char ScanString[8];
- SK_U32 Value;
-};
-
-static struct s_Config OemConfig = {
- {'O','E','M','_','C','o','n','f'},
-#ifdef SK_OEM_CONFIG
- OEM_CONFIG_VALUE,
-#else
- 0,
-#endif
-};
-
-/******************************************************************************
- *
- * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
- *
- * Description:
- * Enable or disable the descriptor polling of the transmit descriptor
- * ring(s) (TxD) for port 'Port'.
- * The new configuration is *not* saved over any SkGeStopPort() and
- * SkGeInitPort() calls.
- *
- * Returns:
- * nothing
- */
-void SkGePollTxD(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
-{
- SK_GEPORT *pPrt;
- SK_U32 DWord;
-
- pPrt = &pAC->GIni.GP[Port];
-
- DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL);
-
- if (pPrt->PXSQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
- }
-
- if (pPrt->PXAQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
- }
-} /* SkGePollTxD */
-
-
-/******************************************************************************
- *
- * SkGeYellowLED() - Switch the yellow LED on or off.
- *
- * Description:
- * Switch the yellow LED on or off.
- *
- * Note:
- * This function may be called any time after SkGeInit(Level 1).
- *
- * Returns:
- * nothing
- */
-void SkGeYellowLED(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int State) /* yellow LED state, 0 = OFF, 0 != ON */
-{
- if (State == 0) {
- /* Switch yellow LED OFF */
- SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
- }
- else {
- /* Switch yellow LED ON */
- SK_OUT8(IoC, B0_LED, LED_STAT_ON);
- }
-} /* SkGeYellowLED */
-
-
-#if (!defined(SK_SLIM) || defined(GENESIS))
-/******************************************************************************
- *
- * SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
- *
- * Description:
- * The Rx or Tx LED which is specified by 'Led' will be
- * enabled, disabled or switched on in test mode.
- *
- * Note:
- * 'Led' must contain the address offset of the LEDs INI register.
- *
- * Usage:
- * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
- *
- * Returns:
- * nothing
- */
-void SkGeXmitLED(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Led, /* offset to the LED Init Value register */
-int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
-{
- SK_U32 LedIni;
-
- switch (Mode) {
- case SK_LED_ENA:
- LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
- SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
- SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
- break;
- case SK_LED_TST:
- SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
- SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
- SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
- break;
- case SK_LED_DIS:
- default:
- /*
- * Do NOT stop the LED Timer here. The LED might be
- * in on state. But it needs to go off.
- */
- SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
- SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
- break;
- }
-
- /*
- * 1000BT: The Transmit LED is driven by the PHY.
- * But the default LED configuration is used for
- * Level One and Broadcom PHYs.
- * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
- * (In this case it has to be added here. But we will see. XXX)
- */
-} /* SkGeXmitLED */
-#endif /* !SK_SLIM || GENESIS */
-
-
-/******************************************************************************
- *
- * DoCalcAddr() - Calculates the start and the end address of a queue.
- *
- * Description:
- * This function calculates the start and the end address of a queue.
- * Afterwards the 'StartVal' is incremented to the next start position.
- * If the port is already initialized the calculated values
- * will be checked against the configured values and an
- * error will be returned, if they are not equal.
- * If the port is not initialized the values will be written to
- * *StartAdr and *EndAddr.
- *
- * Returns:
- * 0: success
- * 1: configuration error
- */
-static int DoCalcAddr(
-SK_AC *pAC, /* adapter context */
-SK_GEPORT SK_FAR *pPrt, /* port index */
-int QuSize, /* size of the queue to configure in kB */
-SK_U32 SK_FAR *StartVal, /* start value for address calculation */
-SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */
-SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */
-{
- SK_U32 EndVal;
- SK_U32 NextStart;
- int Rtv;
-
- Rtv = 0;
- if (QuSize == 0) {
- EndVal = *StartVal;
- NextStart = EndVal;
- }
- else {
- EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
- NextStart = EndVal + 1;
- }
-
- if (pPrt->PState >= SK_PRT_INIT) {
- if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
- Rtv = 1;
- }
- }
- else {
- *QuStartAddr = *StartVal;
- *QuEndAddr = EndVal;
- }
-
- *StartVal = NextStart;
- return(Rtv);
-} /* DoCalcAddr */
-
-/******************************************************************************
- *
- * SkGeInitAssignRamToQueues() - allocate default queue sizes
- *
- * Description:
- * This function assigns the memory to the different queues and ports.
- * When DualNet is set to SK_TRUE all ports get the same amount of memory.
- * Otherwise the first port gets most of the memory and all the
- * other ports just the required minimum.
- * This function can only be called when pAC->GIni.GIRamSize and
- * pAC->GIni.GIMacsFound have been initialized, usually this happens
- * at init level 1
- *
- * Returns:
- * 0 - ok
- * 1 - invalid input values
- * 2 - not enough memory
- */
-
-int SkGeInitAssignRamToQueues(
-SK_AC *pAC, /* Adapter context */
-int ActivePort, /* Active Port in RLMT mode */
-SK_BOOL DualNet) /* adapter context */
-{
- int i;
- int UsedKilobytes; /* memory already assigned */
- int ActivePortKilobytes; /* memory available for active port */
- SK_GEPORT *pGePort;
-
- UsedKilobytes = 0;
-
- if (ActivePort >= pAC->GIni.GIMacsFound) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
- ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
- ActivePort));
- return(1);
- }
- if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
- ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
- ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
- pAC->GIni.GIRamSize));
- return(2);
- }
-
- if (DualNet) {
- /* every port gets the same amount of memory */
- ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
- pGePort = &pAC->GIni.GP[i];
-
- /* take away the minimum memory for active queues */
- ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
-
- /* receive queue gets the minimum + 80% of the rest */
- pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
- ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
- + SK_MIN_RXQ_SIZE;
-
- ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
-
- /* synchronous transmit queue */
- pGePort->PXSQSize = 0;
-
- /* asynchronous transmit queue */
- pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
- SK_MIN_TXQ_SIZE);
- }
- }
- else {
- /* Rlmt Mode or single link adapter */
-
- /* Set standby queue size defaults for all standby ports */
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
- if (i != ActivePort) {
- pGePort = &pAC->GIni.GP[i];
-
- pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
- pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
- pGePort->PXSQSize = 0;
-
- /* Count used RAM */
- UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
- }
- }
- /* what's left? */
- ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
-
- /* assign it to the active port */
- /* first take away the minimum memory */
- ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
- pGePort = &pAC->GIni.GP[ActivePort];
-
- /* receive queue get's the minimum + 80% of the rest */
- pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
- (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
-
- ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
-
- /* synchronous transmit queue */
- pGePort->PXSQSize = 0;
-
- /* asynchronous transmit queue */
- pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
- SK_MIN_TXQ_SIZE;
- }
-#ifdef VCPU
- VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
- pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
-#endif /* VCPU */
-
- return(0);
-} /* SkGeInitAssignRamToQueues */
-
-/******************************************************************************
- *
- * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
- *
- * Description:
- * This function verifies the Queue Size Configuration specified
- * in the variables PRxQSize, PXSQSize, and PXAQSize of all
- * used ports.
- * This requirements must be fullfilled to have a valid configuration:
- * - The size of all queues must not exceed GIRamSize.
- * - The queue sizes must be specified in units of 8 kB.
- * - The size of Rx queues of available ports must not be
- * smaller than 16 kB.
- * - The size of at least one Tx queue (synch. or asynch.)
- * of available ports must not be smaller than 16 kB
- * when Jumbo Frames are used.
- * - The RAM start and end addresses must not be changed
- * for ports which are already initialized.
- * Furthermore SkGeCheckQSize() defines the Start and End Addresses
- * of all ports and stores them into the HWAC port structure.
- *
- * Returns:
- * 0: Queue Size Configuration valid
- * 1: Queue Size Configuration invalid
- */
-static int SkGeCheckQSize(
-SK_AC *pAC, /* adapter context */
-int Port) /* port index */
-{
- SK_GEPORT *pPrt;
- int i;
- int Rtv;
- int Rtv2;
- SK_U32 StartAddr;
-#ifndef SK_SLIM
- int UsedMem; /* total memory used (max. found ports) */
-#endif
-
- Rtv = 0;
-
-#ifndef SK_SLIM
-
- UsedMem = 0;
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
- pPrt = &pAC->GIni.GP[i];
-
- if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
- (pPrt->PXSQSize & QZ_UNITS) != 0 ||
- (pPrt->PXAQSize & QZ_UNITS) != 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
- return(1);
- }
-
- if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
- return(1);
- }
-
- /*
- * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
- * if Jumbo Frames are used, this size has to be >= 16 kB.
- */
- if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
- (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
- ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
- (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
- return(1);
- }
-
- UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
- }
-
- if (UsedMem > pAC->GIni.GIRamSize) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
- return(1);
- }
-#endif /* !SK_SLIM */
-
- /* Now start address calculation */
- StartAddr = pAC->GIni.GIRamOffs;
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
- pPrt = &pAC->GIni.GP[i];
-
- /* Calculate/Check values for the receive queue */
- Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
- &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
- Rtv |= Rtv2;
-
- /* Calculate/Check values for the synchronous Tx queue */
- Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
- &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
- Rtv |= Rtv2;
-
- /* Calculate/Check values for the asynchronous Tx queue */
- Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
- &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
- Rtv |= Rtv2;
-
- if (Rtv) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
- return(1);
- }
- }
-
- return(0);
-} /* SkGeCheckQSize */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkGeInitMacArb() - Initialize the MAC Arbiter
- *
- * Description:
- * This function initializes the MAC Arbiter.
- * It must not be called if there is still an
- * initialized or active port.
- *
- * Returns:
- * nothing
- */
-static void SkGeInitMacArb(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
- /* release local reset */
- SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
-
- /* configure timeout values */
- SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
- SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
- SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
- SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
-
- SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
- SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
- SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
- SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
-
- /* recovery values are needed for XMAC II Rev. B2 only */
- /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
-
- /*
- * There is no start or enable button to push, therefore
- * the MAC arbiter is configured and enabled now.
- */
-} /* SkGeInitMacArb */
-
-
-/******************************************************************************
- *
- * SkGeInitPktArb() - Initialize the Packet Arbiter
- *
- * Description:
- * This function initializes the Packet Arbiter.
- * It must not be called if there is still an
- * initialized or active port.
- *
- * Returns:
- * nothing
- */
-static void SkGeInitPktArb(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
- /* release local reset */
- SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
-
- /* configure timeout values */
- SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
- SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
- SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
- SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
-
- /*
- * enable timeout timers if jumbo frames not used
- * NOTE: the packet arbiter timeout interrupt is needed for
- * half duplex hangup workaround
- */
- if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
- if (pAC->GIni.GIMacsFound == 1) {
- SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
- }
- else {
- SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
- }
- }
-} /* SkGeInitPktArb */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- * SkGeInitMacFifo() - Initialize the MAC FIFOs
- *
- * Description:
- * Initialize all MAC FIFOs of the specified port
- *
- * Returns:
- * nothing
- */
-static void SkGeInitMacFifo(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U16 Word;
-#ifdef VCPU
- SK_U32 DWord;
-#endif /* VCPU */
- /*
- * For each FIFO:
- * - release local reset
- * - use default value for MAC FIFO size
- * - setup defaults for the control register
- * - enable the FIFO
- */
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* Configure Rx MAC FIFO */
- SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
- SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
- SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
-
- /* Configure Tx MAC FIFO */
- SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
- SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
-
- /* Enable frame flushing if jumbo frames used */
- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
- SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* set Rx GMAC FIFO Flush Mask */
- SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
-
- Word = (SK_U16)GMF_RX_CTRL_DEF;
-
- /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
- if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
-
- Word &= ~GMF_RX_F_FL_ON;
- }
-
- /* Configure Rx MAC FIFO */
- SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
- SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
-
- /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
- SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
-
- /* Configure Tx MAC FIFO */
- SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
- SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
-
-#ifdef VCPU
- SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
- SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
-#endif /* VCPU */
-
- /* set Tx GMAC FIFO Almost Empty Threshold */
-/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
- }
-#endif /* YUKON */
-
-} /* SkGeInitMacFifo */
-
-#ifdef SK_LNK_SYNC_CNT
-/******************************************************************************
- *
- * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
- *
- * Description:
- * This function starts the Link Sync Counter of the specified
- * port and enables the generation of an Link Sync IRQ.
- * The Link Sync Counter may be used to detect an active link,
- * if autonegotiation is not used.
- *
- * Note:
- * o To ensure receiving the Link Sync Event the LinkSyncCounter
- * should be initialized BEFORE clearing the XMAC's reset!
- * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
- * function.
- *
- * Returns:
- * nothing
- */
-void SkGeLoadLnkSyncCnt(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_U32 CntVal) /* Counter value */
-{
- SK_U32 OrgIMsk;
- SK_U32 NewIMsk;
- SK_U32 ISrc;
- SK_BOOL IrqPend;
-
- /* stop counter */
- SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
-
- /*
- * ASIC problem:
- * Each time starting the Link Sync Counter an IRQ is generated
- * by the adapter. See problem report entry from 21.07.98
- *
- * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ
- * if no IRQ is already pending.
- */
- IrqPend = SK_FALSE;
- SK_IN32(IoC, B0_ISRC, &ISrc);
- SK_IN32(IoC, B0_IMSK, &OrgIMsk);
- if (Port == MAC_1) {
- NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
- if ((ISrc & IS_LNK_SYNC_M1) != 0) {
- IrqPend = SK_TRUE;
- }
- }
- else {
- NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
- if ((ISrc & IS_LNK_SYNC_M2) != 0) {
- IrqPend = SK_TRUE;
- }
- }
- if (!IrqPend) {
- SK_OUT32(IoC, B0_IMSK, NewIMsk);
- }
-
- /* load counter */
- SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
-
- /* start counter */
- SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
-
- if (!IrqPend) {
- /* clear the unexpected IRQ, and restore the interrupt mask */
- SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
- SK_OUT32(IoC, B0_IMSK, OrgIMsk);
- }
-} /* SkGeLoadLnkSyncCnt*/
-#endif /* SK_LNK_SYNC_CNT */
-
-#if defined(SK_DIAG) || defined(SK_CFG_SYNC)
-/******************************************************************************
- *
- * SkGeCfgSync() - Configure synchronous bandwidth for this port.
- *
- * Description:
- * This function may be used to configure synchronous bandwidth
- * to the specified port. This may be done any time after
- * initializing the port. The configuration values are NOT saved
- * in the HWAC port structure and will be overwritten any
- * time when stopping and starting the port.
- * Any values for the synchronous configuration will be ignored
- * if the size of the synchronous queue is zero!
- *
- * The default configuration for the synchronous service is
- * TXA_ENA_FSYNC. This means if the size of
- * the synchronous queue is unequal zero but no specific
- * synchronous bandwidth is configured, the synchronous queue
- * will always have the 'unlimited' transmit priority!
- *
- * This mode will be restored if the synchronous bandwidth is
- * deallocated ('IntTime' = 0 and 'LimCount' = 0).
- *
- * Returns:
- * 0: success
- * 1: parameter configuration error
- * 2: try to configure quality of service although no
- * synchronous queue is configured
- */
-int SkGeCfgSync(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_U32 IntTime, /* Interval Timer Value in units of 8ns */
-SK_U32 LimCount, /* Number of bytes to transfer during IntTime */
-int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
-{
- int Rtv;
-
- Rtv = 0;
-
- /* check the parameters */
- if (LimCount > IntTime ||
- (LimCount == 0 && IntTime != 0) ||
- (LimCount != 0 && IntTime == 0)) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
- return(1);
- }
-
- if (pAC->GIni.GP[Port].PXSQSize == 0) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
- return(2);
- }
-
- /* calculate register values */
- IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
- LimCount = LimCount / 8;
-
- if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
- return(1);
- }
-
- /*
- * - Enable 'Force Sync' to ensure the synchronous queue
- * has the priority while configuring the new values.
- * - Also 'disable alloc' to ensure the settings complies
- * to the SyncMode parameter.
- * - Disable 'Rate Control' to configure the new values.
- * - write IntTime and LimCount
- * - start 'Rate Control' and disable 'Force Sync'
- * if Interval Timer or Limit Counter not zero.
- */
- SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
- TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-
- SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
- SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
-
- SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
- (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
-
- if (IntTime != 0 || LimCount != 0) {
- SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
- }
-
- return(0);
-} /* SkGeCfgSync */
-#endif /* SK_DIAG || SK_CFG_SYNC*/
-
-
-/******************************************************************************
- *
- * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
- *
- * Desccription:
- * If the queue is used, enable and initialize it.
- * Make sure the queue is still reset, if it is not used.
- *
- * Returns:
- * nothing
- */
-static void DoInitRamQueue(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int QuIoOffs, /* Queue IO Address Offset */
-SK_U32 QuStartAddr, /* Queue Start Address */
-SK_U32 QuEndAddr, /* Queue End Address */
-int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
-{
- SK_U32 RxUpThresVal;
- SK_U32 RxLoThresVal;
-
- if (QuStartAddr != QuEndAddr) {
- /* calculate thresholds, assume we have a big Rx queue */
- RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
- RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
-
- /* build HW address format */
- QuStartAddr = QuStartAddr / 8;
- QuEndAddr = QuEndAddr / 8;
-
- /* release local reset */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
-
- /* configure addresses */
- SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
-
- switch (QuType) {
- case SK_RX_SRAM_Q:
- /* configure threshold for small Rx Queue */
- RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
-
- /* continue with SK_RX_BRAM_Q */
- case SK_RX_BRAM_Q:
- /* write threshold for Rx Queue */
-
- SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
-
- /* the high priority threshold not used */
- break;
- case SK_TX_RAM_Q:
- /*
- * Do NOT use Store & Forward under normal operation due to
- * performance optimization (GENESIS only).
- * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
- * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
- * we NEED Store & Forward of the RAM buffer.
- */
- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
- pAC->GIni.GIYukon) {
- /* enable Store & Forward Mode for the Tx Side */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
- }
- break;
- }
-
- /* set queue operational */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
- }
- else {
- /* ensure the queue is still disabled */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
- }
-} /* DoInitRamQueue */
-
-
-/******************************************************************************
- *
- * SkGeInitRamBufs() - Initialize the RAM Buffer Queues
- *
- * Description:
- * Initialize all RAM Buffer Queues of the specified port
- *
- * Returns:
- * nothing
- */
-static void SkGeInitRamBufs(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- int RxQType;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
- RxQType = SK_RX_SRAM_Q; /* small Rx Queue */
- }
- else {
- RxQType = SK_RX_BRAM_Q; /* big Rx Queue */
- }
-
- DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
- pPrt->PRxQRamEnd, RxQType);
-
- DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
- pPrt->PXsQRamEnd, SK_TX_RAM_Q);
-
- DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
- pPrt->PXaQRamEnd, SK_TX_RAM_Q);
-
-} /* SkGeInitRamBufs */
-
-
-/******************************************************************************
- *
- * SkGeInitRamIface() - Initialize the RAM Interface
- *
- * Description:
- * This function initializes the Adapters RAM Interface.
- *
- * Note:
- * This function is used in the diagnostics.
- *
- * Returns:
- * nothing
- */
-static void SkGeInitRamIface(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
- /* release local reset */
- SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
-
- /* configure timeout values */
- SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
- SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
-
-} /* SkGeInitRamIface */
-
-
-/******************************************************************************
- *
- * SkGeInitBmu() - Initialize the BMU state machines
- *
- * Description:
- * Initialize all BMU state machines of the specified port
- *
- * Returns:
- * nothing
- */
-static void SkGeInitBmu(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U32 RxWm;
- SK_U32 TxWm;
-
- pPrt = &pAC->GIni.GP[Port];
-
- RxWm = SK_BMU_RX_WM;
- TxWm = SK_BMU_TX_WM;
-
- if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
- /* for better performance */
- RxWm /= 2;
- TxWm /= 2;
- }
-
- /* Rx Queue: Release all local resets and set the watermark */
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
-
- /*
- * Tx Queue: Release all local resets if the queue is used !
- * set watermark
- */
- if (pPrt->PXSQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
- }
-
- if (pPrt->PXAQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
- }
- /*
- * Do NOT enable the descriptor poll timers here, because
- * the descriptor addresses are not specified yet.
- */
-} /* SkGeInitBmu */
-
-
-/******************************************************************************
- *
- * TestStopBit() - Test the stop bit of the queue
- *
- * Description:
- * Stopping a queue is not as simple as it seems to be.
- * If descriptor polling is enabled, it may happen
- * that RX/TX stop is done and SV idle is NOT set.
- * In this case we have to issue another stop command.
- *
- * Returns:
- * The queues control status register
- */
-static SK_U32 TestStopBit(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int QuIoOffs) /* Queue IO Address Offset */
-{
- SK_U32 QuCsr; /* CSR contents */
-
- SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
-
- if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
- /* Stop Descriptor overridden by start command */
- SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
-
- SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
- }
-
- return(QuCsr);
-} /* TestStopBit */
-
-
-/******************************************************************************
- *
- * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
- *
- * Description:
- * After calling this function the descriptor rings and Rx and Tx
- * queues of this port may be reconfigured.
- *
- * It is possible to stop the receive and transmit path separate or
- * both together.
- *
- * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC.
- * The receive queue is still active and
- * the pending Rx frames may be still transferred
- * into the RxD.
- * SK_STOP_RX Stop the receive path. The tansmit path
- * has to be stopped once before.
- * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX
- *
- * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive.
- * SK_HARD_RST Resets the MAC and the PHY.
- *
- * Example:
- * 1) A Link Down event was signaled for a port. Therefore the activity
- * of this port should be stopped and a hardware reset should be issued
- * to enable the workaround of XMAC Errata #2. But the received frames
- * should not be discarded.
- * ...
- * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
- * (transfer all pending Rx frames)
- * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
- * ...
- *
- * 2) An event was issued which request the driver to switch
- * the 'virtual active' link to an other already active port
- * as soon as possible. The frames in the receive queue of this
- * port may be lost. But the PHY must not be reset during this
- * event.
- * ...
- * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
- * ...
- *
- * Extended Description:
- * If SK_STOP_TX is set,
- * o disable the MAC's receive and transmitter to prevent
- * from sending incomplete frames
- * o stop the port's transmit queues before terminating the
- * BMUs to prevent from performing incomplete PCI cycles
- * on the PCI bus
- * - The network Rx and Tx activity and PCI Tx transfer is
- * disabled now.
- * o reset the MAC depending on the RstMode
- * o Stop Interval Timer and Limit Counter of Tx Arbiter,
- * also disable Force Sync bit and Enable Alloc bit.
- * o perform a local reset of the port's Tx path
- * - reset the PCI FIFO of the async Tx queue
- * - reset the PCI FIFO of the sync Tx queue
- * - reset the RAM Buffer async Tx queue
- * - reset the RAM Buffer sync Tx queue
- * - reset the MAC Tx FIFO
- * o switch Link and Tx LED off, stop the LED counters
- *
- * If SK_STOP_RX is set,
- * o stop the port's receive queue
- * - The path data transfer activity is fully stopped now.
- * o perform a local reset of the port's Rx path
- * - reset the PCI FIFO of the Rx queue
- * - reset the RAM Buffer receive queue
- * - reset the MAC Rx FIFO
- * o switch Rx LED off, stop the LED counter
- *
- * If all ports are stopped,
- * o reset the RAM Interface.
- *
- * Notes:
- * o This function may be called during the driver states RESET_PORT and
- * SWITCH_PORT.
- */
-void SkGeStopPort(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-int Port, /* port to stop (MAC_1 + n) */
-int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
-int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
-{
-#ifndef SK_DIAG
- SK_EVPARA Para;
-#endif /* !SK_DIAG */
- SK_GEPORT *pPrt;
- SK_U32 DWord;
- SK_U32 XsCsr;
- SK_U32 XaCsr;
- SK_U64 ToutStart;
- int i;
- int ToutCnt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if ((Dir & SK_STOP_TX) != 0) {
- /* disable receiver and transmitter */
- SkMacRxTxDisable(pAC, IoC, Port);
-
- /* stop both transmit queues */
- /*
- * If the BMU is in the reset state CSR_STOP will terminate
- * immediately.
- */
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
-
- ToutStart = SkOsGetTime(pAC);
- ToutCnt = 0;
- do {
- /*
- * Clear packet arbiter timeout to make sure
- * this loop will terminate.
- */
- SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
- PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
-
- /*
- * If the transfer stucks at the MAC the STOP command will not
- * terminate if we don't flush the XMAC's transmit FIFO !
- */
- SkMacFlushTxFifo(pAC, IoC, Port);
-
- XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
- XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
-
- if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
- /*
- * Timeout of 1/18 second reached.
- * This needs to be checked at 1/18 sec only.
- */
- ToutCnt++;
- if (ToutCnt > 1) {
- /* Might be a problem when the driver event handler
- * calls StopPort again. XXX.
- */
-
- /* Fatal Error, Loop aborted */
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
- SKERR_HWI_E018MSG);
-#ifndef SK_DIAG
- Para.Para64 = Port;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-#endif /* !SK_DIAG */
- return;
- }
- /*
- * Cache incoherency workaround: Assume a start command
- * has been lost while sending the frame.
- */
- ToutStart = SkOsGetTime(pAC);
-
- if ((XsCsr & CSR_STOP) != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
- }
- if ((XaCsr & CSR_STOP) != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
- }
- }
-
- /*
- * Because of the ASIC problem report entry from 21.08.1998 it is
- * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
- */
- } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
- (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
-
- /* Reset the MAC depending on the RstMode */
- if (RstMode == SK_SOFT_RST) {
- SkMacSoftRst(pAC, IoC, Port);
- }
- else {
- SkMacHardRst(pAC, IoC, Port);
- }
-
- /* Disable Force Sync bit and Enable Alloc bit */
- SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
- TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-
- /* Stop Interval Timer and Limit Counter of Tx Arbiter */
- SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
- SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
-
- /* Perform a local reset of the port's Tx path */
-
- /* Reset the PCI FIFO of the async Tx queue */
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
- /* Reset the PCI FIFO of the sync Tx queue */
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
- /* Reset the RAM Buffer async Tx queue */
- SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
- /* Reset the RAM Buffer sync Tx queue */
- SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
-
- /* Reset Tx MAC FIFO */
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* Note: MFF_RST_SET does NOT reset the XMAC ! */
- SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
-
- /* switch Link and Tx LED off, stop the LED counters */
- /* Link LED is switched off by the RLMT and the Diag itself */
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* Reset TX MAC FIFO */
- SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
- }
-#endif /* YUKON */
- }
-
- if ((Dir & SK_STOP_RX) != 0) {
- /*
- * The RX Stop Command will not terminate if no buffers
- * are queued in the RxD ring. But it will always reach
- * the Idle state. Therefore we can use this feature to
- * stop the transfer of received packets.
- */
- /* stop the port's receive queue */
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
-
- i = 100;
- do {
- /*
- * Clear packet arbiter timeout to make sure
- * this loop will terminate
- */
- SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
- PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
-
- DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
-
- /* timeout if i==0 (bug fix for #10748) */
- if (--i == 0) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
- SKERR_HWI_E024MSG);
- break;
- }
- /*
- * because of the ASIC problem report entry from 21.08.98
- * it is required to wait until CSR_STOP is reset and
- * CSR_SV_IDLE is set.
- */
- } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
-
- /* The path data transfer activity is fully stopped now */
-
- /* Perform a local reset of the port's Rx path */
-
- /* Reset the PCI FIFO of the Rx queue */
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
- /* Reset the RAM Buffer receive queue */
- SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
-
- /* Reset Rx MAC FIFO */
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
-
- /* switch Rx LED off, stop the LED counter */
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* Reset Rx MAC FIFO */
- SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
- }
-#endif /* YUKON */
- }
-} /* SkGeStopPort */
-
-
-/******************************************************************************
- *
- * SkGeInit0() - Level 0 Initialization
- *
- * Description:
- * - Initialize the BMU address offsets
- *
- * Returns:
- * nothing
- */
-static void SkGeInit0(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
- int i;
- SK_GEPORT *pPrt;
-
- for (i = 0; i < SK_MAX_MACS; i++) {
- pPrt = &pAC->GIni.GP[i];
-
- pPrt->PState = SK_PRT_RESET;
- pPrt->PRxQOff = QOffTab[i].RxQOff;
- pPrt->PXsQOff = QOffTab[i].XsQOff;
- pPrt->PXaQOff = QOffTab[i].XaQOff;
- pPrt->PCheckPar = SK_FALSE;
- pPrt->PIsave = 0;
- pPrt->PPrevShorts = 0;
- pPrt->PLinkResCt = 0;
- pPrt->PAutoNegTOCt = 0;
- pPrt->PPrevRx = 0;
- pPrt->PPrevFcs = 0;
- pPrt->PRxLim = SK_DEF_RX_WA_LIM;
- pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
- pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;
- pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;
- pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;
- pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
- pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
- SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
- pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
- pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
- pPrt->PMSCap = 0;
- pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;
- pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;
- pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
- pPrt->PAutoNegFail = SK_FALSE;
- pPrt->PHWLinkUp = SK_FALSE;
- pPrt->PLinkBroken = SK_TRUE; /* See WA code */
- pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
- pPrt->PMacColThres = TX_COL_DEF;
- pPrt->PMacJamLen = TX_JAM_LEN_DEF;
- pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF;
- pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
- pPrt->PMacIpgData = IPG_DATA_DEF;
- pPrt->PMacLimit4 = SK_FALSE;
- }
-
- pAC->GIni.GIPortUsage = SK_RED_LINK;
- pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
- pAC->GIni.GIValIrqMask = IS_ALL_MSK;
-
-} /* SkGeInit0*/
-
-
-/******************************************************************************
- *
- * SkGeInit1() - Level 1 Initialization
- *
- * Description:
- * o Do a software reset.
- * o Clear all reset bits.
- * o Verify that the detected hardware is present.
- * Return an error if not.
- * o Get the hardware configuration
- * + Read the number of MACs/Ports.
- * + Read the RAM size.
- * + Read the PCI Revision Id.
- * + Find out the adapters host clock speed
- * + Read and check the PHY type
- *
- * Returns:
- * 0: success
- * 5: Unexpected PHY type detected
- * 6: HW self test failed
- */
-static int SkGeInit1(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
- SK_U8 Byte;
- SK_U16 Word;
- SK_U16 CtrlStat;
- SK_U32 DWord;
- int RetVal;
- int i;
-
- RetVal = 0;
-
- /* save CLK_RUN bits (YUKON-Lite) */
- SK_IN16(IoC, B0_CTST, &CtrlStat);
-
- /* do the SW-reset */
- SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-
- /* release the SW-reset */
- SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
-
- /* reset all error bits in the PCI STATUS register */
- /*
- * Note: PCI Cfg cycles cannot be used, because they are not
- * available on some platforms after 'boot time'.
- */
- SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-
- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
- /* release Master Reset */
- SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
-
-#ifdef CLK_RUN
- CtrlStat |= CS_CLK_RUN_ENA;
-#endif /* CLK_RUN */
-
- /* restore CLK_RUN bits */
- SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
- (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
-
- /* read Chip Identification Number */
- SK_IN8(IoC, B2_CHIP_ID, &Byte);
- pAC->GIni.GIChipId = Byte;
-
- /* read number of MACs */
- SK_IN8(IoC, B2_MAC_CFG, &Byte);
- pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
-
- /* get Chip Revision Number */
- pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
-
- /* get diff. PCI parameters */
- SK_IN16(IoC, B0_CTST, &CtrlStat);
-
- /* read the adapters RAM size */
- SK_IN8(IoC, B2_E_0, &Byte);
-
- pAC->GIni.GIGenesis = SK_FALSE;
- pAC->GIni.GIYukon = SK_FALSE;
- pAC->GIni.GIYukonLite = SK_FALSE;
-
-#ifdef GENESIS
- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-
- pAC->GIni.GIGenesis = SK_TRUE;
-
- if (Byte == (SK_U8)3) {
- /* special case: 4 x 64k x 36, offset = 0x80000 */
- pAC->GIni.GIRamSize = 1024;
- pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
- }
- else {
- pAC->GIni.GIRamSize = (int)Byte * 512;
- pAC->GIni.GIRamOffs = 0;
- }
- /* all GE adapters work with 53.125 MHz host clock */
- pAC->GIni.GIHstClkFact = SK_FACT_53;
-
- /* set Descr. Poll Timer Init Value to 250 ms */
- pAC->GIni.GIPollTimerVal =
- SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
-
- pAC->GIni.GIYukon = SK_TRUE;
-
- pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
-
- pAC->GIni.GIRamOffs = 0;
-
- /* WA for chip Rev. A */
- pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
- pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
-
- /* get PM Capabilities of PCI config space */
- SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
-
- /* check if VAUX is available */
- if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
- /* check also if PME from D3cold is set */
- ((Word & PCI_PME_D3C_SUP) != 0)) {
- /* set entry in GE init struct */
- pAC->GIni.GIVauxAvail = SK_TRUE;
- }
-
- if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
- /* this is Rev. A1 */
- pAC->GIni.GIYukonLite = SK_TRUE;
- }
- else {
- /* save Flash-Address Register */
- SK_IN32(IoC, B2_FAR, &DWord);
-
- /* test Flash-Address Register */
- SK_OUT8(IoC, B2_FAR + 3, 0xff);
- SK_IN8(IoC, B2_FAR + 3, &Byte);
-
- if (Byte != 0) {
- /* this is Rev. A0 */
- pAC->GIni.GIYukonLite = SK_TRUE;
-
- /* restore Flash-Address Register */
- SK_OUT32(IoC, B2_FAR, DWord);
- }
- }
-
- /* switch power to VCC (WA for VAUX problem) */
- SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
- PC_VAUX_OFF | PC_VCC_ON));
-
- /* read the Interrupt source */
- SK_IN32(IoC, B0_ISRC, &DWord);
-
- if ((DWord & IS_HW_ERR) != 0) {
- /* read the HW Error Interrupt source */
- SK_IN32(IoC, B0_HWE_ISRC, &DWord);
-
- if ((DWord & IS_IRQ_SENSOR) != 0) {
- /* disable HW Error IRQ */
- pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
- }
- }
-
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
- /* set GMAC Link Control reset */
- SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-
- /* clear GMAC Link Control reset */
- SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
- }
- /* all YU chips work with 78.125 MHz host clock */
- pAC->GIni.GIHstClkFact = SK_FACT_78;
-
- pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */
- }
-#endif /* YUKON */
-
- /* check if 64-bit PCI Slot is present */
- pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
-
- /* check if 66 MHz PCI Clock is active */
- pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
-
- /* read PCI HW Revision Id. */
- SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
- pAC->GIni.GIPciHwRev = Byte;
-
- /* read the PMD type */
- SK_IN8(IoC, B2_PMD_TYP, &Byte);
- pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
-
- /* read the PHY type */
- SK_IN8(IoC, B2_E_1, &Byte);
-
- Byte &= 0x0f; /* the PHY type is stored in the lower nibble */
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- switch (Byte) {
- case SK_PHY_XMAC:
- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
- break;
- case SK_PHY_BCOM:
- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
- pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
- SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
- break;
- case SK_PHY_NAT:
- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
- break;
-#endif /* OTHER_PHY */
- default:
- /* ERROR: unexpected PHY type detected */
- RetVal = 5;
- break;
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
- /* if this field is not initialized */
- Byte = (SK_U8)SK_PHY_MARV_COPPER;
-
- pAC->GIni.GICopperType = SK_TRUE;
- }
-
- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
-
- if (pAC->GIni.GICopperType) {
-
- pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
- SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
- SK_LSPEED_CAP_1000MBPS);
-
- pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
-
- pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
- SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
- }
- else {
- Byte = (SK_U8)SK_PHY_MARV_FIBER;
- }
- }
-#endif /* YUKON */
-
- pAC->GIni.GP[i].PhyType = (int)Byte;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
- ("PHY type: %d PHY addr: %04x\n", Byte,
- pAC->GIni.GP[i].PhyAddr));
- }
-
- /* get MAC Type & set function pointers dependent on */
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- pAC->GIni.GIMacType = SK_MAC_XMAC;
-
- pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats;
- pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic;
- pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter;
- pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus;
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- pAC->GIni.GIMacType = SK_MAC_GMAC;
-
- pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats;
- pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic;
- pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter;
- pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus;
-
-#ifdef SPECIAL_HANDLING
- if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
- /* check HW self test result */
- SK_IN8(IoC, B2_E_3, &Byte);
- if (Byte & B2_E3_RES_MASK) {
- RetVal = 6;
- }
- }
-#endif
- }
-#endif /* YUKON */
-
- return(RetVal);
-} /* SkGeInit1 */
-
-
-/******************************************************************************
- *
- * SkGeInit2() - Level 2 Initialization
- *
- * Description:
- * - start the Blink Source Counter
- * - start the Descriptor Poll Timer
- * - configure the MAC-Arbiter
- * - configure the Packet-Arbiter
- * - enable the Tx Arbiters
- * - enable the RAM Interface Arbiter
- *
- * Returns:
- * nothing
- */
-static void SkGeInit2(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
-#ifdef GENESIS
- SK_U32 DWord;
-#endif /* GENESIS */
- int i;
-
- /* start the Descriptor Poll Timer */
- if (pAC->GIni.GIPollTimerVal != 0) {
- if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
- pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
- }
- SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
- SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
- }
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* start the Blink Source Counter */
- DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
-
- SK_OUT32(IoC, B2_BSC_INI, DWord);
- SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
-
- /*
- * Configure the MAC Arbiter and the Packet Arbiter.
- * They will be started once and never be stopped.
- */
- SkGeInitMacArb(pAC, IoC);
-
- SkGeInitPktArb(pAC, IoC);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* start Time Stamp Timer */
- SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
- }
-#endif /* YUKON */
-
- /* enable the Tx Arbiters */
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
- SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
- }
-
- /* enable the RAM Interface Arbiter */
- SkGeInitRamIface(pAC, IoC);
-
-} /* SkGeInit2 */
-
-/******************************************************************************
- *
- * SkGeInit() - Initialize the GE Adapter with the specified level.
- *
- * Description:
- * Level 0: Initialize the Module structures.
- * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has
- * to be set before calling this level.
- *
- * o Do a software reset.
- * o Clear all reset bits.
- * o Verify that the detected hardware is present.
- * Return an error if not.
- * o Get the hardware configuration
- * + Set GIMacsFound with the number of MACs.
- * + Store the RAM size in GIRamSize.
- * + Save the PCI Revision ID in GIPciHwRev.
- * o return an error
- * if Number of MACs > SK_MAX_MACS
- *
- * After returning from Level 0 the adapter
- * may be accessed with IO operations.
- *
- * Level 2: start the Blink Source Counter
- *
- * Returns:
- * 0: success
- * 1: Number of MACs exceeds SK_MAX_MACS (after level 1)
- * 2: Adapter not present or not accessible
- * 3: Illegal initialization level
- * 4: Initialization Level 1 Call missing
- * 5: Unexpected PHY type detected
- * 6: HW self test failed
- */
-int SkGeInit(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Level) /* initialization level */
-{
- int RetVal; /* return value */
- SK_U32 DWord;
-
- RetVal = 0;
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
- ("SkGeInit(Level %d)\n", Level));
-
- switch (Level) {
- case SK_INIT_DATA:
- /* Initialization Level 0 */
- SkGeInit0(pAC, IoC);
- pAC->GIni.GILevel = SK_INIT_DATA;
- break;
-
- case SK_INIT_IO:
- /* Initialization Level 1 */
- RetVal = SkGeInit1(pAC, IoC);
- if (RetVal != 0) {
- break;
- }
-
- /* check if the adapter seems to be accessible */
- SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
- SK_IN32(IoC, B2_IRQM_INI, &DWord);
- SK_OUT32(IoC, B2_IRQM_INI, 0L);
-
- if (DWord != SK_TEST_VAL) {
- RetVal = 2;
- break;
- }
-
- /* check if the number of GIMacsFound matches SK_MAX_MACS */
- if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
- RetVal = 1;
- break;
- }
-
- /* Level 1 successfully passed */
- pAC->GIni.GILevel = SK_INIT_IO;
- break;
-
- case SK_INIT_RUN:
- /* Initialization Level 2 */
- if (pAC->GIni.GILevel != SK_INIT_IO) {
-#ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
-#endif /* !SK_DIAG */
- RetVal = 4;
- break;
- }
- SkGeInit2(pAC, IoC);
-
- /* Level 2 successfully passed */
- pAC->GIni.GILevel = SK_INIT_RUN;
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
- RetVal = 3;
- break;
- }
-
- return(RetVal);
-} /* SkGeInit */
-
-
-/******************************************************************************
- *
- * SkGeDeInit() - Deinitialize the adapter
- *
- * Description:
- * All ports of the adapter will be stopped if not already done.
- * Do a software reset and switch off all LEDs.
- *
- * Returns:
- * nothing
- */
-void SkGeDeInit(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC) /* IO context */
-{
- int i;
- SK_U16 Word;
-
-#if (!defined(SK_SLIM) && !defined(VCPU))
- /* ensure I2C is ready */
- SkI2cWaitIrq(pAC, IoC);
-#endif
-
- /* stop all current transfer activity */
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
- if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
- pAC->GIni.GP[i].PState != SK_PRT_RESET) {
-
- SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
- }
- }
-
- /* Reset all bits in the PCI STATUS register */
- /*
- * Note: PCI Cfg cycles cannot be used, because they are not
- * available on some platforms after 'boot time'.
- */
- SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-
- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
- /* do the reset, all LEDs are switched off now */
- SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-
- pAC->GIni.GILevel = SK_INIT_DATA;
-} /* SkGeDeInit */
-
-
-/******************************************************************************
- *
- * SkGeInitPort() Initialize the specified port.
- *
- * Description:
- * PRxQSize, PXSQSize, and PXAQSize has to be
- * configured for the specified port before calling this function.
- * The descriptor rings has to be initialized too.
- *
- * o (Re)configure queues of the specified port.
- * o configure the MAC of the specified port.
- * o put ASIC and MAC(s) in operational mode.
- * o initialize Rx/Tx and Sync LED
- * o initialize RAM Buffers and MAC FIFOs
- *
- * The port is ready to connect when returning.
- *
- * Note:
- * The MAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- * 0: success
- * 1: Queue size initialization error. The configured values
- * for PRxQSize, PXSQSize, or PXAQSize are invalid for one
- * or more queues. The specified port was NOT initialized.
- * An error log entry was generated.
- * 2: The port has to be stopped before it can be initialized again.
- */
-int SkGeInitPort(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port to configure */
-{
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (SkGeCheckQSize(pAC, Port) != 0) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
- return(1);
- }
-
- if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
- return(2);
- }
-
- /* configuration ok, initialize the Port now */
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* initialize Rx, Tx and Link LED */
- /*
- * If 1000BT Phy needs LED initialization than swap
- * LED and XMAC initialization order
- */
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
- /* The Link LED is initialized by RLMT or Diagnostics itself */
-
- SkXmInitMac(pAC, IoC, Port);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- SkGmInitMac(pAC, IoC, Port);
- }
-#endif /* YUKON */
-
- /* do NOT initialize the Link Sync Counter */
-
- SkGeInitMacFifo(pAC, IoC, Port);
-
- SkGeInitRamBufs(pAC, IoC, Port);
-
- if (pPrt->PXSQSize != 0) {
- /* enable Force Sync bit if synchronous queue available */
- SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
- }
-
- SkGeInitBmu(pAC, IoC, Port);
-
- /* mark port as initialized */
- pPrt->PState = SK_PRT_INIT;
-
- return(0);
-} /* SkGeInitPort */
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
deleted file mode 100644
index 0a6f67a7a395..000000000000
--- a/drivers/net/sk98lin/skgemib.c
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*****************************************************************************
- *
- * Name: skgemib.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.11 $
- * Date: $Date: 2003/09/15 13:38:12 $
- * Purpose: Private Network Management Interface Management Database
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * PRIVATE OID handler function prototypes
- */
-PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
- SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
- SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int* pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-
-#ifdef SK_POWER_MGMT
-PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-#endif /* SK_POWER_MGMT */
-
-#ifdef SK_DIAG_SUPPORT
-PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance,
- unsigned int TableIndex, SK_U32 NetIndex);
-#endif /* SK_DIAG_SUPPORT */
-
-
-/* defines *******************************************************************/
-#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
-
-
-/* global variables **********************************************************/
-
-/*
- * Table to correlate OID with handler function and index to
- * hardware register stored in StatAddress if applicable.
- */
-PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
- {OID_GEN_XMIT_OK,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
- {OID_GEN_RCV_OK,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
- {OID_GEN_XMIT_ERROR,
- 0,
- 0,
- 0,
- SK_PNMI_RO, General, 0},
- {OID_GEN_RCV_ERROR,
- 0,
- 0,
- 0,
- SK_PNMI_RO, General, 0},
- {OID_GEN_RCV_NO_BUFFER,
- 0,
- 0,
- 0,
- SK_PNMI_RO, General, 0},
- {OID_GEN_DIRECTED_FRAMES_XMIT,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
- {OID_GEN_MULTICAST_FRAMES_XMIT,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
- {OID_GEN_BROADCAST_FRAMES_XMIT,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
- {OID_GEN_DIRECTED_FRAMES_RCV,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
- {OID_GEN_MULTICAST_FRAMES_RCV,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
- {OID_GEN_BROADCAST_FRAMES_RCV,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
- {OID_GEN_RCV_CRC_ERROR,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
- {OID_GEN_TRANSMIT_QUEUE_LENGTH,
- 0,
- 0,
- 0,
- SK_PNMI_RO, General, 0},
- {OID_802_3_PERMANENT_ADDRESS,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, 0},
- {OID_802_3_CURRENT_ADDRESS,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, 0},
- {OID_802_3_RCV_ERROR_ALIGNMENT,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
- {OID_802_3_XMIT_ONE_COLLISION,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
- {OID_802_3_XMIT_MORE_COLLISIONS,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
- {OID_802_3_XMIT_DEFERRED,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
- {OID_802_3_XMIT_MAX_COLLISIONS,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
- {OID_802_3_RCV_OVERRUN,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
- {OID_802_3_XMIT_UNDERRUN,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
- {OID_802_3_XMIT_TIMES_CRS_LOST,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
- {OID_802_3_XMIT_LATE_COLLISIONS,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
-#ifdef SK_POWER_MGMT
- {OID_PNP_CAPABILITIES,
- 0,
- 0,
- 0,
- SK_PNMI_RO, PowerManagement, 0},
- {OID_PNP_SET_POWER,
- 0,
- 0,
- 0,
- SK_PNMI_WO, PowerManagement, 0},
- {OID_PNP_QUERY_POWER,
- 0,
- 0,
- 0,
- SK_PNMI_RO, PowerManagement, 0},
- {OID_PNP_ADD_WAKE_UP_PATTERN,
- 0,
- 0,
- 0,
- SK_PNMI_WO, PowerManagement, 0},
- {OID_PNP_REMOVE_WAKE_UP_PATTERN,
- 0,
- 0,
- 0,
- SK_PNMI_WO, PowerManagement, 0},
- {OID_PNP_ENABLE_WAKE_UP,
- 0,
- 0,
- 0,
- SK_PNMI_RW, PowerManagement, 0},
-#endif /* SK_POWER_MGMT */
-#ifdef SK_DIAG_SUPPORT
- {OID_SKGE_DIAG_MODE,
- 0,
- 0,
- 0,
- SK_PNMI_RW, DiagActions, 0},
-#endif /* SK_DIAG_SUPPORT */
- {OID_SKGE_MDB_VERSION,
- 1,
- 0,
- SK_PNMI_MAI_OFF(MgmtDBVersion),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_SUPPORTED_LIST,
- 0,
- 0,
- 0,
- SK_PNMI_RO, General, 0},
- {OID_SKGE_ALL_DATA,
- 0,
- 0,
- 0,
- SK_PNMI_RW, OidStruct, 0},
- {OID_SKGE_VPD_FREE_BYTES,
- 1,
- 0,
- SK_PNMI_MAI_OFF(VpdFreeBytes),
- SK_PNMI_RO, Vpd, 0},
- {OID_SKGE_VPD_ENTRIES_LIST,
- 1,
- 0,
- SK_PNMI_MAI_OFF(VpdEntriesList),
- SK_PNMI_RO, Vpd, 0},
- {OID_SKGE_VPD_ENTRIES_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(VpdEntriesNumber),
- SK_PNMI_RO, Vpd, 0},
- {OID_SKGE_VPD_KEY,
- SK_PNMI_VPD_ENTRIES,
- sizeof(SK_PNMI_VPD),
- SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
- SK_PNMI_RO, Vpd, 0},
- {OID_SKGE_VPD_VALUE,
- SK_PNMI_VPD_ENTRIES,
- sizeof(SK_PNMI_VPD),
- SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
- SK_PNMI_RO, Vpd, 0},
- {OID_SKGE_VPD_ACCESS,
- SK_PNMI_VPD_ENTRIES,
- sizeof(SK_PNMI_VPD),
- SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
- SK_PNMI_RO, Vpd, 0},
- {OID_SKGE_VPD_ACTION,
- SK_PNMI_VPD_ENTRIES,
- sizeof(SK_PNMI_VPD),
- SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
- SK_PNMI_RW, Vpd, 0},
- {OID_SKGE_PORT_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(PortNumber),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_DEVICE_TYPE,
- 1,
- 0,
- SK_PNMI_MAI_OFF(DeviceType),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_DRIVER_DESCR,
- 1,
- 0,
- SK_PNMI_MAI_OFF(DriverDescr),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_DRIVER_VERSION,
- 1,
- 0,
- SK_PNMI_MAI_OFF(DriverVersion),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_DRIVER_RELDATE,
- 1,
- 0,
- SK_PNMI_MAI_OFF(DriverReleaseDate),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_DRIVER_FILENAME,
- 1,
- 0,
- SK_PNMI_MAI_OFF(DriverFileName),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_HW_DESCR,
- 1,
- 0,
- SK_PNMI_MAI_OFF(HwDescr),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_HW_VERSION,
- 1,
- 0,
- SK_PNMI_MAI_OFF(HwVersion),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_CHIPSET,
- 1,
- 0,
- SK_PNMI_MAI_OFF(Chipset),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_CHIPID,
- 1,
- 0,
- SK_PNMI_MAI_OFF(ChipId),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RAMSIZE,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RamSize),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_VAUXAVAIL,
- 1,
- 0,
- SK_PNMI_MAI_OFF(VauxAvail),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_ACTION,
- 1,
- 0,
- SK_PNMI_MAI_OFF(Action),
- SK_PNMI_RW, Perform, 0},
- {OID_SKGE_RESULT,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TestResult),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_BUS_TYPE,
- 1,
- 0,
- SK_PNMI_MAI_OFF(BusType),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_BUS_SPEED,
- 1,
- 0,
- SK_PNMI_MAI_OFF(BusSpeed),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_BUS_WIDTH,
- 1,
- 0,
- SK_PNMI_MAI_OFF(BusWidth),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_SW_QUEUE_LEN,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxSwQueueLen),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_SW_QUEUE_MAX,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxSwQueueMax),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_RETRY,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxRetryCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RX_INTR_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RxIntrCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_INTR_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxIntrCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RX_NO_BUF_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RxNoBufCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_NO_BUF_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxNoBufCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_USED_DESCR_NO,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxUsedDescrNo),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RX_DELIVERED_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RxDeliveredCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RX_OCTETS_DELIV_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RX_HW_ERROR_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RxHwErrorsCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TX_HW_ERROR_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TxHwErrorsCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_IN_ERRORS_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(InErrorsCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_OUT_ERROR_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(OutErrorsCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_ERR_RECOVERY_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(ErrRecoveryCts),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_SYSUPTIME,
- 1,
- 0,
- SK_PNMI_MAI_OFF(SysUpTime),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_SENSOR_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(SensorNumber),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_SENSOR_INDEX,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_DESCR,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_TYPE,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_VALUE,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_WAR_THRES_LOW,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_WAR_THRES_UPP,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_ERR_THRES_LOW,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_ERR_THRES_UPP,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_STATUS,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_WAR_CTS,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_ERR_CTS,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_WAR_TIME,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_SENSOR_ERR_TIME,
- SK_PNMI_SENSOR_ENTRIES,
- sizeof(SK_PNMI_SENSOR),
- SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
- SK_PNMI_RO, SensorStat, 0},
- {OID_SKGE_CHKSM_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(ChecksumNumber),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_CHKSM_RX_OK_CTS,
- SKCS_NUM_PROTOCOLS,
- sizeof(SK_PNMI_CHECKSUM),
- SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
- SK_PNMI_RO, CsumStat, 0},
- {OID_SKGE_CHKSM_RX_UNABLE_CTS,
- SKCS_NUM_PROTOCOLS,
- sizeof(SK_PNMI_CHECKSUM),
- SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
- SK_PNMI_RO, CsumStat, 0},
- {OID_SKGE_CHKSM_RX_ERR_CTS,
- SKCS_NUM_PROTOCOLS,
- sizeof(SK_PNMI_CHECKSUM),
- SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
- SK_PNMI_RO, CsumStat, 0},
- {OID_SKGE_CHKSM_TX_OK_CTS,
- SKCS_NUM_PROTOCOLS,
- sizeof(SK_PNMI_CHECKSUM),
- SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
- SK_PNMI_RO, CsumStat, 0},
- {OID_SKGE_CHKSM_TX_UNABLE_CTS,
- SKCS_NUM_PROTOCOLS,
- sizeof(SK_PNMI_CHECKSUM),
- SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
- SK_PNMI_RO, CsumStat, 0},
- {OID_SKGE_STAT_TX,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
- {OID_SKGE_STAT_TX_OCTETS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
- {OID_SKGE_STAT_TX_BROADCAST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
- {OID_SKGE_STAT_TX_MULTICAST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
- {OID_SKGE_STAT_TX_UNICAST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
- {OID_SKGE_STAT_TX_LONGFRAMES,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
- {OID_SKGE_STAT_TX_BURST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
- {OID_SKGE_STAT_TX_PFLOWC,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
- {OID_SKGE_STAT_TX_FLOWC,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
- {OID_SKGE_STAT_TX_SINGLE_COL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
- {OID_SKGE_STAT_TX_MULTI_COL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
- {OID_SKGE_STAT_TX_EXCESS_COL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
- {OID_SKGE_STAT_TX_LATE_COL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
- {OID_SKGE_STAT_TX_DEFFERAL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
- {OID_SKGE_STAT_TX_EXCESS_DEF,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
- {OID_SKGE_STAT_TX_UNDERRUN,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
- {OID_SKGE_STAT_TX_CARRIER,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
-/* {OID_SKGE_STAT_TX_UTIL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
- SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
- {OID_SKGE_STAT_TX_64,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
- {OID_SKGE_STAT_TX_127,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
- {OID_SKGE_STAT_TX_255,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
- {OID_SKGE_STAT_TX_511,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
- {OID_SKGE_STAT_TX_1023,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
- {OID_SKGE_STAT_TX_MAX,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
- {OID_SKGE_STAT_TX_SYNC,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
- {OID_SKGE_STAT_TX_SYNC_OCTETS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
- {OID_SKGE_STAT_RX,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
- {OID_SKGE_STAT_RX_OCTETS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
- {OID_SKGE_STAT_RX_BROADCAST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
- {OID_SKGE_STAT_RX_MULTICAST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
- {OID_SKGE_STAT_RX_UNICAST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
- {OID_SKGE_STAT_RX_LONGFRAMES,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
- {OID_SKGE_STAT_RX_PFLOWC,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
- {OID_SKGE_STAT_RX_FLOWC,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
- {OID_SKGE_STAT_RX_PFLOWC_ERR,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
- {OID_SKGE_STAT_RX_FLOWC_UNKWN,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
- {OID_SKGE_STAT_RX_BURST,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
- {OID_SKGE_STAT_RX_MISSED,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
- {OID_SKGE_STAT_RX_FRAMING,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
- {OID_SKGE_STAT_RX_OVERFLOW,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
- {OID_SKGE_STAT_RX_JABBER,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
- {OID_SKGE_STAT_RX_CARRIER,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
- {OID_SKGE_STAT_RX_IR_LENGTH,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
- {OID_SKGE_STAT_RX_SYMBOL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
- {OID_SKGE_STAT_RX_SHORTS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
- {OID_SKGE_STAT_RX_RUNT,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
- {OID_SKGE_STAT_RX_CEXT,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
- {OID_SKGE_STAT_RX_TOO_LONG,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
- {OID_SKGE_STAT_RX_FCS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
-/* {OID_SKGE_STAT_RX_UTIL,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
- SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
- {OID_SKGE_STAT_RX_64,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
- {OID_SKGE_STAT_RX_127,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
- {OID_SKGE_STAT_RX_255,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
- {OID_SKGE_STAT_RX_511,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
- {OID_SKGE_STAT_RX_1023,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
- {OID_SKGE_STAT_RX_MAX,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_STAT),
- SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
- SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
- {OID_SKGE_PHYS_CUR_ADDR,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
- SK_PNMI_RW, Addr, 0},
- {OID_SKGE_PHYS_FAC_ADDR,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
- SK_PNMI_RO, Addr, 0},
- {OID_SKGE_PMD,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_CONNECTOR,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_PHY_TYPE,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_LINK_CAP,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_LINK_MODE,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
- SK_PNMI_RW, MacPrivateConf, 0},
- {OID_SKGE_LINK_MODE_STATUS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_LINK_STATUS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_FLOWCTRL_CAP,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_FLOWCTRL_MODE,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
- SK_PNMI_RW, MacPrivateConf, 0},
- {OID_SKGE_FLOWCTRL_STATUS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_PHY_OPERATION_CAP,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_PHY_OPERATION_MODE,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
- SK_PNMI_RW, MacPrivateConf, 0},
- {OID_SKGE_PHY_OPERATION_STATUS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_SPEED_CAP,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_SPEED_MODE,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
- SK_PNMI_RW, MacPrivateConf, 0},
- {OID_SKGE_SPEED_STATUS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_CONF),
- SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
- SK_PNMI_RO, MacPrivateConf, 0},
- {OID_SKGE_TRAP,
- 1,
- 0,
- SK_PNMI_MAI_OFF(Trap),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_TRAP_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(TrapNumber),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RLMT_MODE,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtMode),
- SK_PNMI_RW, Rlmt, 0},
- {OID_SKGE_RLMT_PORT_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtPortNumber),
- SK_PNMI_RO, Rlmt, 0},
- {OID_SKGE_RLMT_PORT_ACTIVE,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtPortActive),
- SK_PNMI_RO, Rlmt, 0},
- {OID_SKGE_RLMT_PORT_PREFERRED,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtPortPreferred),
- SK_PNMI_RW, Rlmt, 0},
- {OID_SKGE_RLMT_CHANGE_CTS,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtChangeCts),
- SK_PNMI_RO, Rlmt, 0},
- {OID_SKGE_RLMT_CHANGE_TIME,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtChangeTime),
- SK_PNMI_RO, Rlmt, 0},
- {OID_SKGE_RLMT_CHANGE_ESTIM,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtChangeEstimate),
- SK_PNMI_RO, Rlmt, 0},
- {OID_SKGE_RLMT_CHANGE_THRES,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtChangeThreshold),
- SK_PNMI_RW, Rlmt, 0},
- {OID_SKGE_RLMT_PORT_INDEX,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_RLMT),
- SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
- SK_PNMI_RO, RlmtStat, 0},
- {OID_SKGE_RLMT_STATUS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_RLMT),
- SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
- SK_PNMI_RO, RlmtStat, 0},
- {OID_SKGE_RLMT_TX_HELLO_CTS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_RLMT),
- SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
- SK_PNMI_RO, RlmtStat, 0},
- {OID_SKGE_RLMT_RX_HELLO_CTS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_RLMT),
- SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
- SK_PNMI_RO, RlmtStat, 0},
- {OID_SKGE_RLMT_TX_SP_REQ_CTS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_RLMT),
- SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
- SK_PNMI_RO, RlmtStat, 0},
- {OID_SKGE_RLMT_RX_SP_CTS,
- SK_PNMI_MAC_ENTRIES,
- sizeof(SK_PNMI_RLMT),
- SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
- SK_PNMI_RO, RlmtStat, 0},
- {OID_SKGE_RLMT_MONITOR_NUMBER,
- 1,
- 0,
- SK_PNMI_MAI_OFF(RlmtMonitorNumber),
- SK_PNMI_RO, General, 0},
- {OID_SKGE_RLMT_MONITOR_INDEX,
- SK_PNMI_MONITOR_ENTRIES,
- sizeof(SK_PNMI_RLMT_MONITOR),
- SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
- SK_PNMI_RO, Monitor, 0},
- {OID_SKGE_RLMT_MONITOR_ADDR,
- SK_PNMI_MONITOR_ENTRIES,
- sizeof(SK_PNMI_RLMT_MONITOR),
- SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
- SK_PNMI_RO, Monitor, 0},
- {OID_SKGE_RLMT_MONITOR_ERRS,
- SK_PNMI_MONITOR_ENTRIES,
- sizeof(SK_PNMI_RLMT_MONITOR),
- SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
- SK_PNMI_RO, Monitor, 0},
- {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
- SK_PNMI_MONITOR_ENTRIES,
- sizeof(SK_PNMI_RLMT_MONITOR),
- SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
- SK_PNMI_RO, Monitor, 0},
- {OID_SKGE_RLMT_MONITOR_ADMIN,
- SK_PNMI_MONITOR_ENTRIES,
- sizeof(SK_PNMI_RLMT_MONITOR),
- SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
- SK_PNMI_RW, Monitor, 0},
- {OID_SKGE_MTU,
- 1,
- 0,
- SK_PNMI_MAI_OFF(MtuSize),
- SK_PNMI_RW, MacPrivateConf, 0},
- {OID_SKGE_VCT_GET,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Vct, 0},
- {OID_SKGE_VCT_SET,
- 0,
- 0,
- 0,
- SK_PNMI_WO, Vct, 0},
- {OID_SKGE_VCT_STATUS,
- 0,
- 0,
- 0,
- SK_PNMI_RO, Vct, 0},
- {OID_SKGE_BOARDLEVEL,
- 0,
- 0,
- 0,
- SK_PNMI_RO, General, 0},
-};
-
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
deleted file mode 100644
index b36dd9ac6b29..000000000000
--- a/drivers/net/sk98lin/skgepnmi.c
+++ /dev/null
@@ -1,8210 +0,0 @@
-/*****************************************************************************
- *
- * Name: skgepnmi.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.111 $
- * Date: $Date: 2003/09/15 13:35:35 $
- * Purpose: Private Network Management Interface
- *
- ****************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-#ifndef _lint
-static const char SysKonnectFileId[] =
- "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
-#endif /* !_lint */
-
-#include "h/skdrv1st.h"
-#include "h/sktypes.h"
-#include "h/xmac_ii.h"
-#include "h/skdebug.h"
-#include "h/skqueue.h"
-#include "h/skgepnmi.h"
-#include "h/skgesirq.h"
-#include "h/skcsum.h"
-#include "h/skvpd.h"
-#include "h/skgehw.h"
-#include "h/skgeinit.h"
-#include "h/skdrv2nd.h"
-#include "h/skgepnm2.h"
-#ifdef SK_POWER_MGMT
-#include "h/skgepmgt.h"
-#endif
-/* defines *******************************************************************/
-
-#ifndef DEBUG
-#define PNMI_STATIC static
-#else /* DEBUG */
-#define PNMI_STATIC
-#endif /* DEBUG */
-
-/*
- * Public Function prototypes
- */
-int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
-int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
- unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
-int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
- unsigned int * pLen, SK_U32 NetIndex);
-
-
-/*
- * Private Function prototypes
- */
-
-PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
- PhysPortIndex);
-PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
- PhysPortIndex);
-PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
-PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
-PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
- unsigned int PhysPortIndex, unsigned int StatIndex);
-PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
- unsigned int StatIndex, SK_U32 NetIndex);
-PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
-PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
- unsigned int *pEntries);
-PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
- unsigned int KeyArrLen, unsigned int *pKeyNo);
-PNMI_STATIC int LookupId(SK_U32 Id);
-PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
- unsigned int LastMac);
-PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
- unsigned int *pLen, SK_U32 NetIndex);
-PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
- char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
-PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
-PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
- unsigned int PortIndex);
-PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
- unsigned int SensorIndex);
-PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
-PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
-PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
-PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
-PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
- unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
-PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
-
-/*
- * Table to correlate OID with handler function and index to
- * hardware register stored in StatAddress if applicable.
- */
-#include "skgemib.c"
-
-/* global variables **********************************************************/
-
-/*
- * Overflow status register bit table and corresponding counter
- * dependent on MAC type - the number relates to the size of overflow
- * mask returned by the pFnMacOverflow function
- */
-PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
-/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
-/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
-/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
-/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
-/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
-/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
-/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
-/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
-/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
-/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
-/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
-/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
-/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
-/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
-/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
-/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
-/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
-/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
-/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
-/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
-/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
-/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
-/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
-/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
-/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
-/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
-/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
-/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
-/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
-/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
-/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
-/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
-/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
-/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
-/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
-/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
-/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
-/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
-/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
-/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
-/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
-/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
-/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
-/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
-/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
-/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
-/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
-/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
-/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
-/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
-/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
-/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
-/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
-/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
-/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
-/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
-/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
-/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
-/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
-/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
-/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
-/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
-/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
-/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
-};
-
-/*
- * Table for hardware register saving on resets and port switches
- */
-PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
- /* SK_PNMI_HTX */
- {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_OCTETHIGH */
- {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
- /* SK_PNMI_HTX_OCTETLOW */
- {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
- /* SK_PNMI_HTX_BROADCAST */
- {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
- /* SK_PNMI_HTX_MULTICAST */
- {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
- /* SK_PNMI_HTX_UNICAST */
- {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
- /* SK_PNMI_HTX_BURST */
- {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_PMACC */
- {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
- /* SK_PNMI_HTX_MACC */
- {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_COL */
- {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
- /* SK_PNMI_HTX_SINGLE_COL */
- {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
- /* SK_PNMI_HTX_MULTI_COL */
- {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
- /* SK_PNMI_HTX_EXCESS_COL */
- {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
- /* SK_PNMI_HTX_LATE_COL */
- {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
- /* SK_PNMI_HTX_DEFFERAL */
- {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_EXCESS_DEF */
- {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_UNDERRUN */
- {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
- /* SK_PNMI_HTX_CARRIER */
- {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_UTILUNDER */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_UTILOVER */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_64 */
- {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
- /* SK_PNMI_HTX_127 */
- {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
- /* SK_PNMI_HTX_255 */
- {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
- /* SK_PNMI_HTX_511 */
- {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
- /* SK_PNMI_HTX_1023 */
- {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
- /* SK_PNMI_HTX_MAX */
- {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
- /* SK_PNMI_HTX_LONGFRAMES */
- {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
- /* SK_PNMI_HTX_SYNC */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_SYNC_OCTET */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HTX_RESERVED */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX */
- {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_OCTETHIGH */
- {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
- /* SK_PNMI_HRX_OCTETLOW */
- {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
- /* SK_PNMI_HRX_BADOCTETHIGH */
- {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
- /* SK_PNMI_HRX_BADOCTETLOW */
- {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
- /* SK_PNMI_HRX_BROADCAST */
- {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
- /* SK_PNMI_HRX_MULTICAST */
- {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
- /* SK_PNMI_HRX_UNICAST */
- {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
- /* SK_PNMI_HRX_PMACC */
- {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
- /* SK_PNMI_HRX_MACC */
- {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_PMACC_ERR */
- {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_MACC_UNKWN */
- {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_BURST */
- {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_MISSED */
- {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_FRAMING */
- {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_UNDERSIZE */
- {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
- /* SK_PNMI_HRX_OVERFLOW */
- {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
- /* SK_PNMI_HRX_JABBER */
- {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
- /* SK_PNMI_HRX_CARRIER */
- {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_IRLENGTH */
- {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_SYMBOL */
- {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_SHORTS */
- {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_RUNT */
- {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
- /* SK_PNMI_HRX_TOO_LONG */
- {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
- /* SK_PNMI_HRX_FCS */
- {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
- /* SK_PNMI_HRX_CEXT */
- {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_UTILUNDER */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_UTILOVER */
- {{0, SK_FALSE}, {0, SK_FALSE}},
- /* SK_PNMI_HRX_64 */
- {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
- /* SK_PNMI_HRX_127 */
- {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
- /* SK_PNMI_HRX_255 */
- {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
- /* SK_PNMI_HRX_511 */
- {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
- /* SK_PNMI_HRX_1023 */
- {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
- /* SK_PNMI_HRX_MAX */
- {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
- /* SK_PNMI_HRX_LONGFRAMES */
- {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
- /* SK_PNMI_HRX_RESERVED */
- {{0, SK_FALSE}, {0, SK_FALSE}}
-};
-
-
-/*****************************************************************************
- *
- * Public functions
- *
- */
-
-/*****************************************************************************
- *
- * SkPnmiInit - Init function of PNMI
- *
- * Description:
- * SK_INIT_DATA: Initialises the data structures
- * SK_INIT_IO: Resets the XMAC statistics, determines the device and
- * connector type.
- * SK_INIT_RUN: Starts a timer event for port switch per hour
- * calculation.
- *
- * Returns:
- * Always 0
- */
-int SkPnmiInit(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Level) /* Initialization level */
-{
- unsigned int PortMax; /* Number of ports */
- unsigned int PortIndex; /* Current port index in loop */
- SK_U16 Val16; /* Multiple purpose 16 bit variable */
- SK_U8 Val8; /* Mulitple purpose 8 bit variable */
- SK_EVPARA EventParam; /* Event struct for timer event */
- SK_PNMI_VCT *pVctBackupData;
-
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
-
- switch (Level) {
-
- case SK_INIT_DATA:
- SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
- pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
- pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
- pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
- for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
-
- pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
- pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
- }
-
-#ifdef SK_PNMI_CHECK
- if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
- ("CounterOffset struct size (%d) differs from"
- "SK_PNMI_MAX_IDX (%d)\n",
- SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
- }
-
- if (SK_PNMI_MAX_IDX !=
- (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
- ("StatAddr table size (%d) differs from "
- "SK_PNMI_MAX_IDX (%d)\n",
- (sizeof(StatAddr) /
- (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
- SK_PNMI_MAX_IDX));
- }
-#endif /* SK_PNMI_CHECK */
- break;
-
- case SK_INIT_IO:
- /*
- * Reset MAC counters
- */
- PortMax = pAC->GIni.GIMacsFound;
-
- for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
-
- pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
- }
-
- /* Initialize DSP variables for Vct() to 0xff => Never written! */
- for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
- pAC->GIni.GP[PortIndex].PCableLen = 0xff;
- pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
- pVctBackupData->PCableLen = 0xff;
- }
-
- /*
- * Get pci bus speed
- */
- SK_IN16(IoC, B0_CTST, &Val16);
- if ((Val16 & CS_BUS_CLOCK) == 0) {
-
- pAC->Pnmi.PciBusSpeed = 33;
- }
- else {
- pAC->Pnmi.PciBusSpeed = 66;
- }
-
- /*
- * Get pci bus width
- */
- SK_IN16(IoC, B0_CTST, &Val16);
- if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
-
- pAC->Pnmi.PciBusWidth = 32;
- }
- else {
- pAC->Pnmi.PciBusWidth = 64;
- }
-
- /*
- * Get chipset
- */
- switch (pAC->GIni.GIChipId) {
- case CHIP_ID_GENESIS:
- pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
- break;
-
- case CHIP_ID_YUKON:
- pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
- break;
-
- default:
- break;
- }
-
- /*
- * Get PMD and DeviceType
- */
- SK_IN8(IoC, B2_PMD_TYP, &Val8);
- switch (Val8) {
- case 'S':
- pAC->Pnmi.PMD = 3;
- if (pAC->GIni.GIMacsFound > 1) {
-
- pAC->Pnmi.DeviceType = 0x00020002;
- }
- else {
- pAC->Pnmi.DeviceType = 0x00020001;
- }
- break;
-
- case 'L':
- pAC->Pnmi.PMD = 2;
- if (pAC->GIni.GIMacsFound > 1) {
-
- pAC->Pnmi.DeviceType = 0x00020004;
- }
- else {
- pAC->Pnmi.DeviceType = 0x00020003;
- }
- break;
-
- case 'C':
- pAC->Pnmi.PMD = 4;
- if (pAC->GIni.GIMacsFound > 1) {
-
- pAC->Pnmi.DeviceType = 0x00020006;
- }
- else {
- pAC->Pnmi.DeviceType = 0x00020005;
- }
- break;
-
- case 'T':
- pAC->Pnmi.PMD = 5;
- if (pAC->GIni.GIMacsFound > 1) {
-
- pAC->Pnmi.DeviceType = 0x00020008;
- }
- else {
- pAC->Pnmi.DeviceType = 0x00020007;
- }
- break;
-
- default :
- pAC->Pnmi.PMD = 1;
- pAC->Pnmi.DeviceType = 0;
- break;
- }
-
- /*
- * Get connector
- */
- SK_IN8(IoC, B2_CONN_TYP, &Val8);
- switch (Val8) {
- case 'C':
- pAC->Pnmi.Connector = 2;
- break;
-
- case 'D':
- pAC->Pnmi.Connector = 3;
- break;
-
- case 'F':
- pAC->Pnmi.Connector = 4;
- break;
-
- case 'J':
- pAC->Pnmi.Connector = 5;
- break;
-
- case 'V':
- pAC->Pnmi.Connector = 6;
- break;
-
- default:
- pAC->Pnmi.Connector = 1;
- break;
- }
- break;
-
- case SK_INIT_RUN:
- /*
- * Start timer for RLMT change counter
- */
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
- SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
- 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
- EventParam);
- break;
-
- default:
- break; /* Nothing todo */
- }
-
- return (0);
-}
-
-/*****************************************************************************
- *
- * SkPnmiGetVar - Retrieves the value of a single OID
- *
- * Description:
- * Calls a general sub-function for all this stuff. If the instance
- * -1 is passed, the values of all instances are returned in an
- * array of values.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed
- * SK_PNMI_ERR_GENERAL A general severe internal error occured
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
- * the data.
- * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-static int SkPnmiGetVar(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 Id, /* Object ID that is to be processed */
-void *pBuf, /* Buffer to which the management data will be copied */
-unsigned int *pLen, /* On call: buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
- Id, *pLen, Instance, NetIndex));
-
- return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
- Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiPreSetVar - Presets the value of a single OID
- *
- * Description:
- * Calls a general sub-function for all this stuff. The preset does
- * the same as a set, but returns just before finally setting the
- * new value. This is useful to check if a set might be successfull.
- * If the instance -1 is passed, an array of values is supposed and
- * all instances of the OID will be set.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-static int SkPnmiPreSetVar(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 Id, /* Object ID that is to be processed */
-void *pBuf, /* Buffer to which the management data will be copied */
-unsigned int *pLen, /* Total length of management data */
-SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
- Id, *pLen, Instance, NetIndex));
-
-
- return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
- Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiSetVar - Sets the value of a single OID
- *
- * Description:
- * Calls a general sub-function for all this stuff. The preset does
- * the same as a set, but returns just before finally setting the
- * new value. This is useful to check if a set might be successfull.
- * If the instance -1 is passed, an array of values is supposed and
- * all instances of the OID will be set.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-int SkPnmiSetVar(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 Id, /* Object ID that is to be processed */
-void *pBuf, /* Buffer to which the management data will be copied */
-unsigned int *pLen, /* Total length of management data */
-SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
- Id, *pLen, Instance, NetIndex));
-
- return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
- Instance, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- * Runs through the IdTable, queries the single OIDs and stores the
- * returned data into the management database structure
- * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
- * is stored in the IdTable. The return value of the function will also
- * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
- * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed
- * SK_PNMI_ERR_GENERAL A general severe internal error occured
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
- * the data.
- * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
- */
-int SkPnmiGetStruct(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-void *pBuf, /* Buffer to which the management data will be copied. */
-unsigned int *pLen, /* Length of buffer */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- unsigned int TableIndex;
- unsigned int DstOffset;
- unsigned int InstanceNo;
- unsigned int InstanceCnt;
- SK_U32 Instance;
- unsigned int TmpLen;
- char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
-
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
- *pLen, NetIndex));
-
- if (*pLen < SK_PNMI_STRUCT_SIZE) {
-
- if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
-
- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
- (SK_U32)(-1));
- }
-
- *pLen = SK_PNMI_STRUCT_SIZE;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * Check NetIndex
- */
- if (NetIndex >= pAC->Rlmt.NumNets) {
- return (SK_PNMI_ERR_UNKNOWN_NET);
- }
-
- /* Update statistic */
- SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
-
- if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
- SK_PNMI_ERR_OK) {
-
- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (Ret);
- }
-
- if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (Ret);
- }
-
- if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (Ret);
- }
-
- /*
- * Increment semaphores to indicate that an update was
- * already done
- */
- pAC->Pnmi.MacUpdatedFlag ++;
- pAC->Pnmi.RlmtUpdatedFlag ++;
- pAC->Pnmi.SirqUpdatedFlag ++;
-
- /* Get vpd keys for instance calculation */
- Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
- if (Ret != SK_PNMI_ERR_OK) {
-
- pAC->Pnmi.MacUpdatedFlag --;
- pAC->Pnmi.RlmtUpdatedFlag --;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /* Retrieve values */
- SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
- for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
-
- InstanceNo = IdTable[TableIndex].InstanceNo;
- for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
- InstanceCnt ++) {
-
- DstOffset = IdTable[TableIndex].Offset +
- (InstanceCnt - 1) *
- IdTable[TableIndex].StructSize;
-
- /*
- * For the VPD the instance is not an index number
- * but the key itself. Determin with the instance
- * counter the VPD key to be used.
- */
- if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
- IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
- IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
- IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
-
- SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
- }
- else {
- Instance = (SK_U32)InstanceCnt;
- }
-
- TmpLen = *pLen - DstOffset;
- Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
- IdTable[TableIndex].Id, (char *)pBuf +
- DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
-
- /*
- * An unknown instance error means that we reached
- * the last instance of that variable. Proceed with
- * the next OID in the table and ignore the return
- * code.
- */
- if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
-
- break;
- }
-
- if (Ret != SK_PNMI_ERR_OK) {
-
- pAC->Pnmi.MacUpdatedFlag --;
- pAC->Pnmi.RlmtUpdatedFlag --;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
- SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (Ret);
- }
- }
- }
-
- pAC->Pnmi.MacUpdatedFlag --;
- pAC->Pnmi.RlmtUpdatedFlag --;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- *pLen = SK_PNMI_STRUCT_SIZE;
- SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- * Calls a general sub-function for all this set stuff. The preset does
- * the same as a set, but returns just before finally setting the
- * new value. This is useful to check if a set might be successfull.
- * The sub-function runs through the IdTable, checks which OIDs are able
- * to set, and calls the handler function of the OID to perform the
- * preset. The return value of the function will also be stored in
- * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- * SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- */
-int SkPnmiPreSetStruct(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-void *pBuf, /* Buffer which contains the data to be set */
-unsigned int *pLen, /* Length of buffer */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
- *pLen, NetIndex));
-
- return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
- pLen, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
- *
- * Description:
- * Calls a general sub-function for all this set stuff. The return value
- * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
- * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
- * The sub-function runs through the IdTable, checks which OIDs are able
- * to set, and calls the handler function of the OID to perform the
- * set. The return value of the function will also be stored in
- * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- * SK_PNMI_MIN_STRUCT_SIZE.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- */
-int SkPnmiSetStruct(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-void *pBuf, /* Buffer which contains the data to be set */
-unsigned int *pLen, /* Length of buffer */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
- *pLen, NetIndex));
-
- return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
- pLen, NetIndex));
-}
-
-/*****************************************************************************
- *
- * SkPnmiEvent - Event handler
- *
- * Description:
- * Handles the following events:
- * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
- * interrupt will be generated which is
- * first handled by SIRQ which generates a
- * this event. The event increments the
- * upper 32 bit of the 64 bit counter.
- * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
- * when a sensor reports a warning or
- * error. The event will store a trap
- * message in the trap buffer.
- * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
- * module and is used to calculate the
- * port switches per hour.
- * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
- * timestamps.
- * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
- * before a hard reset of the XMAC is
- * performed. All counters will be saved
- * and added to the hardware counter
- * values after reset to grant continuous
- * counter values.
- * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
- * went logically up. A trap message will
- * be stored to the trap buffer.
- * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
- * went logically down. A trap message will
- * be stored to the trap buffer.
- * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
- * spanning tree root bridges were
- * detected. A trap message will be stored
- * to the trap buffer.
- * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
- * down. PNMI will not further add the
- * statistic values to the virtual port.
- * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
- * is now an active port. PNMI will now
- * add the statistic data of this port to
- * the virtual port.
- * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
- * contains the number of nets. 1 means single net, 2 means
- * dual net. The second parameter is -1
- *
- * Returns:
- * Always 0
- */
-int SkPnmiEvent(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 Event, /* Event-Id */
-SK_EVPARA Param) /* Event dependent parameter */
-{
- unsigned int PhysPortIndex;
- unsigned int MaxNetNumber;
- int CounterIndex;
- int Ret;
- SK_U16 MacStatus;
- SK_U64 OverflowStatus;
- SK_U64 Mask;
- int MacType;
- SK_U64 Value;
- SK_U32 Val32;
- SK_U16 Register;
- SK_EVPARA EventParam;
- SK_U64 NewestValue;
- SK_U64 OldestValue;
- SK_U64 Delta;
- SK_PNMI_ESTIMATE *pEst;
- SK_U32 NetIndex;
- SK_GEPORT *pPrt;
- SK_PNMI_VCT *pVctBackupData;
- SK_U32 RetCode;
- int i;
- SK_U32 CableLength;
-
-
-#ifdef DEBUG
- if (Event != SK_PNMI_EVT_XMAC_RESET) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
- (unsigned int)Event, (unsigned int)Param.Para64));
- }
-#endif /* DEBUG */
- SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
-
- MacType = pAC->GIni.GIMacType;
-
- switch (Event) {
-
- case SK_PNMI_EVT_SIRQ_OVERFLOW:
- PhysPortIndex = (int)Param.Para32[0];
- MacStatus = (SK_U16)Param.Para32[1];
-#ifdef DEBUG
- if (PhysPortIndex >= SK_MAX_MACS) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
- " wrong, PhysPortIndex=0x%x\n",
- PhysPortIndex));
- return (0);
- }
-#endif /* DEBUG */
- OverflowStatus = 0;
-
- /*
- * Check which source caused an overflow interrupt.
- */
- if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
- MacStatus, &OverflowStatus) != 0) ||
- (OverflowStatus == 0)) {
-
- SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
- return (0);
- }
-
- /*
- * Check the overflow status register and increment
- * the upper dword of corresponding counter.
- */
- for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
- CounterIndex ++) {
-
- Mask = (SK_U64)1 << CounterIndex;
- if ((OverflowStatus & Mask) == 0) {
-
- continue;
- }
-
- switch (StatOvrflwBit[CounterIndex][MacType]) {
-
- case SK_PNMI_HTX_UTILUNDER:
- case SK_PNMI_HTX_UTILOVER:
- if (MacType == SK_MAC_XMAC) {
- XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
- Register |= XM_TX_SAM_LINE;
- XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
- }
- break;
-
- case SK_PNMI_HRX_UTILUNDER:
- case SK_PNMI_HRX_UTILOVER:
- if (MacType == SK_MAC_XMAC) {
- XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
- Register |= XM_RX_SAM_LINE;
- XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
- }
- break;
-
- case SK_PNMI_HTX_OCTETHIGH:
- case SK_PNMI_HTX_OCTETLOW:
- case SK_PNMI_HTX_RESERVED:
- case SK_PNMI_HRX_OCTETHIGH:
- case SK_PNMI_HRX_OCTETLOW:
- case SK_PNMI_HRX_IRLENGTH:
- case SK_PNMI_HRX_RESERVED:
-
- /*
- * the following counters aren't be handled (id > 63)
- */
- case SK_PNMI_HTX_SYNC:
- case SK_PNMI_HTX_SYNC_OCTET:
- break;
-
- case SK_PNMI_HRX_LONGFRAMES:
- if (MacType == SK_MAC_GMAC) {
- pAC->Pnmi.Port[PhysPortIndex].
- CounterHigh[CounterIndex] ++;
- }
- break;
-
- default:
- pAC->Pnmi.Port[PhysPortIndex].
- CounterHigh[CounterIndex] ++;
- }
- }
- break;
-
- case SK_PNMI_EVT_SEN_WAR_LOW:
-#ifdef DEBUG
- if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
- (unsigned int)Param.Para64));
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Store a trap message in the trap buffer and generate
- * an event for user space applications with the
- * SK_DRIVER_SENDEVENT macro.
- */
- QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
- (unsigned int)Param.Para64);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
- break;
-
- case SK_PNMI_EVT_SEN_WAR_UPP:
-#ifdef DEBUG
- if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
- (unsigned int)Param.Para64));
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Store a trap message in the trap buffer and generate
- * an event for user space applications with the
- * SK_DRIVER_SENDEVENT macro.
- */
- QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
- (unsigned int)Param.Para64);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
- break;
-
- case SK_PNMI_EVT_SEN_ERR_LOW:
-#ifdef DEBUG
- if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
- (unsigned int)Param.Para64));
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Store a trap message in the trap buffer and generate
- * an event for user space applications with the
- * SK_DRIVER_SENDEVENT macro.
- */
- QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
- (unsigned int)Param.Para64);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
- break;
-
- case SK_PNMI_EVT_SEN_ERR_UPP:
-#ifdef DEBUG
- if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
- (unsigned int)Param.Para64));
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Store a trap message in the trap buffer and generate
- * an event for user space applications with the
- * SK_DRIVER_SENDEVENT macro.
- */
- QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
- (unsigned int)Param.Para64);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
- break;
-
- case SK_PNMI_EVT_CHG_EST_TIMER:
- /*
- * Calculate port switch average on a per hour basis
- * Time interval for check : 28125 ms
- * Number of values for average : 8
- *
- * Be careful in changing these values, on change check
- * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
- * array one less than value number)
- * - Timer initialization SkTimerStart() in SkPnmiInit
- * - Delta value below must be multiplicated with
- * power of 2
- *
- */
- pEst = &pAC->Pnmi.RlmtChangeEstimate;
- CounterIndex = pEst->EstValueIndex + 1;
- if (CounterIndex == 7) {
-
- CounterIndex = 0;
- }
- pEst->EstValueIndex = CounterIndex;
-
- NewestValue = pAC->Pnmi.RlmtChangeCts;
- OldestValue = pEst->EstValue[CounterIndex];
- pEst->EstValue[CounterIndex] = NewestValue;
-
- /*
- * Calculate average. Delta stores the number of
- * port switches per 28125 * 8 = 225000 ms
- */
- if (NewestValue >= OldestValue) {
-
- Delta = NewestValue - OldestValue;
- }
- else {
- /* Overflow situation */
- Delta = (SK_U64)(0 - OldestValue) + NewestValue;
- }
-
- /*
- * Extrapolate delta to port switches per hour.
- * Estimate = Delta * (3600000 / 225000)
- * = Delta * 16
- * = Delta << 4
- */
- pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
-
- /*
- * Check if threshold is exceeded. If the threshold is
- * permanently exceeded every 28125 ms an event will be
- * generated to remind the user of this condition.
- */
- if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
- (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
- pAC->Pnmi.RlmtChangeThreshold)) {
-
- QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
- }
-
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
- SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
- 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
- EventParam);
- break;
-
- case SK_PNMI_EVT_CLEAR_COUNTER:
- /*
- * Param.Para32[0] contains the NetIndex (0 ..1).
- * Param.Para32[1] is reserved, contains -1.
- */
- NetIndex = (SK_U32)Param.Para32[0];
-
-#ifdef DEBUG
- if (NetIndex >= pAC->Rlmt.NumNets) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
- NetIndex));
-
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Set all counters and timestamps to zero.
- * The according NetIndex is required as a
- * parameter of the event.
- */
- ResetCounter(pAC, IoC, NetIndex);
- break;
-
- case SK_PNMI_EVT_XMAC_RESET:
- /*
- * To grant continuous counter values store the current
- * XMAC statistic values to the entries 1..n of the
- * CounterOffset array. XMAC Errata #2
- */
-#ifdef DEBUG
- if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
- (unsigned int)Param.Para64));
- return (0);
- }
-#endif
- PhysPortIndex = (unsigned int)Param.Para64;
-
- /*
- * Update XMAC statistic to get fresh values
- */
- Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
- if (Ret != SK_PNMI_ERR_OK) {
-
- SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
- return (0);
- }
- /*
- * Increment semaphore to indicate that an update was
- * already done
- */
- pAC->Pnmi.MacUpdatedFlag ++;
-
- for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
- CounterIndex ++) {
-
- if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
- continue;
- }
-
- pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
- GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
- pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
- }
-
- pAC->Pnmi.MacUpdatedFlag --;
- break;
-
- case SK_PNMI_EVT_RLMT_PORT_UP:
- PhysPortIndex = (unsigned int)Param.Para32[0];
-#ifdef DEBUG
- if (PhysPortIndex >= SK_MAX_MACS) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
- " wrong, PhysPortIndex=%d\n", PhysPortIndex));
-
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Store a trap message in the trap buffer and generate an event for
- * user space applications with the SK_DRIVER_SENDEVENT macro.
- */
- QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
- /* Bugfix for XMAC errata (#10620)*/
- if (MacType == SK_MAC_XMAC) {
- /* Add incremental difference to offset (#10620)*/
- (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
- XM_RXE_SHT_ERR, &Val32);
-
- Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
- CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
- pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
- Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
- }
-
- /* Tell VctStatus() that a link was up meanwhile. */
- pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
- break;
-
- case SK_PNMI_EVT_RLMT_PORT_DOWN:
- PhysPortIndex = (unsigned int)Param.Para32[0];
-
-#ifdef DEBUG
- if (PhysPortIndex >= SK_MAX_MACS) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
- " wrong, PhysPortIndex=%d\n", PhysPortIndex));
-
- return (0);
- }
-#endif /* DEBUG */
-
- /*
- * Store a trap message in the trap buffer and generate an event for
- * user space applications with the SK_DRIVER_SENDEVENT macro.
- */
- QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
- /* Bugfix #10620 - get zero level for incremental difference */
- if (MacType == SK_MAC_XMAC) {
-
- (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
- XM_RXE_SHT_ERR, &Val32);
-
- pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
- (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
- CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
- }
- break;
-
- case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
- PhysPortIndex = (unsigned int)Param.Para32[0];
- NetIndex = (SK_U32)Param.Para32[1];
-
-#ifdef DEBUG
- if (PhysPortIndex >= SK_MAX_MACS) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
- PhysPortIndex));
- }
-
- if (NetIndex >= pAC->Rlmt.NumNets) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
- NetIndex));
- }
-#endif /* DEBUG */
-
- /*
- * For now, ignore event if NetIndex != 0.
- */
- if (Param.Para32[1] != 0) {
-
- return (0);
- }
-
- /*
- * Nothing to do if port is already inactive
- */
- if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- return (0);
- }
-
- /*
- * Update statistic counters to calculate new offset for the virtual
- * port and increment semaphore to indicate that an update was already
- * done.
- */
- if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
- SK_PNMI_ERR_OK) {
-
- SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
- return (0);
- }
- pAC->Pnmi.MacUpdatedFlag ++;
-
- /*
- * Calculate new counter offset for virtual port to grant continous
- * counting on port switches. The virtual port consists of all currently
- * active ports. The port down event indicates that a port is removed
- * from the virtual port. Therefore add the counter value of the removed
- * port to the CounterOffset for the virtual port to grant the same
- * counter value.
- */
- for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
- CounterIndex ++) {
-
- if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
- continue;
- }
-
- Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
- pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
- }
-
- /*
- * Set port to inactive
- */
- pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
-
- pAC->Pnmi.MacUpdatedFlag --;
- break;
-
- case SK_PNMI_EVT_RLMT_ACTIVE_UP:
- PhysPortIndex = (unsigned int)Param.Para32[0];
- NetIndex = (SK_U32)Param.Para32[1];
-
-#ifdef DEBUG
- if (PhysPortIndex >= SK_MAX_MACS) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
- PhysPortIndex));
- }
-
- if (NetIndex >= pAC->Rlmt.NumNets) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
- NetIndex));
- }
-#endif /* DEBUG */
-
- /*
- * For now, ignore event if NetIndex != 0.
- */
- if (Param.Para32[1] != 0) {
-
- return (0);
- }
-
- /*
- * Nothing to do if port is already active
- */
- if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- return (0);
- }
-
- /*
- * Statistic maintenance
- */
- pAC->Pnmi.RlmtChangeCts ++;
- pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
-
- /*
- * Store a trap message in the trap buffer and generate an event for
- * user space applications with the SK_DRIVER_SENDEVENT macro.
- */
- QueueRlmtNewMacTrap(pAC, PhysPortIndex);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
-
- /*
- * Update statistic counters to calculate new offset for the virtual
- * port and increment semaphore to indicate that an update was
- * already done.
- */
- if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
- SK_PNMI_ERR_OK) {
-
- SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
- return (0);
- }
- pAC->Pnmi.MacUpdatedFlag ++;
-
- /*
- * Calculate new counter offset for virtual port to grant continous
- * counting on port switches. A new port is added to the virtual port.
- * Therefore substract the counter value of the new port from the
- * CounterOffset for the virtual port to grant the same value.
- */
- for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
- CounterIndex ++) {
-
- if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
- continue;
- }
-
- Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
-
- pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
- }
-
- /* Set port to active */
- pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
-
- pAC->Pnmi.MacUpdatedFlag --;
- break;
-
- case SK_PNMI_EVT_RLMT_SEGMENTATION:
- /*
- * Para.Para32[0] contains the NetIndex.
- */
-
- /*
- * Store a trap message in the trap buffer and generate an event for
- * user space applications with the SK_DRIVER_SENDEVENT macro.
- */
- QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
- (void)SK_DRIVER_SENDEVENT(pAC, IoC);
- break;
-
- case SK_PNMI_EVT_RLMT_SET_NETS:
- /*
- * Param.Para32[0] contains the number of Nets.
- * Param.Para32[1] is reserved, contains -1.
- */
- /*
- * Check number of nets
- */
- MaxNetNumber = pAC->GIni.GIMacsFound;
- if (((unsigned int)Param.Para32[0] < 1)
- || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
- return (SK_PNMI_ERR_UNKNOWN_NET);
- }
-
- if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
- pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
- }
- else { /* dual net mode */
- pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
- }
- break;
-
- case SK_PNMI_EVT_VCT_RESET:
- PhysPortIndex = Param.Para32[0];
- pPrt = &pAC->GIni.GP[PhysPortIndex];
- pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-
- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
- RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
- if (RetCode == 2) {
- /*
- * VCT test is still running.
- * Start VCT timer counter again.
- */
- SK_MEMSET((char *) &Param, 0, sizeof(Param));
- Param.Para32[0] = PhysPortIndex;
- Param.Para32[1] = -1;
- SkTimerStart(pAC, IoC,
- &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
- 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
- break;
- }
- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
- pAC->Pnmi.VctStatus[PhysPortIndex] |=
- (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
-
- /* Copy results for later use to PNMI struct. */
- for (i = 0; i < 4; i++) {
- if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
- if ((pPrt->PMdiPairLen[i] > 35) &&
- (pPrt->PMdiPairLen[i] < 0xff)) {
- pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
- }
- }
- if ((pPrt->PMdiPairLen[i] > 35) &&
- (pPrt->PMdiPairLen[i] != 0xff)) {
- CableLength = 1000 *
- (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
- }
- else {
- CableLength = 0;
- }
- pVctBackupData->PMdiPairLen[i] = CableLength;
- pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
- }
-
- Param.Para32[0] = PhysPortIndex;
- Param.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
- SkEventDispatcher(pAC, IoC);
- }
-
- break;
-
- default:
- break;
- }
-
- SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
- return (0);
-}
-
-
-/******************************************************************************
- *
- * Private functions
- *
- */
-
-/*****************************************************************************
- *
- * PnmiVar - Gets, presets, and sets single OIDs
- *
- * Description:
- * Looks up the requested OID, calls the corresponding handler
- * function, and passes the parameters with the get, preset, or
- * set command. The function is called by SkGePnmiGetVar,
- * SkGePnmiPreSetVar, or SkGePnmiSetVar.
- *
- * Returns:
- * SK_PNMI_ERR_XXX. For details have a look at the description of the
- * calling functions.
- * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
- */
-PNMI_STATIC int PnmiVar(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* Total length of pBuf management data */
-SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int TableIndex;
- int Ret;
-
-
- if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_OID);
- }
-
- /* Check NetIndex */
- if (NetIndex >= pAC->Rlmt.NumNets) {
- return (SK_PNMI_ERR_UNKNOWN_NET);
- }
-
- SK_PNMI_CHECKFLAGS("PnmiVar: On call");
-
- Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
- Instance, TableIndex, NetIndex);
-
- SK_PNMI_CHECKFLAGS("PnmiVar: On return");
-
- return (Ret);
-}
-
-/*****************************************************************************
- *
- * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
- *
- * Description:
- * The return value of the function will also be stored in
- * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
- * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
- * checks which OIDs are able to set, and calls the handler function of
- * the OID to perform the set. The return value of the function will
- * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
- * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
- * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
- *
- * Returns:
- * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
- * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
- */
-PNMI_STATIC int PnmiStruct(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* PRESET/SET action to be performed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* Length of pBuf management data buffer */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- unsigned int TableIndex;
- unsigned int DstOffset;
- unsigned int Len;
- unsigned int InstanceNo;
- unsigned int InstanceCnt;
- SK_U32 Instance;
- SK_U32 Id;
-
-
- /* Check if the passed buffer has the right size */
- if (*pLen < SK_PNMI_STRUCT_SIZE) {
-
- /* Check if we can return the error within the buffer */
- if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
-
- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
- (SK_U32)(-1));
- }
-
- *pLen = SK_PNMI_STRUCT_SIZE;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /* Check NetIndex */
- if (NetIndex >= pAC->Rlmt.NumNets) {
- return (SK_PNMI_ERR_UNKNOWN_NET);
- }
-
- SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
-
- /*
- * Update the values of RLMT and SIRQ and increment semaphores to
- * indicate that an update was already done.
- */
- if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (Ret);
- }
-
- if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (Ret);
- }
-
- pAC->Pnmi.RlmtUpdatedFlag ++;
- pAC->Pnmi.SirqUpdatedFlag ++;
-
- /* Preset/Set values */
- for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
-
- if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
- (IdTable[TableIndex].Access != SK_PNMI_WO)) {
-
- continue;
- }
-
- InstanceNo = IdTable[TableIndex].InstanceNo;
- Id = IdTable[TableIndex].Id;
-
- for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
- InstanceCnt ++) {
-
- DstOffset = IdTable[TableIndex].Offset +
- (InstanceCnt - 1) *
- IdTable[TableIndex].StructSize;
-
- /*
- * Because VPD multiple instance variables are
- * not setable we do not need to evaluate VPD
- * instances. Have a look to VPD instance
- * calculation in SkPnmiGetStruct().
- */
- Instance = (SK_U32)InstanceCnt;
-
- /*
- * Evaluate needed buffer length
- */
- Len = 0;
- Ret = IdTable[TableIndex].Func(pAC, IoC,
- SK_PNMI_GET, IdTable[TableIndex].Id,
- NULL, &Len, Instance, TableIndex, NetIndex);
-
- if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
-
- break;
- }
- if (Ret != SK_PNMI_ERR_TOO_SHORT) {
-
- pAC->Pnmi.RlmtUpdatedFlag --;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
- SK_PNMI_SET_STAT(pBuf,
- SK_PNMI_ERR_GENERAL, DstOffset);
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (SK_PNMI_ERR_GENERAL);
- }
- if (Id == OID_SKGE_VPD_ACTION) {
-
- switch (*(pBuf + DstOffset)) {
-
- case SK_PNMI_VPD_CREATE:
- Len = 3 + *(pBuf + DstOffset + 3);
- break;
-
- case SK_PNMI_VPD_DELETE:
- Len = 3;
- break;
-
- default:
- Len = 1;
- break;
- }
- }
-
- /* Call the OID handler function */
- Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
- IdTable[TableIndex].Id, pBuf + DstOffset,
- &Len, Instance, TableIndex, NetIndex);
-
- if (Ret != SK_PNMI_ERR_OK) {
-
- pAC->Pnmi.RlmtUpdatedFlag --;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
- DstOffset);
- *pLen = SK_PNMI_MIN_STRUCT_SIZE;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- }
- }
-
- pAC->Pnmi.RlmtUpdatedFlag --;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * LookupId - Lookup an OID in the IdTable
- *
- * Description:
- * Scans the IdTable to find the table entry of an OID.
- *
- * Returns:
- * The table index or -1 if not found.
- */
-PNMI_STATIC int LookupId(
-SK_U32 Id) /* Object identifier to be searched */
-{
- int i;
-
- for (i = 0; i < ID_TABLE_SIZE; i++) {
-
- if (IdTable[i].Id == Id) {
-
- return i;
- }
- }
-
- return (-1);
-}
-
-/*****************************************************************************
- *
- * OidStruct - Handler of OID_SKGE_ALL_DATA
- *
- * Description:
- * This OID performs a Get/Preset/SetStruct call and returns all data
- * in a SK_PNMI_STRUCT_DATA structure.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int OidStruct(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- if (Id != OID_SKGE_ALL_DATA) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
- SK_PNMI_ERR003MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * Check instance. We only handle single instance variables
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- switch (Action) {
-
- case SK_PNMI_GET:
- return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-
- case SK_PNMI_PRESET:
- return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
-
- case SK_PNMI_SET:
- return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
- }
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
-}
-
-/*****************************************************************************
- *
- * Perform - OID handler of OID_SKGE_ACTION
- *
- * Description:
- * None.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int Perform(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- SK_U32 ActionOp;
-
-
- /*
- * Check instance. We only handle single instance variables
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /* Check if a get should be performed */
- if (Action == SK_PNMI_GET) {
-
- /* A get is easy. We always return the same value */
- ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
- SK_PNMI_STORE_U32(pBuf, ActionOp);
- *pLen = sizeof(SK_U32);
-
- return (SK_PNMI_ERR_OK);
- }
-
- /* Continue with PRESET/SET action */
- if (*pLen > sizeof(SK_U32)) {
-
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* Check if the command is a known one */
- SK_PNMI_READ_U32(pBuf, ActionOp);
- if (*pLen > sizeof(SK_U32) ||
- (ActionOp != SK_PNMI_ACT_IDLE &&
- ActionOp != SK_PNMI_ACT_RESET &&
- ActionOp != SK_PNMI_ACT_SELFTEST &&
- ActionOp != SK_PNMI_ACT_RESETCNT)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* A preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- switch (ActionOp) {
-
- case SK_PNMI_ACT_IDLE:
- /* Nothing to do */
- break;
-
- case SK_PNMI_ACT_RESET:
- /*
- * Perform a driver reset or something that comes near
- * to this.
- */
- Ret = SK_DRIVER_RESET(pAC, IoC);
- if (Ret != 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
- SK_PNMI_ERR005MSG);
-
- return (SK_PNMI_ERR_GENERAL);
- }
- break;
-
- case SK_PNMI_ACT_SELFTEST:
- /*
- * Perform a driver selftest or something similar to this.
- * Currently this feature is not used and will probably
- * implemented in another way.
- */
- Ret = SK_DRIVER_SELFTEST(pAC, IoC);
- pAC->Pnmi.TestResult = Ret;
- break;
-
- case SK_PNMI_ACT_RESETCNT:
- /* Set all counters and timestamps to zero */
- ResetCounter(pAC, IoC, NetIndex);
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
- SK_PNMI_ERR006MSG);
-
- return (SK_PNMI_ERR_GENERAL);
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
- *
- * Description:
- * Retrieves the statistic values of the virtual port (logical
- * index 0). Only special OIDs of NDIS are handled which consist
- * of a 32 bit instead of a 64 bit value. The OIDs are public
- * because perhaps some other platform can use them too.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int Mac8023Stat(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- SK_U64 StatVal;
- SK_U32 StatVal32;
- SK_BOOL Is64BitReq = SK_FALSE;
-
- /*
- * Only the active Mac is returned
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- /*
- * Check action type
- */
- if (Action != SK_PNMI_GET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /* Check length */
- switch (Id) {
-
- case OID_802_3_PERMANENT_ADDRESS:
- case OID_802_3_CURRENT_ADDRESS:
- if (*pLen < sizeof(SK_MAC_ADDR)) {
-
- *pLen = sizeof(SK_MAC_ADDR);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
-#ifndef SK_NDIS_64BIT_CTR
- if (*pLen < sizeof(SK_U32)) {
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
-#else /* SK_NDIS_64BIT_CTR */
-
- /* for compatibility, at least 32bit are required for OID */
- if (*pLen < sizeof(SK_U32)) {
- /*
- * but indicate handling for 64bit values,
- * if insufficient space is provided
- */
- *pLen = sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
-#endif /* SK_NDIS_64BIT_CTR */
- break;
- }
-
- /*
- * Update all statistics, because we retrieve virtual MAC, which
- * consists of multiple physical statistics and increment semaphore
- * to indicate that an update was already done.
- */
- Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
- if ( Ret != SK_PNMI_ERR_OK) {
-
- *pLen = 0;
- return (Ret);
- }
- pAC->Pnmi.MacUpdatedFlag ++;
-
- /*
- * Get value (MAC Index 0 identifies the virtual MAC)
- */
- switch (Id) {
-
- case OID_802_3_PERMANENT_ADDRESS:
- CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
- *pLen = sizeof(SK_MAC_ADDR);
- break;
-
- case OID_802_3_CURRENT_ADDRESS:
- CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
- *pLen = sizeof(SK_MAC_ADDR);
- break;
-
- default:
- StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
-
- /* by default 32bit values are evaluated */
- if (!Is64BitReq) {
- StatVal32 = (SK_U32)StatVal;
- SK_PNMI_STORE_U32(pBuf, StatVal32);
- *pLen = sizeof(SK_U32);
- }
- else {
- SK_PNMI_STORE_U64(pBuf, StatVal);
- *pLen = sizeof(SK_U64);
- }
- break;
- }
-
- pAC->Pnmi.MacUpdatedFlag --;
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
- *
- * Description:
- * Retrieves the MAC statistic data.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int MacPrivateStat(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int LogPortMax;
- unsigned int LogPortIndex;
- unsigned int PhysPortMax;
- unsigned int Limit;
- unsigned int Offset;
- int MacType;
- int Ret;
- SK_U64 StatVal;
-
-
-
- /* Calculate instance if wished. MAC index 0 is the virtual MAC */
- PhysPortMax = pAC->GIni.GIMacsFound;
- LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
- MacType = pAC->GIni.GIMacType;
-
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
- LogPortMax--;
- }
-
- if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
- /* Check instance range */
- if ((Instance < 1) || (Instance > LogPortMax)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
- LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
- Limit = LogPortIndex + 1;
- }
-
- else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
- LogPortIndex = 0;
- Limit = LogPortMax;
- }
-
- /* Check action */
- if (Action != SK_PNMI_GET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /* Check length */
- if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
-
- *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * Update MAC statistic and increment semaphore to indicate that
- * an update was already done.
- */
- Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
- if (Ret != SK_PNMI_ERR_OK) {
-
- *pLen = 0;
- return (Ret);
- }
- pAC->Pnmi.MacUpdatedFlag ++;
-
- /* Get value */
- Offset = 0;
- for (; LogPortIndex < Limit; LogPortIndex ++) {
-
- switch (Id) {
-
-/* XXX not yet implemented due to XMAC problems
- case OID_SKGE_STAT_TX_UTIL:
- return (SK_PNMI_ERR_GENERAL);
-*/
-/* XXX not yet implemented due to XMAC problems
- case OID_SKGE_STAT_RX_UTIL:
- return (SK_PNMI_ERR_GENERAL);
-*/
- case OID_SKGE_STAT_RX:
- if (MacType == SK_MAC_GMAC) {
- StatVal =
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HRX_BROADCAST, NetIndex) +
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HRX_MULTICAST, NetIndex) +
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HRX_UNICAST, NetIndex) +
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HRX_UNDERSIZE, NetIndex);
- }
- else {
- StatVal = GetStatVal(pAC, IoC, LogPortIndex,
- IdTable[TableIndex].Param, NetIndex);
- }
- break;
-
- case OID_SKGE_STAT_TX:
- if (MacType == SK_MAC_GMAC) {
- StatVal =
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HTX_BROADCAST, NetIndex) +
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HTX_MULTICAST, NetIndex) +
- GetStatVal(pAC, IoC, LogPortIndex,
- SK_PNMI_HTX_UNICAST, NetIndex);
- }
- else {
- StatVal = GetStatVal(pAC, IoC, LogPortIndex,
- IdTable[TableIndex].Param, NetIndex);
- }
- break;
-
- default:
- StatVal = GetStatVal(pAC, IoC, LogPortIndex,
- IdTable[TableIndex].Param, NetIndex);
- }
- SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
-
- Offset += sizeof(SK_U64);
- }
- *pLen = Offset;
-
- pAC->Pnmi.MacUpdatedFlag --;
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
- *
- * Description:
- * Get/Presets/Sets the current and factory MAC address. The MAC
- * address of the virtual port, which is reported to the OS, may
- * not be changed, but the physical ones. A set to the virtual port
- * will be ignored. No error should be reported because otherwise
- * a multiple instance set (-1) would always fail.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int Addr(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- unsigned int LogPortMax;
- unsigned int PhysPortMax;
- unsigned int LogPortIndex;
- unsigned int PhysPortIndex;
- unsigned int Limit;
- unsigned int Offset = 0;
-
- /*
- * Calculate instance if wished. MAC index 0 is the virtual
- * MAC.
- */
- PhysPortMax = pAC->GIni.GIMacsFound;
- LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
- LogPortMax--;
- }
-
- if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
- /* Check instance range */
- if ((Instance < 1) || (Instance > LogPortMax)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
- LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
- Limit = LogPortIndex + 1;
- }
- else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
- LogPortIndex = 0;
- Limit = LogPortMax;
- }
-
- /*
- * Perform Action
- */
- if (Action == SK_PNMI_GET) {
-
- /* Check length */
- if (*pLen < (Limit - LogPortIndex) * 6) {
-
- *pLen = (Limit - LogPortIndex) * 6;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * Get value
- */
- for (; LogPortIndex < Limit; LogPortIndex ++) {
-
- switch (Id) {
-
- case OID_SKGE_PHYS_CUR_ADDR:
- if (LogPortIndex == 0) {
- CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
- }
- else {
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-
- CopyMac(pBuf + Offset,
- &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
- }
- Offset += 6;
- break;
-
- case OID_SKGE_PHYS_FAC_ADDR:
- if (LogPortIndex == 0) {
- CopyMac(pBuf + Offset,
- &pAC->Addr.Net[NetIndex].PermanentMacAddress);
- }
- else {
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- CopyMac(pBuf + Offset,
- &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
- }
- Offset += 6;
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
- SK_PNMI_ERR008MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
-
- *pLen = Offset;
- }
- else {
- /*
- * The logical MAC address may not be changed only
- * the physical ones
- */
- if (Id == OID_SKGE_PHYS_FAC_ADDR) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /*
- * Only the current address may be changed
- */
- if (Id != OID_SKGE_PHYS_CUR_ADDR) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
- SK_PNMI_ERR009MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /* Check length */
- if (*pLen < (Limit - LogPortIndex) * 6) {
-
- *pLen = (Limit - LogPortIndex) * 6;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- if (*pLen > (Limit - LogPortIndex) * 6) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /*
- * Check Action
- */
- if (Action == SK_PNMI_PRESET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_OK);
- }
-
- /*
- * Set OID_SKGE_MAC_CUR_ADDR
- */
- for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
-
- /*
- * A set to virtual port and set of broadcast
- * address will be ignored
- */
- if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
- "\xff\xff\xff\xff\xff\xff", 6) == 0) {
-
- continue;
- }
-
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
- LogPortIndex);
-
- Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
- (SK_MAC_ADDR *)(pBuf + Offset),
- (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
- SK_ADDR_PHYSICAL_ADDRESS));
- if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
-
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- *pLen = Offset;
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
- *
- * Description:
- * Retrieves the statistic values of the CSUM module. The CSUM data
- * structure must be available in the SK_AC even if the CSUM module
- * is not included, because PNMI reads the statistic data from the
- * CSUM part of SK_AC directly.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int CsumStat(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int Index;
- unsigned int Limit;
- unsigned int Offset = 0;
- SK_U64 StatVal;
-
-
- /*
- * Calculate instance if wished
- */
- if (Instance != (SK_U32)(-1)) {
-
- if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
- Index = (unsigned int)Instance - 1;
- Limit = Index + 1;
- }
- else {
- Index = 0;
- Limit = SKCS_NUM_PROTOCOLS;
- }
-
- /*
- * Check action
- */
- if (Action != SK_PNMI_GET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /* Check length */
- if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
-
- *pLen = (Limit - Index) * sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * Get value
- */
- for (; Index < Limit; Index ++) {
-
- switch (Id) {
-
- case OID_SKGE_CHKSM_RX_OK_CTS:
- StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
- break;
-
- case OID_SKGE_CHKSM_RX_UNABLE_CTS:
- StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
- break;
-
- case OID_SKGE_CHKSM_RX_ERR_CTS:
- StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
- break;
-
- case OID_SKGE_CHKSM_TX_OK_CTS:
- StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
- break;
-
- case OID_SKGE_CHKSM_TX_UNABLE_CTS:
- StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
- SK_PNMI_ERR010MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
- Offset += sizeof(SK_U64);
- }
-
- /*
- * Store used buffer space
- */
- *pLen = Offset;
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
- *
- * Description:
- * Retrieves the statistic values of the I2C module, which handles
- * the temperature and voltage sensors.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int SensorStat(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int i;
- unsigned int Index;
- unsigned int Limit;
- unsigned int Offset;
- unsigned int Len;
- SK_U32 Val32;
- SK_U64 Val64;
-
-
- /*
- * Calculate instance if wished
- */
- if ((Instance != (SK_U32)(-1))) {
-
- if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- Index = (unsigned int)Instance -1;
- Limit = (unsigned int)Instance;
- }
- else {
- Index = 0;
- Limit = (unsigned int) pAC->I2c.MaxSens;
- }
-
- /*
- * Check action
- */
- if (Action != SK_PNMI_GET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /* Check length */
- switch (Id) {
-
- case OID_SKGE_SENSOR_VALUE:
- case OID_SKGE_SENSOR_WAR_THRES_LOW:
- case OID_SKGE_SENSOR_WAR_THRES_UPP:
- case OID_SKGE_SENSOR_ERR_THRES_LOW:
- case OID_SKGE_SENSOR_ERR_THRES_UPP:
- if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
-
- *pLen = (Limit - Index) * sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_SENSOR_DESCR:
- for (Offset = 0, i = Index; i < Limit; i ++) {
-
- Len = (unsigned int)
- SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
- if (Len >= SK_PNMI_STRINGLEN2) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
- SK_PNMI_ERR011MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- Offset += Len;
- }
- if (*pLen < Offset) {
-
- *pLen = Offset;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_SENSOR_INDEX:
- case OID_SKGE_SENSOR_TYPE:
- case OID_SKGE_SENSOR_STATUS:
- if (*pLen < Limit - Index) {
-
- *pLen = Limit - Index;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_SENSOR_WAR_CTS:
- case OID_SKGE_SENSOR_WAR_TIME:
- case OID_SKGE_SENSOR_ERR_CTS:
- case OID_SKGE_SENSOR_ERR_TIME:
- if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
-
- *pLen = (Limit - Index) * sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
- SK_PNMI_ERR012MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
-
- }
-
- /*
- * Get value
- */
- for (Offset = 0; Index < Limit; Index ++) {
-
- switch (Id) {
-
- case OID_SKGE_SENSOR_INDEX:
- *(pBuf + Offset) = (char)Index;
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SENSOR_DESCR:
- Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
- SK_MEMCPY(pBuf + Offset + 1,
- pAC->I2c.SenTable[Index].SenDesc, Len);
- *(pBuf + Offset) = (char)Len;
- Offset += Len + 1;
- break;
-
- case OID_SKGE_SENSOR_TYPE:
- *(pBuf + Offset) =
- (char)pAC->I2c.SenTable[Index].SenType;
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SENSOR_VALUE:
- Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_SENSOR_WAR_THRES_LOW:
- Val32 = (SK_U32)pAC->I2c.SenTable[Index].
- SenThreWarnLow;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_SENSOR_WAR_THRES_UPP:
- Val32 = (SK_U32)pAC->I2c.SenTable[Index].
- SenThreWarnHigh;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_SENSOR_ERR_THRES_LOW:
- Val32 = (SK_U32)pAC->I2c.SenTable[Index].
- SenThreErrLow;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_SENSOR_ERR_THRES_UPP:
- Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_SENSOR_STATUS:
- *(pBuf + Offset) =
- (char)pAC->I2c.SenTable[Index].SenErrFlag;
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SENSOR_WAR_CTS:
- Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- case OID_SKGE_SENSOR_ERR_CTS:
- Val64 = pAC->I2c.SenTable[Index].SenErrCts;
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- case OID_SKGE_SENSOR_WAR_TIME:
- Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
- SenBegWarnTS);
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- case OID_SKGE_SENSOR_ERR_TIME:
- Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
- SenBegErrTS);
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- default:
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
- ("SensorStat: Unknown OID should be handled before"));
-
- return (SK_PNMI_ERR_GENERAL);
- }
- }
-
- /*
- * Store used buffer space
- */
- *pLen = Offset;
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Vpd - OID handler function of OID_SKGE_VPD_XXX
- *
- * Description:
- * Get/preset/set of VPD data. As instance the name of a VPD key
- * can be passed. The Instance parameter is a SK_U32 and can be
- * used as a string buffer for the VPD key, because their maximum
- * length is 4 byte.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int Vpd(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_VPD_STATUS *pVpdStatus;
- unsigned int BufLen;
- char Buf[256];
- char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
- char KeyStr[SK_PNMI_VPD_KEY_SIZE];
- unsigned int KeyNo;
- unsigned int Offset;
- unsigned int Index;
- unsigned int FirstIndex;
- unsigned int LastIndex;
- unsigned int Len;
- int Ret;
- SK_U32 Val32;
-
- /*
- * Get array of all currently stored VPD keys
- */
- Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
- if (Ret != SK_PNMI_ERR_OK) {
- *pLen = 0;
- return (Ret);
- }
-
- /*
- * If instance is not -1, try to find the requested VPD key for
- * the multiple instance variables. The other OIDs as for example
- * OID VPD_ACTION are single instance variables and must be
- * handled separatly.
- */
- FirstIndex = 0;
- LastIndex = KeyNo;
-
- if ((Instance != (SK_U32)(-1))) {
-
- if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
- Id == OID_SKGE_VPD_ACCESS) {
-
- SK_STRNCPY(KeyStr, (char *)&Instance, 4);
- KeyStr[4] = 0;
-
- for (Index = 0; Index < KeyNo; Index ++) {
-
- if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
- FirstIndex = Index;
- LastIndex = Index+1;
- break;
- }
- }
- if (Index == KeyNo) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
- }
- else if (Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
- }
-
- /*
- * Get value, if a query should be performed
- */
- if (Action == SK_PNMI_GET) {
-
- switch (Id) {
-
- case OID_SKGE_VPD_FREE_BYTES:
- /* Check length of buffer */
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- /* Get number of free bytes */
- pVpdStatus = VpdStat(pAC, IoC);
- if (pVpdStatus == NULL) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
- SK_PNMI_ERR017MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
- SK_PNMI_ERR018MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_VPD_ENTRIES_LIST:
- /* Check length */
- for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
-
- Len += SK_STRLEN(KeyArr[Index]) + 1;
- }
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /* Get value */
- *(pBuf) = (char)Len - 1;
- for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
-
- Len = SK_STRLEN(KeyArr[Index]);
- SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
-
- Offset += Len;
-
- if (Index < KeyNo - 1) {
-
- *(pBuf + Offset) = ' ';
- Offset ++;
- }
- }
- *pLen = Offset;
- break;
-
- case OID_SKGE_VPD_ENTRIES_NUMBER:
- /* Check length */
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- Val32 = (SK_U32)KeyNo;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_VPD_KEY:
- /* Check buffer length, if it is large enough */
- for (Len = 0, Index = FirstIndex;
- Index < LastIndex; Index ++) {
-
- Len += SK_STRLEN(KeyArr[Index]) + 1;
- }
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * Get the key to an intermediate buffer, because
- * we have to prepend a length byte.
- */
- for (Offset = 0, Index = FirstIndex;
- Index < LastIndex; Index ++) {
-
- Len = SK_STRLEN(KeyArr[Index]);
-
- *(pBuf + Offset) = (char)Len;
- SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
- Len);
- Offset += Len + 1;
- }
- *pLen = Offset;
- break;
-
- case OID_SKGE_VPD_VALUE:
- /* Check the buffer length if it is large enough */
- for (Offset = 0, Index = FirstIndex;
- Index < LastIndex; Index ++) {
-
- BufLen = 256;
- if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
- (int *)&BufLen) > 0 ||
- BufLen >= SK_PNMI_VPD_DATALEN) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR021,
- SK_PNMI_ERR021MSG);
-
- return (SK_PNMI_ERR_GENERAL);
- }
- Offset += BufLen + 1;
- }
- if (*pLen < Offset) {
-
- *pLen = Offset;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * Get the value to an intermediate buffer, because
- * we have to prepend a length byte.
- */
- for (Offset = 0, Index = FirstIndex;
- Index < LastIndex; Index ++) {
-
- BufLen = 256;
- if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
- (int *)&BufLen) > 0 ||
- BufLen >= SK_PNMI_VPD_DATALEN) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR022,
- SK_PNMI_ERR022MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- *(pBuf + Offset) = (char)BufLen;
- SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
- Offset += BufLen + 1;
- }
- *pLen = Offset;
- break;
-
- case OID_SKGE_VPD_ACCESS:
- if (*pLen < LastIndex - FirstIndex) {
-
- *pLen = LastIndex - FirstIndex;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- for (Offset = 0, Index = FirstIndex;
- Index < LastIndex; Index ++) {
-
- if (VpdMayWrite(KeyArr[Index])) {
-
- *(pBuf + Offset) = SK_PNMI_VPD_RW;
- }
- else {
- *(pBuf + Offset) = SK_PNMI_VPD_RO;
- }
- Offset ++;
- }
- *pLen = Offset;
- break;
-
- case OID_SKGE_VPD_ACTION:
- Offset = LastIndex - FirstIndex;
- if (*pLen < Offset) {
-
- *pLen = Offset;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- SK_MEMSET(pBuf, 0, Offset);
- *pLen = Offset;
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
- SK_PNMI_ERR023MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- else {
- /* The only OID which can be set is VPD_ACTION */
- if (Id != OID_SKGE_VPD_ACTION) {
-
- if (Id == OID_SKGE_VPD_FREE_BYTES ||
- Id == OID_SKGE_VPD_ENTRIES_LIST ||
- Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
- Id == OID_SKGE_VPD_KEY ||
- Id == OID_SKGE_VPD_VALUE ||
- Id == OID_SKGE_VPD_ACCESS) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
- SK_PNMI_ERR024MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * From this point we handle VPD_ACTION. Check the buffer
- * length. It should at least have the size of one byte.
- */
- if (*pLen < 1) {
-
- *pLen = 1;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- /*
- * The first byte contains the VPD action type we should
- * perform.
- */
- switch (*pBuf) {
-
- case SK_PNMI_VPD_IGNORE:
- /* Nothing to do */
- break;
-
- case SK_PNMI_VPD_CREATE:
- /*
- * We have to create a new VPD entry or we modify
- * an existing one. Check first the buffer length.
- */
- if (*pLen < 4) {
-
- *pLen = 4;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- KeyStr[0] = pBuf[1];
- KeyStr[1] = pBuf[2];
- KeyStr[2] = 0;
-
- /*
- * Is the entry writable or does it belong to the
- * read-only area?
- */
- if (!VpdMayWrite(KeyStr)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- Offset = (int)pBuf[3] & 0xFF;
-
- SK_MEMCPY(Buf, pBuf + 4, Offset);
- Buf[Offset] = 0;
-
- /* A preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- /* Write the new entry or modify an existing one */
- Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
- if (Ret == SK_PNMI_VPD_NOWRITE ) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- else if (Ret != SK_PNMI_VPD_OK) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
- SK_PNMI_ERR025MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * Perform an update of the VPD data. This is
- * not mandantory, but just to be sure.
- */
- Ret = VpdUpdate(pAC, IoC);
- if (Ret != SK_PNMI_VPD_OK) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
- SK_PNMI_ERR026MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- break;
-
- case SK_PNMI_VPD_DELETE:
- /* Check if the buffer size is plausible */
- if (*pLen < 3) {
-
- *pLen = 3;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- if (*pLen > 3) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- KeyStr[0] = pBuf[1];
- KeyStr[1] = pBuf[2];
- KeyStr[2] = 0;
-
- /* Find the passed key in the array */
- for (Index = 0; Index < KeyNo; Index ++) {
-
- if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
-
- break;
- }
- }
- /*
- * If we cannot find the key it is wrong, so we
- * return an appropriate error value.
- */
- if (Index == KeyNo) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- /* Ok, you wanted it and you will get it */
- Ret = VpdDelete(pAC, IoC, KeyStr);
- if (Ret != SK_PNMI_VPD_OK) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
- SK_PNMI_ERR027MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * Perform an update of the VPD data. This is
- * not mandantory, but just to be sure.
- */
- Ret = VpdUpdate(pAC, IoC);
- if (Ret != SK_PNMI_VPD_OK) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
- SK_PNMI_ERR028MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- break;
-
- default:
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * General - OID handler function of various single instance OIDs
- *
- * Description:
- * The code is simple. No description necessary.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int General(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- unsigned int Index;
- unsigned int Len;
- unsigned int Offset;
- unsigned int Val;
- SK_U8 Val8;
- SK_U16 Val16;
- SK_U32 Val32;
- SK_U64 Val64;
- SK_U64 Val64RxHwErrs = 0;
- SK_U64 Val64TxHwErrs = 0;
- SK_BOOL Is64BitReq = SK_FALSE;
- char Buf[256];
- int MacType;
-
- /*
- * Check instance. We only handle single instance variables.
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- /*
- * Check action. We only allow get requests.
- */
- if (Action != SK_PNMI_GET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- MacType = pAC->GIni.GIMacType;
-
- /*
- * Check length for the various supported OIDs
- */
- switch (Id) {
-
- case OID_GEN_XMIT_ERROR:
- case OID_GEN_RCV_ERROR:
- case OID_GEN_RCV_NO_BUFFER:
-#ifndef SK_NDIS_64BIT_CTR
- if (*pLen < sizeof(SK_U32)) {
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
-#else /* SK_NDIS_64BIT_CTR */
-
- /*
- * for compatibility, at least 32bit are required for oid
- */
- if (*pLen < sizeof(SK_U32)) {
- /*
- * but indicate handling for 64bit values,
- * if insufficient space is provided
- */
- *pLen = sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
-
- Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
-#endif /* SK_NDIS_64BIT_CTR */
- break;
-
- case OID_SKGE_PORT_NUMBER:
- case OID_SKGE_DEVICE_TYPE:
- case OID_SKGE_RESULT:
- case OID_SKGE_RLMT_MONITOR_NUMBER:
- case OID_GEN_TRANSMIT_QUEUE_LENGTH:
- case OID_SKGE_TRAP_NUMBER:
- case OID_SKGE_MDB_VERSION:
- case OID_SKGE_BOARDLEVEL:
- case OID_SKGE_CHIPID:
- case OID_SKGE_RAMSIZE:
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_CHIPSET:
- if (*pLen < sizeof(SK_U16)) {
-
- *pLen = sizeof(SK_U16);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_BUS_TYPE:
- case OID_SKGE_BUS_SPEED:
- case OID_SKGE_BUS_WIDTH:
- case OID_SKGE_SENSOR_NUMBER:
- case OID_SKGE_CHKSM_NUMBER:
- case OID_SKGE_VAUXAVAIL:
- if (*pLen < sizeof(SK_U8)) {
-
- *pLen = sizeof(SK_U8);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_TX_SW_QUEUE_LEN:
- case OID_SKGE_TX_SW_QUEUE_MAX:
- case OID_SKGE_TX_RETRY:
- case OID_SKGE_RX_INTR_CTS:
- case OID_SKGE_TX_INTR_CTS:
- case OID_SKGE_RX_NO_BUF_CTS:
- case OID_SKGE_TX_NO_BUF_CTS:
- case OID_SKGE_TX_USED_DESCR_NO:
- case OID_SKGE_RX_DELIVERED_CTS:
- case OID_SKGE_RX_OCTETS_DELIV_CTS:
- case OID_SKGE_RX_HW_ERROR_CTS:
- case OID_SKGE_TX_HW_ERROR_CTS:
- case OID_SKGE_IN_ERRORS_CTS:
- case OID_SKGE_OUT_ERROR_CTS:
- case OID_SKGE_ERR_RECOVERY_CTS:
- case OID_SKGE_SYSUPTIME:
- if (*pLen < sizeof(SK_U64)) {
-
- *pLen = sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- /* Checked later */
- break;
- }
-
- /* Update statistic */
- if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
- Id == OID_SKGE_TX_HW_ERROR_CTS ||
- Id == OID_SKGE_IN_ERRORS_CTS ||
- Id == OID_SKGE_OUT_ERROR_CTS ||
- Id == OID_GEN_XMIT_ERROR ||
- Id == OID_GEN_RCV_ERROR) {
-
- /* Force the XMAC to update its statistic counters and
- * Increment semaphore to indicate that an update was
- * already done.
- */
- Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
- if (Ret != SK_PNMI_ERR_OK) {
-
- *pLen = 0;
- return (Ret);
- }
- pAC->Pnmi.MacUpdatedFlag ++;
-
- /*
- * Some OIDs consist of multiple hardware counters. Those
- * values which are contained in all of them will be added
- * now.
- */
- switch (Id) {
-
- case OID_SKGE_RX_HW_ERROR_CTS:
- case OID_SKGE_IN_ERRORS_CTS:
- case OID_GEN_RCV_ERROR:
- Val64RxHwErrs =
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
- break;
-
- case OID_SKGE_TX_HW_ERROR_CTS:
- case OID_SKGE_OUT_ERROR_CTS:
- case OID_GEN_XMIT_ERROR:
- Val64TxHwErrs =
- GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
- break;
- }
- }
-
- /*
- * Retrieve value
- */
- switch (Id) {
-
- case OID_SKGE_SUPPORTED_LIST:
- Len = ID_TABLE_SIZE * sizeof(SK_U32);
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- for (Offset = 0, Index = 0; Offset < Len;
- Offset += sizeof(SK_U32), Index ++) {
-
- Val32 = (SK_U32)IdTable[Index].Id;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- }
- *pLen = Len;
- break;
-
- case OID_SKGE_BOARDLEVEL:
- Val32 = (SK_U32)pAC->GIni.GILevel;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_PORT_NUMBER:
- Val32 = (SK_U32)pAC->GIni.GIMacsFound;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_DEVICE_TYPE:
- Val32 = (SK_U32)pAC->Pnmi.DeviceType;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_DRIVER_DESCR:
- if (pAC->Pnmi.pDriverDescription == NULL) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
- SK_PNMI_ERR007MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
- if (Len > SK_PNMI_STRINGLEN1) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
- SK_PNMI_ERR029MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- *pBuf = (char)(Len - 1);
- SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
- *pLen = Len;
- break;
-
- case OID_SKGE_DRIVER_VERSION:
- if (pAC->Pnmi.pDriverVersion == NULL) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
- SK_PNMI_ERR030MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
- if (Len > SK_PNMI_STRINGLEN1) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
- SK_PNMI_ERR031MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- *pBuf = (char)(Len - 1);
- SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
- *pLen = Len;
- break;
-
- case OID_SKGE_DRIVER_RELDATE:
- if (pAC->Pnmi.pDriverReleaseDate == NULL) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
- SK_PNMI_ERR053MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
- if (Len > SK_PNMI_STRINGLEN1) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
- SK_PNMI_ERR054MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- *pBuf = (char)(Len - 1);
- SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
- *pLen = Len;
- break;
-
- case OID_SKGE_DRIVER_FILENAME:
- if (pAC->Pnmi.pDriverFileName == NULL) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
- SK_PNMI_ERR055MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
- if (Len > SK_PNMI_STRINGLEN1) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
- SK_PNMI_ERR056MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- *pBuf = (char)(Len - 1);
- SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
- *pLen = Len;
- break;
-
- case OID_SKGE_HW_DESCR:
- /*
- * The hardware description is located in the VPD. This
- * query may move to the initialisation routine. But
- * the VPD data is cached and therefore a call here
- * will not make much difference.
- */
- Len = 256;
- if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
- SK_PNMI_ERR032MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- Len ++;
- if (Len > SK_PNMI_STRINGLEN1) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
- SK_PNMI_ERR033MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- *pBuf = (char)(Len - 1);
- SK_MEMCPY(pBuf + 1, Buf, Len - 1);
- *pLen = Len;
- break;
-
- case OID_SKGE_HW_VERSION:
- /* Oh, I love to do some string manipulation */
- if (*pLen < 5) {
-
- *pLen = 5;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
- pBuf[0] = 4;
- pBuf[1] = 'v';
- pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
- pBuf[3] = '.';
- pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
- *pLen = 5;
- break;
-
- case OID_SKGE_CHIPSET:
- Val16 = pAC->Pnmi.Chipset;
- SK_PNMI_STORE_U16(pBuf, Val16);
- *pLen = sizeof(SK_U16);
- break;
-
- case OID_SKGE_CHIPID:
- Val32 = pAC->GIni.GIChipId;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_RAMSIZE:
- Val32 = pAC->GIni.GIRamSize;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_VAUXAVAIL:
- *pBuf = (char) pAC->GIni.GIVauxAvail;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_BUS_TYPE:
- *pBuf = (char) SK_PNMI_BUS_PCI;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_BUS_SPEED:
- *pBuf = pAC->Pnmi.PciBusSpeed;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_BUS_WIDTH:
- *pBuf = pAC->Pnmi.PciBusWidth;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_RESULT:
- Val32 = pAC->Pnmi.TestResult;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_SENSOR_NUMBER:
- *pBuf = (char)pAC->I2c.MaxSens;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_CHKSM_NUMBER:
- *pBuf = SKCS_NUM_PROTOCOLS;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_TRAP_NUMBER:
- GetTrapQueueLen(pAC, &Len, &Val);
- Val32 = (SK_U32)Val;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_TRAP:
- GetTrapQueueLen(pAC, &Len, &Val);
- if (*pLen < Len) {
-
- *pLen = Len;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- CopyTrapQueue(pAC, pBuf);
- *pLen = Len;
- break;
-
- case OID_SKGE_RLMT_MONITOR_NUMBER:
-/* XXX Not yet implemented by RLMT therefore we return zero elements */
- Val32 = 0;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_TX_SW_QUEUE_LEN:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
- pAC->Pnmi.BufPort[1].TxSwQueueLen;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
- pAC->Pnmi.Port[1].TxSwQueueLen;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
-
- case OID_SKGE_TX_SW_QUEUE_MAX:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
- pAC->Pnmi.BufPort[1].TxSwQueueMax;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
- pAC->Pnmi.Port[1].TxSwQueueMax;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_TX_RETRY:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
- pAC->Pnmi.BufPort[1].TxRetryCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].TxRetryCts +
- pAC->Pnmi.Port[1].TxRetryCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RX_INTR_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
- pAC->Pnmi.BufPort[1].RxIntrCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].RxIntrCts +
- pAC->Pnmi.Port[1].RxIntrCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_TX_INTR_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
- pAC->Pnmi.BufPort[1].TxIntrCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].TxIntrCts +
- pAC->Pnmi.Port[1].TxIntrCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RX_NO_BUF_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
- pAC->Pnmi.BufPort[1].RxNoBufCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
- pAC->Pnmi.Port[1].RxNoBufCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_TX_NO_BUF_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
- pAC->Pnmi.BufPort[1].TxNoBufCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
- pAC->Pnmi.Port[1].TxNoBufCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_TX_USED_DESCR_NO:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
- pAC->Pnmi.BufPort[1].TxUsedDescrNo;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
- pAC->Pnmi.Port[1].TxUsedDescrNo;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RX_DELIVERED_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
- pAC->Pnmi.BufPort[1].RxDeliveredCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
- pAC->Pnmi.Port[1].RxDeliveredCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RX_OCTETS_DELIV_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
- pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
- pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RX_HW_ERROR_CTS:
- SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_TX_HW_ERROR_CTS:
- SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_IN_ERRORS_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = Val64RxHwErrs +
- pAC->Pnmi.BufPort[0].RxNoBufCts +
- pAC->Pnmi.BufPort[1].RxNoBufCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = Val64RxHwErrs +
- pAC->Pnmi.Port[0].RxNoBufCts +
- pAC->Pnmi.Port[1].RxNoBufCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_OUT_ERROR_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = Val64TxHwErrs +
- pAC->Pnmi.BufPort[0].TxNoBufCts +
- pAC->Pnmi.BufPort[1].TxNoBufCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
- }
- /* Single net mode */
- else {
- Val64 = Val64TxHwErrs +
- pAC->Pnmi.Port[0].TxNoBufCts +
- pAC->Pnmi.Port[1].TxNoBufCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_ERR_RECOVERY_CTS:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
- pAC->Pnmi.BufPort[1].ErrRecoveryCts;
- }
- }
- else {
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
- }
- /* Single net mode */
- else {
- Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
- pAC->Pnmi.Port[1].ErrRecoveryCts;
- }
- }
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_SYSUPTIME:
- Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
- Val64 -= pAC->Pnmi.StartUpTime;
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_MDB_VERSION:
- Val32 = SK_PNMI_MDB_VERSION;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_GEN_RCV_ERROR:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
- }
- else {
- Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
- }
-
- /*
- * by default 32bit values are evaluated
- */
- if (!Is64BitReq) {
- Val32 = (SK_U32)Val64;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- }
- else {
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- }
- break;
-
- case OID_GEN_XMIT_ERROR:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
- }
- else {
- Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
- }
-
- /*
- * by default 32bit values are evaluated
- */
- if (!Is64BitReq) {
- Val32 = (SK_U32)Val64;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- }
- else {
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- }
- break;
-
- case OID_GEN_RCV_NO_BUFFER:
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
- }
- else {
- Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
- }
-
- /*
- * by default 32bit values are evaluated
- */
- if (!Is64BitReq) {
- Val32 = (SK_U32)Val64;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- }
- else {
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- }
- break;
-
- case OID_GEN_TRANSMIT_QUEUE_LENGTH:
- Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
- SK_PNMI_ERR034MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
- Id == OID_SKGE_TX_HW_ERROR_CTS ||
- Id == OID_SKGE_IN_ERRORS_CTS ||
- Id == OID_SKGE_OUT_ERROR_CTS ||
- Id == OID_GEN_XMIT_ERROR ||
- Id == OID_GEN_RCV_ERROR) {
-
- pAC->Pnmi.MacUpdatedFlag --;
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
- *
- * Description:
- * Get/Presets/Sets the RLMT OIDs.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int Rlmt(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- int Ret;
- unsigned int PhysPortIndex;
- unsigned int PhysPortMax;
- SK_EVPARA EventParam;
- SK_U32 Val32;
- SK_U64 Val64;
-
-
- /*
- * Check instance. Only single instance OIDs are allowed here.
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- /*
- * Perform the requested action.
- */
- if (Action == SK_PNMI_GET) {
-
- /*
- * Check if the buffer length is large enough.
- */
-
- switch (Id) {
-
- case OID_SKGE_RLMT_MODE:
- case OID_SKGE_RLMT_PORT_ACTIVE:
- case OID_SKGE_RLMT_PORT_PREFERRED:
- if (*pLen < sizeof(SK_U8)) {
-
- *pLen = sizeof(SK_U8);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_RLMT_PORT_NUMBER:
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_RLMT_CHANGE_CTS:
- case OID_SKGE_RLMT_CHANGE_TIME:
- case OID_SKGE_RLMT_CHANGE_ESTIM:
- case OID_SKGE_RLMT_CHANGE_THRES:
- if (*pLen < sizeof(SK_U64)) {
-
- *pLen = sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
- SK_PNMI_ERR035MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * Update RLMT statistic and increment semaphores to indicate
- * that an update was already done. Maybe RLMT will hold its
- * statistic always up to date some time. Then we can
- * remove this type of call.
- */
- if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
- *pLen = 0;
- return (Ret);
- }
- pAC->Pnmi.RlmtUpdatedFlag ++;
-
- /*
- * Retrieve Value
- */
- switch (Id) {
-
- case OID_SKGE_RLMT_MODE:
- *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_RLMT_PORT_NUMBER:
- Val32 = (SK_U32)pAC->GIni.GIMacsFound;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
- break;
-
- case OID_SKGE_RLMT_PORT_ACTIVE:
- *pBuf = 0;
- /*
- * If multiple ports may become active this OID
- * doesn't make sense any more. A new variable in
- * the port structure should be created. However,
- * for this variable the first active port is
- * returned.
- */
- PhysPortMax = pAC->GIni.GIMacsFound;
-
- for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
- break;
- }
- }
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_RLMT_PORT_PREFERRED:
- *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
- *pLen = sizeof(char);
- break;
-
- case OID_SKGE_RLMT_CHANGE_CTS:
- Val64 = pAC->Pnmi.RlmtChangeCts;
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RLMT_CHANGE_TIME:
- Val64 = pAC->Pnmi.RlmtChangeTime;
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RLMT_CHANGE_ESTIM:
- Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- case OID_SKGE_RLMT_CHANGE_THRES:
- Val64 = pAC->Pnmi.RlmtChangeThreshold;
- SK_PNMI_STORE_U64(pBuf, Val64);
- *pLen = sizeof(SK_U64);
- break;
-
- default:
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
- ("Rlmt: Unknown OID should be handled before"));
-
- pAC->Pnmi.RlmtUpdatedFlag --;
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- pAC->Pnmi.RlmtUpdatedFlag --;
- }
- else {
- /* Perform a preset or set */
- switch (Id) {
-
- case OID_SKGE_RLMT_MODE:
- /* Check if the buffer length is plausible */
- if (*pLen < sizeof(char)) {
-
- *pLen = sizeof(char);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- /* Check if the value range is correct */
- if (*pLen != sizeof(char) ||
- (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
- *(SK_U8 *)pBuf > 15) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_OK);
- }
- /* Send an event to RLMT to change the mode */
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
- EventParam.Para32[0] |= (SK_U32)(*pBuf);
- EventParam.Para32[1] = 0;
- if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
- SK_PNMI_ERR037MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- break;
-
- case OID_SKGE_RLMT_PORT_PREFERRED:
- /* Check if the buffer length is plausible */
- if (*pLen < sizeof(char)) {
-
- *pLen = sizeof(char);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- /* Check if the value range is correct */
- if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
- (SK_U8)pAC->GIni.GIMacsFound) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_OK);
- }
-
- /*
- * Send an event to RLMT change the preferred port.
- * A param of -1 means automatic mode. RLMT will
- * make the decision which is the preferred port.
- */
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
- EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
- EventParam.Para32[1] = NetIndex;
- if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
- SK_PNMI_ERR038MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- break;
-
- case OID_SKGE_RLMT_CHANGE_THRES:
- /* Check if the buffer length is plausible */
- if (*pLen < sizeof(SK_U64)) {
-
- *pLen = sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- /*
- * There are not many restrictions to the
- * value range.
- */
- if (*pLen != sizeof(SK_U64)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- /* A preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_OK);
- }
- /*
- * Store the new threshold, which will be taken
- * on the next timer event.
- */
- SK_PNMI_READ_U64(pBuf, Val64);
- pAC->Pnmi.RlmtChangeThreshold = Val64;
- break;
-
- default:
- /* The other OIDs are not be able for set */
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
- *
- * Description:
- * Performs get requests on multiple instance variables.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int RlmtStat(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int PhysPortMax;
- unsigned int PhysPortIndex;
- unsigned int Limit;
- unsigned int Offset;
- int Ret;
- SK_U32 Val32;
- SK_U64 Val64;
-
- /*
- * Calculate the port indexes from the instance.
- */
- PhysPortMax = pAC->GIni.GIMacsFound;
-
- if ((Instance != (SK_U32)(-1))) {
- /* Check instance range */
- if ((Instance < 1) || (Instance > PhysPortMax)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- /* Single net mode */
- PhysPortIndex = Instance - 1;
-
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- PhysPortIndex = NetIndex;
- }
-
- /* Both net modes */
- Limit = PhysPortIndex + 1;
- }
- else {
- /* Single net mode */
- PhysPortIndex = 0;
- Limit = PhysPortMax;
-
- /* Dual net mode */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- PhysPortIndex = NetIndex;
- Limit = PhysPortIndex + 1;
- }
- }
-
- /*
- * Currently only get requests are allowed.
- */
- if (Action != SK_PNMI_GET) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /*
- * Check if the buffer length is large enough.
- */
- switch (Id) {
-
- case OID_SKGE_RLMT_PORT_INDEX:
- case OID_SKGE_RLMT_STATUS:
- if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
-
- *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_RLMT_TX_HELLO_CTS:
- case OID_SKGE_RLMT_RX_HELLO_CTS:
- case OID_SKGE_RLMT_TX_SP_REQ_CTS:
- case OID_SKGE_RLMT_RX_SP_CTS:
- if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
-
- *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
- SK_PNMI_ERR039MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
-
- }
-
- /*
- * Update statistic and increment semaphores to indicate that
- * an update was already done.
- */
- if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
-
- *pLen = 0;
- return (Ret);
- }
- pAC->Pnmi.RlmtUpdatedFlag ++;
-
- /*
- * Get value
- */
- Offset = 0;
- for (; PhysPortIndex < Limit; PhysPortIndex ++) {
-
- switch (Id) {
-
- case OID_SKGE_RLMT_PORT_INDEX:
- Val32 = PhysPortIndex;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_RLMT_STATUS:
- if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
- SK_RLMT_PS_INIT ||
- pAC->Rlmt.Port[PhysPortIndex].PortState ==
- SK_RLMT_PS_DOWN) {
-
- Val32 = SK_PNMI_RLMT_STATUS_ERROR;
- }
- else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
- }
- else {
- Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
- }
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_RLMT_TX_HELLO_CTS:
- Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- case OID_SKGE_RLMT_RX_HELLO_CTS:
- Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- case OID_SKGE_RLMT_TX_SP_REQ_CTS:
- Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- case OID_SKGE_RLMT_RX_SP_CTS:
- Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
- SK_PNMI_STORE_U64(pBuf + Offset, Val64);
- Offset += sizeof(SK_U64);
- break;
-
- default:
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
- ("RlmtStat: Unknown OID should be errored before"));
-
- pAC->Pnmi.RlmtUpdatedFlag --;
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- *pLen = Offset;
-
- pAC->Pnmi.RlmtUpdatedFlag --;
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacPrivateConf - OID handler function of OIDs concerning the configuration
- *
- * Description:
- * Get/Presets/Sets the OIDs concerning the configuration.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int MacPrivateConf(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int PhysPortMax;
- unsigned int PhysPortIndex;
- unsigned int LogPortMax;
- unsigned int LogPortIndex;
- unsigned int Limit;
- unsigned int Offset;
- char Val8;
- char *pBufPtr;
- int Ret;
- SK_EVPARA EventParam;
- SK_U32 Val32;
-
- /*
- * Calculate instance if wished. MAC index 0 is the virtual MAC.
- */
- PhysPortMax = pAC->GIni.GIMacsFound;
- LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
- LogPortMax--;
- }
-
- if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
- /* Check instance range */
- if ((Instance < 1) || (Instance > LogPortMax)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
- LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
- Limit = LogPortIndex + 1;
- }
-
- else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
-
- LogPortIndex = 0;
- Limit = LogPortMax;
- }
-
- /*
- * Perform action
- */
- if (Action == SK_PNMI_GET) {
-
- /* Check length */
- switch (Id) {
-
- case OID_SKGE_PMD:
- case OID_SKGE_CONNECTOR:
- case OID_SKGE_LINK_CAP:
- case OID_SKGE_LINK_MODE:
- case OID_SKGE_LINK_MODE_STATUS:
- case OID_SKGE_LINK_STATUS:
- case OID_SKGE_FLOWCTRL_CAP:
- case OID_SKGE_FLOWCTRL_MODE:
- case OID_SKGE_FLOWCTRL_STATUS:
- case OID_SKGE_PHY_OPERATION_CAP:
- case OID_SKGE_PHY_OPERATION_MODE:
- case OID_SKGE_PHY_OPERATION_STATUS:
- case OID_SKGE_SPEED_CAP:
- case OID_SKGE_SPEED_MODE:
- case OID_SKGE_SPEED_STATUS:
- if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
-
- *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_MTU:
- case OID_SKGE_PHY_TYPE:
- if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
-
- *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
- SK_PNMI_ERR041MSG);
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * Update statistic and increment semaphore to indicate
- * that an update was already done.
- */
- if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
-
- *pLen = 0;
- return (Ret);
- }
- pAC->Pnmi.SirqUpdatedFlag ++;
-
- /*
- * Get value
- */
- Offset = 0;
- for (; LogPortIndex < Limit; LogPortIndex ++) {
-
- pBufPtr = pBuf + Offset;
-
- switch (Id) {
-
- case OID_SKGE_PMD:
- *pBufPtr = pAC->Pnmi.PMD;
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_CONNECTOR:
- *pBufPtr = pAC->Pnmi.Connector;
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_PHY_TYPE:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- continue;
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
- Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
- SK_PNMI_STORE_U32(pBufPtr, Val32);
- }
- }
- else { /* DualNetMode */
-
- Val32 = pAC->GIni.GP[NetIndex].PhyType;
- SK_PNMI_STORE_U32(pBufPtr, Val32);
- }
- Offset += sizeof(SK_U32);
- break;
-
- case OID_SKGE_LINK_CAP:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_LINK_MODE:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_LINK_MODE_STATUS:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr =
- CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_LINK_STATUS:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_FLOWCTRL_CAP:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_FLOWCTRL_MODE:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_FLOWCTRL_STATUS:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_PHY_OPERATION_CAP:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_PHY_OPERATION_MODE:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_PHY_OPERATION_STATUS:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
- }
- }
- else {
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SPEED_CAP:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical ports */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SPEED_MODE:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SPEED_STATUS:
- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
- if (LogPortIndex == 0) {
- /* Get value for virtual port */
- VirtualConf(pAC, IoC, Id, pBufPtr);
- }
- else {
- /* Get value for physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
-
- *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
- }
- }
- else { /* DualNetMode */
-
- *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_MTU:
- Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
- SK_PNMI_STORE_U32(pBufPtr, Val32);
- Offset += sizeof(SK_U32);
- break;
-
- default:
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
- ("MacPrivateConf: Unknown OID should be handled before"));
-
- pAC->Pnmi.SirqUpdatedFlag --;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- *pLen = Offset;
- pAC->Pnmi.SirqUpdatedFlag --;
-
- return (SK_PNMI_ERR_OK);
- }
-
- /*
- * From here SET or PRESET action. Check if the passed
- * buffer length is plausible.
- */
- switch (Id) {
-
- case OID_SKGE_LINK_MODE:
- case OID_SKGE_FLOWCTRL_MODE:
- case OID_SKGE_PHY_OPERATION_MODE:
- case OID_SKGE_SPEED_MODE:
- if (*pLen < Limit - LogPortIndex) {
-
- *pLen = Limit - LogPortIndex;
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- if (*pLen != Limit - LogPortIndex) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- break;
-
- case OID_SKGE_MTU:
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- if (*pLen != sizeof(SK_U32)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
- break;
-
- default:
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /*
- * Perform preset or set
- */
- Offset = 0;
- for (; LogPortIndex < Limit; LogPortIndex ++) {
-
- switch (Id) {
-
- case OID_SKGE_LINK_MODE:
- /* Check the value range */
- Val8 = *(pBuf + Offset);
- if (Val8 == 0) {
-
- Offset += sizeof(char);
- break;
- }
- if (Val8 < SK_LMODE_HALF ||
- (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
- (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- if (LogPortIndex == 0) {
-
- /*
- * The virtual port consists of all currently
- * active ports. Find them and send an event
- * with the new link mode to SIRQ.
- */
- for (PhysPortIndex = 0;
- PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- if (!pAC->Pnmi.Port[PhysPortIndex].
- ActiveFlag) {
-
- continue;
- }
-
- EventParam.Para32[0] = PhysPortIndex;
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_LMODE,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR043,
- SK_PNMI_ERR043MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- }
- else {
- /*
- * Send an event with the new link mode to
- * the SIRQ module.
- */
- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR043,
- SK_PNMI_ERR043MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_FLOWCTRL_MODE:
- /* Check the value range */
- Val8 = *(pBuf + Offset);
- if (Val8 == 0) {
-
- Offset += sizeof(char);
- break;
- }
- if (Val8 < SK_FLOW_MODE_NONE ||
- (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
- (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- if (LogPortIndex == 0) {
-
- /*
- * The virtual port consists of all currently
- * active ports. Find them and send an event
- * with the new flow control mode to SIRQ.
- */
- for (PhysPortIndex = 0;
- PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- if (!pAC->Pnmi.Port[PhysPortIndex].
- ActiveFlag) {
-
- continue;
- }
-
- EventParam.Para32[0] = PhysPortIndex;
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_FLOWMODE,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR044,
- SK_PNMI_ERR044MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- }
- else {
- /*
- * Send an event with the new flow control
- * mode to the SIRQ module.
- */
- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_FLOWMODE, EventParam)
- > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR044,
- SK_PNMI_ERR044MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_PHY_OPERATION_MODE :
- /* Check the value range */
- Val8 = *(pBuf + Offset);
- if (Val8 == 0) {
- /* mode of this port remains unchanged */
- Offset += sizeof(char);
- break;
- }
- if (Val8 < SK_MS_MODE_AUTO ||
- (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
- (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- if (LogPortIndex == 0) {
-
- /*
- * The virtual port consists of all currently
- * active ports. Find them and send an event
- * with new master/slave (role) mode to SIRQ.
- */
- for (PhysPortIndex = 0;
- PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- if (!pAC->Pnmi.Port[PhysPortIndex].
- ActiveFlag) {
-
- continue;
- }
-
- EventParam.Para32[0] = PhysPortIndex;
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_ROLE,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR042,
- SK_PNMI_ERR042MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- }
- else {
- /*
- * Send an event with the new master/slave
- * (role) mode to the SIRQ module.
- */
- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_ROLE, EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR042,
- SK_PNMI_ERR042MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
-
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_SPEED_MODE:
- /* Check the value range */
- Val8 = *(pBuf + Offset);
- if (Val8 == 0) {
-
- Offset += sizeof(char);
- break;
- }
- if (Val8 < (SK_LSPEED_AUTO) ||
- (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
- (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- if (LogPortIndex == 0) {
-
- /*
- * The virtual port consists of all currently
- * active ports. Find them and send an event
- * with the new flow control mode to SIRQ.
- */
- for (PhysPortIndex = 0;
- PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- continue;
- }
-
- EventParam.Para32[0] = PhysPortIndex;
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_SPEED,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR045,
- SK_PNMI_ERR045MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- }
- else {
- /*
- * Send an event with the new flow control
- * mode to the SIRQ module.
- */
- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
- pAC, LogPortIndex);
- EventParam.Para32[1] = (SK_U32)Val8;
- if (SkGeSirqEvent(pAC, IoC,
- SK_HWEV_SET_SPEED,
- EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SK_PNMI_ERR045,
- SK_PNMI_ERR045MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- Offset += sizeof(char);
- break;
-
- case OID_SKGE_MTU :
- /* Check the value range */
- Val32 = *(SK_U32*)(pBuf + Offset);
- if (Val32 == 0) {
- /* mtu of this port remains unchanged */
- Offset += sizeof(SK_U32);
- break;
- }
- if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- /* The preset ends here */
- if (Action == SK_PNMI_PRESET) {
- return (SK_PNMI_ERR_OK);
- }
-
- if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
- return (SK_PNMI_ERR_GENERAL);
- }
-
- Offset += sizeof(SK_U32);
- break;
-
- default:
- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
- ("MacPrivateConf: Unknown OID should be handled before set"));
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * Monitor - OID handler function for RLMT_MONITOR_XXX
- *
- * Description:
- * Because RLMT currently does not support the monitoring of
- * remote adapter cards, we return always an empty table.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
- * value range.
- * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-PNMI_STATIC int Monitor(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- unsigned int Index;
- unsigned int Limit;
- unsigned int Offset;
- unsigned int Entries;
-
-
- /*
- * Calculate instance if wished.
- */
- /* XXX Not yet implemented. Return always an empty table. */
- Entries = 0;
-
- if ((Instance != (SK_U32)(-1))) {
-
- if ((Instance < 1) || (Instance > Entries)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- Index = (unsigned int)Instance - 1;
- Limit = (unsigned int)Instance;
- }
- else {
- Index = 0;
- Limit = Entries;
- }
-
- /*
- * Get/Set value
- */
- if (Action == SK_PNMI_GET) {
-
- for (Offset=0; Index < Limit; Index ++) {
-
- switch (Id) {
-
- case OID_SKGE_RLMT_MONITOR_INDEX:
- case OID_SKGE_RLMT_MONITOR_ADDR:
- case OID_SKGE_RLMT_MONITOR_ERRS:
- case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
- case OID_SKGE_RLMT_MONITOR_ADMIN:
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
- SK_PNMI_ERR046MSG);
-
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- }
- *pLen = Offset;
- }
- else {
- /* Only MONITOR_ADMIN can be set */
- if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_READ_ONLY);
- }
-
- /* Check if the length is plausible */
- if (*pLen < (Limit - Index)) {
-
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- /* Okay, we have a wide value range */
- if (*pLen != (Limit - Index)) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-/*
- for (Offset=0; Index < Limit; Index ++) {
- }
-*/
-/*
- * XXX Not yet implemented. Return always BAD_VALUE, because the table
- * is empty.
- */
- *pLen = 0;
- return (SK_PNMI_ERR_BAD_VALUE);
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * VirtualConf - Calculates the values of configuration OIDs for virtual port
- *
- * Description:
- * We handle here the get of the configuration group OIDs, which are
- * a little bit complicated. The virtual port consists of all currently
- * active physical ports. If multiple ports are active and configured
- * differently we get in some trouble to return a single value. So we
- * get the value of the first active port and compare it with that of
- * the other active ports. If they are not the same, we return a value
- * that indicates that the state is indeterminated.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void VirtualConf(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf) /* Buffer used for the management data transfer */
-{
- unsigned int PhysPortMax;
- unsigned int PhysPortIndex;
- SK_U8 Val8;
- SK_U32 Val32;
- SK_BOOL PortActiveFlag;
- SK_GEPORT *pPrt;
-
- *pBuf = 0;
- PortActiveFlag = SK_FALSE;
- PhysPortMax = pAC->GIni.GIMacsFound;
-
- for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- pPrt = &pAC->GIni.GP[PhysPortIndex];
-
- /* Check if the physical port is active */
- if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- continue;
- }
-
- PortActiveFlag = SK_TRUE;
-
- switch (Id) {
-
- case OID_SKGE_PHY_TYPE:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
- Val32 = pPrt->PhyType;
- SK_PNMI_STORE_U32(pBuf, Val32);
- continue;
- }
-
- case OID_SKGE_LINK_CAP:
-
- /*
- * Different capabilities should not happen, but
- * in the case of the cases OR them all together.
- * From a curious point of view the virtual port
- * is capable of all found capabilities.
- */
- *pBuf |= pPrt->PLinkCap;
- break;
-
- case OID_SKGE_LINK_MODE:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PLinkModeConf;
- continue;
- }
-
- /*
- * If we find an active port with a different link
- * mode than the first one we return a value that
- * indicates that the link mode is indeterminated.
- */
- if (*pBuf != pPrt->PLinkModeConf) {
-
- *pBuf = SK_LMODE_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_LINK_MODE_STATUS:
- /* Get the link mode of the physical port */
- Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
-
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = Val8;
- continue;
- }
-
- /*
- * If we find an active port with a different link
- * mode status than the first one we return a value
- * that indicates that the link mode status is
- * indeterminated.
- */
- if (*pBuf != Val8) {
-
- *pBuf = SK_LMODE_STAT_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_LINK_STATUS:
- /* Get the link status of the physical port */
- Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
-
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = Val8;
- continue;
- }
-
- /*
- * If we find an active port with a different link
- * status than the first one, we return a value
- * that indicates that the link status is
- * indeterminated.
- */
- if (*pBuf != Val8) {
-
- *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_FLOWCTRL_CAP:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PFlowCtrlCap;
- continue;
- }
-
- /*
- * From a curious point of view the virtual port
- * is capable of all found capabilities.
- */
- *pBuf |= pPrt->PFlowCtrlCap;
- break;
-
- case OID_SKGE_FLOWCTRL_MODE:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PFlowCtrlMode;
- continue;
- }
-
- /*
- * If we find an active port with a different flow
- * control mode than the first one, we return a value
- * that indicates that the mode is indeterminated.
- */
- if (*pBuf != pPrt->PFlowCtrlMode) {
-
- *pBuf = SK_FLOW_MODE_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_FLOWCTRL_STATUS:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PFlowCtrlStatus;
- continue;
- }
-
- /*
- * If we find an active port with a different flow
- * control status than the first one, we return a
- * value that indicates that the status is
- * indeterminated.
- */
- if (*pBuf != pPrt->PFlowCtrlStatus) {
-
- *pBuf = SK_FLOW_STAT_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_PHY_OPERATION_CAP:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PMSCap;
- continue;
- }
-
- /*
- * From a curious point of view the virtual port
- * is capable of all found capabilities.
- */
- *pBuf |= pPrt->PMSCap;
- break;
-
- case OID_SKGE_PHY_OPERATION_MODE:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PMSMode;
- continue;
- }
-
- /*
- * If we find an active port with a different master/
- * slave mode than the first one, we return a value
- * that indicates that the mode is indeterminated.
- */
- if (*pBuf != pPrt->PMSMode) {
-
- *pBuf = SK_MS_MODE_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_PHY_OPERATION_STATUS:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PMSStatus;
- continue;
- }
-
- /*
- * If we find an active port with a different master/
- * slave status than the first one, we return a
- * value that indicates that the status is
- * indeterminated.
- */
- if (*pBuf != pPrt->PMSStatus) {
-
- *pBuf = SK_MS_STAT_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_SPEED_MODE:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PLinkSpeed;
- continue;
- }
-
- /*
- * If we find an active port with a different flow
- * control mode than the first one, we return a value
- * that indicates that the mode is indeterminated.
- */
- if (*pBuf != pPrt->PLinkSpeed) {
-
- *pBuf = SK_LSPEED_INDETERMINATED;
- }
- break;
-
- case OID_SKGE_SPEED_STATUS:
- /* Check if it is the first active port */
- if (*pBuf == 0) {
-
- *pBuf = pPrt->PLinkSpeedUsed;
- continue;
- }
-
- /*
- * If we find an active port with a different flow
- * control status than the first one, we return a
- * value that indicates that the status is
- * indeterminated.
- */
- if (*pBuf != pPrt->PLinkSpeedUsed) {
-
- *pBuf = SK_LSPEED_STAT_INDETERMINATED;
- }
- break;
- }
- }
-
- /*
- * If no port is active return an indeterminated answer
- */
- if (!PortActiveFlag) {
-
- switch (Id) {
-
- case OID_SKGE_LINK_CAP:
- *pBuf = SK_LMODE_CAP_INDETERMINATED;
- break;
-
- case OID_SKGE_LINK_MODE:
- *pBuf = SK_LMODE_INDETERMINATED;
- break;
-
- case OID_SKGE_LINK_MODE_STATUS:
- *pBuf = SK_LMODE_STAT_INDETERMINATED;
- break;
-
- case OID_SKGE_LINK_STATUS:
- *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
- break;
-
- case OID_SKGE_FLOWCTRL_CAP:
- case OID_SKGE_FLOWCTRL_MODE:
- *pBuf = SK_FLOW_MODE_INDETERMINATED;
- break;
-
- case OID_SKGE_FLOWCTRL_STATUS:
- *pBuf = SK_FLOW_STAT_INDETERMINATED;
- break;
-
- case OID_SKGE_PHY_OPERATION_CAP:
- *pBuf = SK_MS_CAP_INDETERMINATED;
- break;
-
- case OID_SKGE_PHY_OPERATION_MODE:
- *pBuf = SK_MS_MODE_INDETERMINATED;
- break;
-
- case OID_SKGE_PHY_OPERATION_STATUS:
- *pBuf = SK_MS_STAT_INDETERMINATED;
- break;
- case OID_SKGE_SPEED_CAP:
- *pBuf = SK_LSPEED_CAP_INDETERMINATED;
- break;
-
- case OID_SKGE_SPEED_MODE:
- *pBuf = SK_LSPEED_INDETERMINATED;
- break;
-
- case OID_SKGE_SPEED_STATUS:
- *pBuf = SK_LSPEED_STAT_INDETERMINATED;
- break;
- }
- }
-}
-
-/*****************************************************************************
- *
- * CalculateLinkStatus - Determins the link status of a physical port
- *
- * Description:
- * Determins the link status the following way:
- * LSTAT_PHY_DOWN: Link is down
- * LSTAT_AUTONEG: Auto-negotiation failed
- * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
- * logically up.
- * LSTAT_LOG_UP: RLMT marked the port as up
- *
- * Returns:
- * Link status of physical port
- */
-PNMI_STATIC SK_U8 CalculateLinkStatus(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-unsigned int PhysPortIndex) /* Physical port index */
-{
- SK_U8 Result;
-
- if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
-
- Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
- }
- else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
-
- Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
- }
- else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
-
- Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
- }
- else {
- Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
- }
-
- return (Result);
-}
-
-/*****************************************************************************
- *
- * CalculateLinkModeStatus - Determins the link mode status of a phys. port
- *
- * Description:
- * The COMMON module only tells us if the mode is half or full duplex.
- * But in the decade of auto sensing it is useful for the user to
- * know if the mode was negotiated or forced. Therefore we have a
- * look to the mode, which was last used by the negotiation process.
- *
- * Returns:
- * The link mode status
- */
-PNMI_STATIC SK_U8 CalculateLinkModeStatus(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-unsigned int PhysPortIndex) /* Physical port index */
-{
- SK_U8 Result;
-
- /* Get the current mode, which can be full or half duplex */
- Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
-
- /* Check if no valid mode could be found (link is down) */
- if (Result < SK_LMODE_STAT_HALF) {
-
- Result = SK_LMODE_STAT_UNKNOWN;
- }
- else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
-
- /*
- * Auto-negotiation was used to bring up the link. Change
- * the already found duplex status that it indicates
- * auto-negotiation was involved.
- */
- if (Result == SK_LMODE_STAT_HALF) {
-
- Result = SK_LMODE_STAT_AUTOHALF;
- }
- else if (Result == SK_LMODE_STAT_FULL) {
-
- Result = SK_LMODE_STAT_AUTOFULL;
- }
- }
-
- return (Result);
-}
-
-/*****************************************************************************
- *
- * GetVpdKeyArr - Obtain an array of VPD keys
- *
- * Description:
- * Read the VPD keys and build an array of VPD keys, which are
- * easy to access.
- *
- * Returns:
- * SK_PNMI_ERR_OK Task successfully performed.
- * SK_PNMI_ERR_GENERAL Something went wrong.
- */
-PNMI_STATIC int GetVpdKeyArr(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-char *pKeyArr, /* Ptr KeyArray */
-unsigned int KeyArrLen, /* Length of array in bytes */
-unsigned int *pKeyNo) /* Number of keys */
-{
- unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
- char BufKeys[SK_PNMI_VPD_BUFSIZE];
- unsigned int StartOffset;
- unsigned int Offset;
- int Index;
- int Ret;
-
-
- SK_MEMSET(pKeyArr, 0, KeyArrLen);
-
- /*
- * Get VPD key list
- */
- Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
- (int *)pKeyNo);
- if (Ret > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
- SK_PNMI_ERR014MSG);
-
- return (SK_PNMI_ERR_GENERAL);
- }
- /* If no keys are available return now */
- if (*pKeyNo == 0 || BufKeysLen == 0) {
-
- return (SK_PNMI_ERR_OK);
- }
- /*
- * If the key list is too long for us trunc it and give a
- * errorlog notification. This case should not happen because
- * the maximum number of keys is limited due to RAM limitations
- */
- if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
- SK_PNMI_ERR015MSG);
-
- *pKeyNo = SK_PNMI_VPD_ENTRIES;
- }
-
- /*
- * Now build an array of fixed string length size and copy
- * the keys together.
- */
- for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
- Offset ++) {
-
- if (BufKeys[Offset] != 0) {
-
- continue;
- }
-
- if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
- SK_PNMI_ERR016MSG);
- return (SK_PNMI_ERR_GENERAL);
- }
-
- SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
- &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
-
- Index ++;
- StartOffset = Offset + 1;
- }
-
- /* Last key not zero terminated? Get it anyway */
- if (StartOffset < Offset) {
-
- SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
- &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * SirqUpdate - Let the SIRQ update its internal values
- *
- * Description:
- * Just to be sure that the SIRQ module holds its internal data
- * structures up to date, we send an update event before we make
- * any access.
- *
- * Returns:
- * SK_PNMI_ERR_OK Task successfully performed.
- * SK_PNMI_ERR_GENERAL Something went wrong.
- */
-PNMI_STATIC int SirqUpdate(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC) /* IO context handle */
-{
- SK_EVPARA EventParam;
-
-
- /* Was the module already updated during the current PNMI call? */
- if (pAC->Pnmi.SirqUpdatedFlag > 0) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- /* Send an synchronuous update event to the module */
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
- if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
- SK_PNMI_ERR047MSG);
-
- return (SK_PNMI_ERR_GENERAL);
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * RlmtUpdate - Let the RLMT update its internal values
- *
- * Description:
- * Just to be sure that the RLMT module holds its internal data
- * structures up to date, we send an update event before we make
- * any access.
- *
- * Returns:
- * SK_PNMI_ERR_OK Task successfully performed.
- * SK_PNMI_ERR_GENERAL Something went wrong.
- */
-PNMI_STATIC int RlmtUpdate(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
-{
- SK_EVPARA EventParam;
-
-
- /* Was the module already updated during the current PNMI call? */
- if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- /* Send an synchronuous update event to the module */
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
- EventParam.Para32[0] = NetIndex;
- EventParam.Para32[1] = (SK_U32)-1;
- if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
- SK_PNMI_ERR048MSG);
-
- return (SK_PNMI_ERR_GENERAL);
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * MacUpdate - Force the XMAC to output the current statistic
- *
- * Description:
- * The XMAC holds its statistic internally. To obtain the current
- * values we must send a command so that the statistic data will
- * be written to a predefined memory area on the adapter.
- *
- * Returns:
- * SK_PNMI_ERR_OK Task successfully performed.
- * SK_PNMI_ERR_GENERAL Something went wrong.
- */
-PNMI_STATIC int MacUpdate(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-unsigned int FirstMac, /* Index of the first Mac to be updated */
-unsigned int LastMac) /* Index of the last Mac to be updated */
-{
- unsigned int MacIndex;
-
- /*
- * Were the statistics already updated during the
- * current PNMI call?
- */
- if (pAC->Pnmi.MacUpdatedFlag > 0) {
-
- return (SK_PNMI_ERR_OK);
- }
-
- /* Send an update command to all MACs specified */
- for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
-
- /*
- * 2002-09-13 pweber: Freeze the current SW counters.
- * (That should be done as close as
- * possible to the update of the
- * HW counters)
- */
- if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
- pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
- }
-
- /* 2002-09-13 pweber: Update the HW counter */
- if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
-
- return (SK_PNMI_ERR_GENERAL);
- }
- }
-
- return (SK_PNMI_ERR_OK);
-}
-
-/*****************************************************************************
- *
- * GetStatVal - Retrieve an XMAC statistic counter
- *
- * Description:
- * Retrieves the statistic counter of a virtual or physical port. The
- * virtual port is identified by the index 0. It consists of all
- * currently active ports. To obtain the counter value for this port
- * we must add the statistic counter of all active ports. To grant
- * continuous counter values for the virtual port even when port
- * switches occur we must additionally add a delta value, which was
- * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
- *
- * Returns:
- * Requested statistic value
- */
-PNMI_STATIC SK_U64 GetStatVal(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-unsigned int LogPortIndex, /* Index of the logical Port to be processed */
-unsigned int StatIndex, /* Index to statistic value */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
-{
- unsigned int PhysPortIndex;
- unsigned int PhysPortMax;
- SK_U64 Val = 0;
-
-
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
-
- PhysPortIndex = NetIndex;
-
- Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
- }
- else { /* Single Net mode */
-
- if (LogPortIndex == 0) {
-
- PhysPortMax = pAC->GIni.GIMacsFound;
-
- /* Add counter of all active ports */
- for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
- PhysPortIndex ++) {
-
- if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
- Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
- }
- }
-
- /* Correct value because of port switches */
- Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
- }
- else {
- /* Get counter value of physical port */
- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-
- Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
- }
- }
- return (Val);
-}
-
-/*****************************************************************************
- *
- * GetPhysStatVal - Get counter value for physical port
- *
- * Description:
- * Builds a 64bit counter value. Except for the octet counters
- * the lower 32bit are counted in hardware and the upper 32bit
- * in software by monitoring counter overflow interrupts in the
- * event handler. To grant continous counter values during XMAC
- * resets (caused by a workaround) we must add a delta value.
- * The delta was calculated in the event handler when a
- * SK_PNMI_EVT_XMAC_RESET was received.
- *
- * Returns:
- * Counter value
- */
-PNMI_STATIC SK_U64 GetPhysStatVal(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
-unsigned int StatIndex) /* Index to statistic value */
-{
- SK_U64 Val = 0;
- SK_U32 LowVal = 0;
- SK_U32 HighVal = 0;
- SK_U16 Word;
- int MacType;
- unsigned int HelpIndex;
- SK_GEPORT *pPrt;
-
- SK_PNMI_PORT *pPnmiPrt;
- SK_GEMACFUNC *pFnMac;
-
- pPrt = &pAC->GIni.GP[PhysPortIndex];
-
- MacType = pAC->GIni.GIMacType;
-
- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
- if (MacType == SK_MAC_XMAC) {
- pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
- }
- else {
- pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
- }
-
- pFnMac = &pAC->GIni.GIFunc;
-
- switch (StatIndex) {
- case SK_PNMI_HTX:
- if (MacType == SK_MAC_GMAC) {
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
- &LowVal);
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
- &HighVal);
- LowVal += HighVal;
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
- &HighVal);
- LowVal += HighVal;
- }
- else {
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- }
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HRX:
- if (MacType == SK_MAC_GMAC) {
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
- &LowVal);
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
- &HighVal);
- LowVal += HighVal;
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
- &HighVal);
- LowVal += HighVal;
- }
- else {
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- }
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HTX_OCTET:
- case SK_PNMI_HRX_OCTET:
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &HighVal);
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex + 1][MacType].Reg,
- &LowVal);
- break;
-
- case SK_PNMI_HTX_BURST:
- case SK_PNMI_HTX_EXCESS_DEF:
- case SK_PNMI_HTX_CARRIER:
- /* Not supported by GMAC */
- if (MacType == SK_MAC_GMAC) {
- return (Val);
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HTX_MACC:
- /* GMAC only supports PAUSE MAC control frames */
- if (MacType == SK_MAC_GMAC) {
- HelpIndex = SK_PNMI_HTX_PMACC;
- }
- else {
- HelpIndex = StatIndex;
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[HelpIndex][MacType].Reg,
- &LowVal);
-
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HTX_COL:
- case SK_PNMI_HRX_UNDERSIZE:
- /* Not supported by XMAC */
- if (MacType == SK_MAC_XMAC) {
- return (Val);
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HTX_DEFFERAL:
- /* Not supported by GMAC */
- if (MacType == SK_MAC_GMAC) {
- return (Val);
- }
-
- /*
- * XMAC counts frames with deferred transmission
- * even in full-duplex mode.
- *
- * In full-duplex mode the counter remains constant!
- */
- if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
- (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
-
- LowVal = 0;
- HighVal = 0;
- }
- else {
- /* Otherwise get contents of hardware register */
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- }
- break;
-
- case SK_PNMI_HRX_BADOCTET:
- /* Not supported by XMAC */
- if (MacType == SK_MAC_XMAC) {
- return (Val);
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &HighVal);
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex + 1][MacType].Reg,
- &LowVal);
- break;
-
- case SK_PNMI_HTX_OCTETLOW:
- case SK_PNMI_HRX_OCTETLOW:
- case SK_PNMI_HRX_BADOCTETLOW:
- return (Val);
-
- case SK_PNMI_HRX_LONGFRAMES:
- /* For XMAC the SW counter is managed by PNMI */
- if (MacType == SK_MAC_XMAC) {
- return (pPnmiPrt->StatRxLongFrameCts);
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HRX_TOO_LONG:
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
-
- Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-
- if (MacType == SK_MAC_GMAC) {
- /* For GMAC the SW counter is additionally managed by PNMI */
- Val += pPnmiPrt->StatRxFrameTooLongCts;
- }
- else {
- /*
- * Frames longer than IEEE 802.3 frame max size are counted
- * by XMAC in frame_too_long counter even reception of long
- * frames was enabled and the frame was correct.
- * So correct the value by subtracting RxLongFrame counter.
- */
- Val -= pPnmiPrt->StatRxLongFrameCts;
- }
-
- LowVal = (SK_U32)Val;
- HighVal = (SK_U32)(Val >> 32);
- break;
-
- case SK_PNMI_HRX_SHORTS:
- /* Not supported by GMAC */
- if (MacType == SK_MAC_GMAC) {
- /* GM_RXE_FRAG?? */
- return (Val);
- }
-
- /*
- * XMAC counts short frame errors even if link down (#10620)
- *
- * If link-down the counter remains constant
- */
- if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
-
- /* Otherwise get incremental difference */
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
-
- Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
- Val -= pPnmiPrt->RxShortZeroMark;
-
- LowVal = (SK_U32)Val;
- HighVal = (SK_U32)(Val >> 32);
- }
- break;
-
- case SK_PNMI_HRX_MACC:
- case SK_PNMI_HRX_MACC_UNKWN:
- case SK_PNMI_HRX_BURST:
- case SK_PNMI_HRX_MISSED:
- case SK_PNMI_HRX_FRAMING:
- case SK_PNMI_HRX_CARRIER:
- case SK_PNMI_HRX_IRLENGTH:
- case SK_PNMI_HRX_SYMBOL:
- case SK_PNMI_HRX_CEXT:
- /* Not supported by GMAC */
- if (MacType == SK_MAC_GMAC) {
- return (Val);
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- case SK_PNMI_HRX_PMACC_ERR:
- /* For GMAC the SW counter is managed by PNMI */
- if (MacType == SK_MAC_GMAC) {
- return (pPnmiPrt->StatRxPMaccErr);
- }
-
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
-
- /* SW counter managed by PNMI */
- case SK_PNMI_HTX_SYNC:
- LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
- HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
- break;
-
- /* SW counter managed by PNMI */
- case SK_PNMI_HTX_SYNC_OCTET:
- LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
- HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
- break;
-
- case SK_PNMI_HRX_FCS:
- /*
- * Broadcom filters FCS errors and counts it in
- * Receive Error Counter register
- */
- if (pPrt->PhyType == SK_PHY_BCOM) {
- /* do not read while not initialized (PHY_READ hangs!)*/
- if (pPrt->PState != SK_PRT_RESET) {
- SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
-
- LowVal = Word;
- }
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- }
- else {
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- }
- break;
-
- default:
- (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
- StatAddr[StatIndex][MacType].Reg,
- &LowVal);
- HighVal = pPnmiPrt->CounterHigh[StatIndex];
- break;
- }
-
- Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
-
- /* Correct value because of possible XMAC reset. XMAC Errata #2 */
- Val += pPnmiPrt->CounterOffset[StatIndex];
-
- return (Val);
-}
-
-/*****************************************************************************
- *
- * ResetCounter - Set all counters and timestamps to zero
- *
- * Description:
- * Notifies other common modules which store statistic data to
- * reset their counters and finally reset our own counters.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void ResetCounter(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-SK_U32 NetIndex)
-{
- unsigned int PhysPortIndex;
- SK_EVPARA EventParam;
-
-
- SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-
- /* Notify sensor module */
- SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
-
- /* Notify RLMT module */
- EventParam.Para32[0] = NetIndex;
- EventParam.Para32[1] = (SK_U32)-1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
- EventParam.Para32[1] = 0;
-
- /* Notify SIRQ module */
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
-
- /* Notify CSUM module */
-#ifdef SK_USE_CSUM
- EventParam.Para32[0] = NetIndex;
- EventParam.Para32[1] = (SK_U32)-1;
- SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
- EventParam);
-#endif /* SK_USE_CSUM */
-
- /* Clear XMAC statistic */
- for (PhysPortIndex = 0; PhysPortIndex <
- (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
-
- (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
-
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
- 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
- CounterOffset, 0, sizeof(pAC->Pnmi.Port[
- PhysPortIndex].CounterOffset));
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
- 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
- StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
- PhysPortIndex].StatSyncOctetsCts));
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
- StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
- PhysPortIndex].StatRxLongFrameCts));
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
- StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
- PhysPortIndex].StatRxFrameTooLongCts));
- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
- StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
- PhysPortIndex].StatRxPMaccErr));
- }
-
- /*
- * Clear local statistics
- */
- SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
- sizeof(pAC->Pnmi.VirtualCounterOffset));
- pAC->Pnmi.RlmtChangeCts = 0;
- pAC->Pnmi.RlmtChangeTime = 0;
- SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
- sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
- pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
- pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
- pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
- pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
- pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
- pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
- pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
- pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
- pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
- pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
- pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
- pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
-}
-
-/*****************************************************************************
- *
- * GetTrapEntry - Get an entry in the trap buffer
- *
- * Description:
- * The trap buffer stores various events. A user application somehow
- * gets notified that an event occured and retrieves the trap buffer
- * contens (or simply polls the buffer). The buffer is organized as
- * a ring which stores the newest traps at the beginning. The oldest
- * traps are overwritten by the newest ones. Each trap entry has a
- * unique number, so that applications may detect new trap entries.
- *
- * Returns:
- * A pointer to the trap entry
- */
-PNMI_STATIC char* GetTrapEntry(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_U32 TrapId, /* SNMP ID of the trap */
-unsigned int Size) /* Space needed for trap entry */
-{
- unsigned int BufPad = pAC->Pnmi.TrapBufPad;
- unsigned int BufFree = pAC->Pnmi.TrapBufFree;
- unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
- unsigned int End = pAC->Pnmi.TrapQueueEnd;
- char *pBuf = &pAC->Pnmi.TrapBuf[0];
- int Wrap;
- unsigned int NeededSpace;
- unsigned int EntrySize;
- SK_U32 Val32;
- SK_U64 Val64;
-
-
- /* Last byte of entry will get a copy of the entry length */
- Size ++;
-
- /*
- * Calculate needed buffer space */
- if (Beg >= Size) {
-
- NeededSpace = Size;
- Wrap = SK_FALSE;
- }
- else {
- NeededSpace = Beg + Size;
- Wrap = SK_TRUE;
- }
-
- /*
- * Check if enough buffer space is provided. Otherwise
- * free some entries. Leave one byte space between begin
- * and end of buffer to make it possible to detect whether
- * the buffer is full or empty
- */
- while (BufFree < NeededSpace + 1) {
-
- if (End == 0) {
-
- End = SK_PNMI_TRAP_QUEUE_LEN;
- }
-
- EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
- BufFree += EntrySize;
- End -= EntrySize;
-#ifdef DEBUG
- SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
-#endif /* DEBUG */
- if (End == BufPad) {
-#ifdef DEBUG
- SK_MEMSET(pBuf, (char)(-1), End);
-#endif /* DEBUG */
- BufFree += End;
- End = 0;
- BufPad = 0;
- }
- }
-
- /*
- * Insert new entry as first entry. Newest entries are
- * stored at the beginning of the queue.
- */
- if (Wrap) {
-
- BufPad = Beg;
- Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
- }
- else {
- Beg = Beg - Size;
- }
- BufFree -= NeededSpace;
-
- /* Save the current offsets */
- pAC->Pnmi.TrapQueueBeg = Beg;
- pAC->Pnmi.TrapQueueEnd = End;
- pAC->Pnmi.TrapBufPad = BufPad;
- pAC->Pnmi.TrapBufFree = BufFree;
-
- /* Initialize the trap entry */
- *(pBuf + Beg + Size - 1) = (char)Size;
- *(pBuf + Beg) = (char)Size;
- Val32 = (pAC->Pnmi.TrapUnique) ++;
- SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
- SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
- Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
- SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
-
- return (pBuf + Beg);
-}
-
-/*****************************************************************************
- *
- * CopyTrapQueue - Copies the trap buffer for the TRAP OID
- *
- * Description:
- * On a query of the TRAP OID the trap buffer contents will be
- * copied continuously to the request buffer, which must be large
- * enough. No length check is performed.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void CopyTrapQueue(
-SK_AC *pAC, /* Pointer to adapter context */
-char *pDstBuf) /* Buffer to which the queued traps will be copied */
-{
- unsigned int BufPad = pAC->Pnmi.TrapBufPad;
- unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
- unsigned int End = pAC->Pnmi.TrapQueueEnd;
- char *pBuf = &pAC->Pnmi.TrapBuf[0];
- unsigned int Len;
- unsigned int DstOff = 0;
-
-
- while (Trap != End) {
-
- Len = (unsigned int)*(pBuf + Trap);
-
- /*
- * Last byte containing a copy of the length will
- * not be copied.
- */
- *(pDstBuf + DstOff) = (char)(Len - 1);
- SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
- DstOff += Len - 1;
-
- Trap += Len;
- if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
-
- Trap = BufPad;
- }
- }
-}
-
-/*****************************************************************************
- *
- * GetTrapQueueLen - Get the length of the trap buffer
- *
- * Description:
- * Evaluates the number of currently stored traps and the needed
- * buffer size to retrieve them.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void GetTrapQueueLen(
-SK_AC *pAC, /* Pointer to adapter context */
-unsigned int *pLen, /* Length in Bytes of all queued traps */
-unsigned int *pEntries) /* Returns number of trapes stored in queue */
-{
- unsigned int BufPad = pAC->Pnmi.TrapBufPad;
- unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
- unsigned int End = pAC->Pnmi.TrapQueueEnd;
- char *pBuf = &pAC->Pnmi.TrapBuf[0];
- unsigned int Len;
- unsigned int Entries = 0;
- unsigned int TotalLen = 0;
-
-
- while (Trap != End) {
-
- Len = (unsigned int)*(pBuf + Trap);
- TotalLen += Len - 1;
- Entries ++;
-
- Trap += Len;
- if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
-
- Trap = BufPad;
- }
- }
-
- *pEntries = Entries;
- *pLen = TotalLen;
-}
-
-/*****************************************************************************
- *
- * QueueSimpleTrap - Store a simple trap to the trap buffer
- *
- * Description:
- * A simple trap is a trap with now additional data. It consists
- * simply of a trap code.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void QueueSimpleTrap(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_U32 TrapId) /* Type of sensor trap */
-{
- GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
-}
-
-/*****************************************************************************
- *
- * QueueSensorTrap - Stores a sensor trap in the trap buffer
- *
- * Description:
- * Gets an entry in the trap buffer and fills it with sensor related
- * data.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void QueueSensorTrap(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_U32 TrapId, /* Type of sensor trap */
-unsigned int SensorIndex) /* Index of sensor which caused the trap */
-{
- char *pBuf;
- unsigned int Offset;
- unsigned int DescrLen;
- SK_U32 Val32;
-
-
- /* Get trap buffer entry */
- DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
- pBuf = GetTrapEntry(pAC, TrapId,
- SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
- Offset = SK_PNMI_TRAP_SIMPLE_LEN;
-
- /* Store additionally sensor trap related data */
- Val32 = OID_SKGE_SENSOR_INDEX;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- *(pBuf + Offset + 4) = 4;
- Val32 = (SK_U32)SensorIndex;
- SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
- Offset += 9;
-
- Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- *(pBuf + Offset + 4) = (char)DescrLen;
- SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
- DescrLen);
- Offset += DescrLen + 5;
-
- Val32 = OID_SKGE_SENSOR_TYPE;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- *(pBuf + Offset + 4) = 1;
- *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
- Offset += 6;
-
- Val32 = OID_SKGE_SENSOR_VALUE;
- SK_PNMI_STORE_U32(pBuf + Offset, Val32);
- *(pBuf + Offset + 4) = 4;
- Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
- SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
-}
-
-/*****************************************************************************
- *
- * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
- *
- * Description:
- * Nothing further to explain.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void QueueRlmtNewMacTrap(
-SK_AC *pAC, /* Pointer to adapter context */
-unsigned int ActiveMac) /* Index (0..n) of the currently active port */
-{
- char *pBuf;
- SK_U32 Val32;
-
-
- pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
- SK_PNMI_TRAP_RLMT_CHANGE_LEN);
-
- Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
- SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
- *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
- *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
-}
-
-/*****************************************************************************
- *
- * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
- *
- * Description:
- * Nothing further to explain.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void QueueRlmtPortTrap(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_U32 TrapId, /* Type of RLMT port trap */
-unsigned int PortIndex) /* Index of the port, which changed its state */
-{
- char *pBuf;
- SK_U32 Val32;
-
-
- pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
-
- Val32 = OID_SKGE_RLMT_PORT_INDEX;
- SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
- *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
- *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
-}
-
-/*****************************************************************************
- *
- * CopyMac - Copies a MAC address
- *
- * Description:
- * Nothing further to explain.
- *
- * Returns:
- * Nothing
- */
-PNMI_STATIC void CopyMac(
-char *pDst, /* Pointer to destination buffer */
-SK_MAC_ADDR *pMac) /* Pointer of Source */
-{
- int i;
-
-
- for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
-
- *(pDst + i) = pMac->a[i];
- }
-}
-
-#ifdef SK_POWER_MGMT
-/*****************************************************************************
- *
- * PowerManagement - OID handler function of PowerManagement OIDs
- *
- * Description:
- * The code is simple. No description necessary.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-
-PNMI_STATIC int PowerManagement(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* Get/PreSet/Set action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer to which to mgmt data will be retrieved */
-unsigned int *pLen, /* On call: buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
-{
-
- SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
-
- /*
- * Check instance. We only handle single instance variables
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
-
- /* Check length */
- switch (Id) {
-
- case OID_PNP_CAPABILITIES:
- if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
-
- *pLen = sizeof(SK_PNP_CAPABILITIES);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_PNP_SET_POWER:
- case OID_PNP_QUERY_POWER:
- if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
- {
- *pLen = sizeof(SK_DEVICE_POWER_STATE);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_PNP_ADD_WAKE_UP_PATTERN:
- case OID_PNP_REMOVE_WAKE_UP_PATTERN:
- if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
-
- *pLen = sizeof(SK_PM_PACKET_PATTERN);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_PNP_ENABLE_WAKE_UP:
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
- }
-
- /*
- * Perform action
- */
- if (Action == SK_PNMI_GET) {
-
- /*
- * Get value
- */
- switch (Id) {
-
- case OID_PNP_CAPABILITIES:
- RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
- break;
-
- case OID_PNP_QUERY_POWER:
- /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
- the miniport to indicate whether it can transition its NIC
- to the low-power state.
- A miniport driver must always return NDIS_STATUS_SUCCESS
- to a query of OID_PNP_QUERY_POWER. */
- *pLen = sizeof(SK_DEVICE_POWER_STATE);
- RetCode = SK_PNMI_ERR_OK;
- break;
-
- /* NDIS handles these OIDs as write-only.
- * So in case of get action the buffer with written length = 0
- * is returned
- */
- case OID_PNP_SET_POWER:
- case OID_PNP_ADD_WAKE_UP_PATTERN:
- case OID_PNP_REMOVE_WAKE_UP_PATTERN:
- *pLen = 0;
- RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
- break;
-
- case OID_PNP_ENABLE_WAKE_UP:
- RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
- break;
-
- default:
- RetCode = SK_PNMI_ERR_GENERAL;
- break;
- }
-
- return (RetCode);
- }
-
-
- /*
- * Perform preset or set
- */
-
- /* POWER module does not support PRESET action */
- if (Action == SK_PNMI_PRESET) {
- return (SK_PNMI_ERR_OK);
- }
-
- switch (Id) {
- case OID_PNP_SET_POWER:
- RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
- break;
-
- case OID_PNP_ADD_WAKE_UP_PATTERN:
- RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
- break;
-
- case OID_PNP_REMOVE_WAKE_UP_PATTERN:
- RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
- break;
-
- case OID_PNP_ENABLE_WAKE_UP:
- RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
- break;
-
- default:
- RetCode = SK_PNMI_ERR_READ_ONLY;
- }
-
- return (RetCode);
-}
-#endif /* SK_POWER_MGMT */
-
-#ifdef SK_DIAG_SUPPORT
-/*****************************************************************************
- *
- * DiagActions - OID handler function of Diagnostic driver
- *
- * Description:
- * The code is simple. No description necessary.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-
-PNMI_STATIC int DiagActions(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
-
- SK_U32 DiagStatus;
- SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
-
- /*
- * Check instance. We only handle single instance variables.
- */
- if (Instance != (SK_U32)(-1) && Instance != 1) {
-
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- /*
- * Check length.
- */
- switch (Id) {
-
- case OID_SKGE_DIAG_MODE:
- if (*pLen < sizeof(SK_U32)) {
-
- *pLen = sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /* Perform action. */
-
- /* GET value. */
- if (Action == SK_PNMI_GET) {
-
- switch (Id) {
-
- case OID_SKGE_DIAG_MODE:
- DiagStatus = pAC->Pnmi.DiagAttached;
- SK_PNMI_STORE_U32(pBuf, DiagStatus);
- *pLen = sizeof(SK_U32);
- RetCode = SK_PNMI_ERR_OK;
- break;
-
- default:
- *pLen = 0;
- RetCode = SK_PNMI_ERR_GENERAL;
- break;
- }
- return (RetCode);
- }
-
- /* From here SET or PRESET value. */
-
- /* PRESET value is not supported. */
- if (Action == SK_PNMI_PRESET) {
- return (SK_PNMI_ERR_OK);
- }
-
- /* SET value. */
- switch (Id) {
- case OID_SKGE_DIAG_MODE:
-
- /* Handle the SET. */
- switch (*pBuf) {
-
- /* Attach the DIAG to this adapter. */
- case SK_DIAG_ATTACHED:
- /* Check if we come from running */
- if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
-
- RetCode = SkDrvLeaveDiagMode(pAC);
-
- }
- else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
-
- RetCode = SK_PNMI_ERR_OK;
- }
-
- else {
-
- RetCode = SK_PNMI_ERR_GENERAL;
-
- }
-
- if (RetCode == SK_PNMI_ERR_OK) {
-
- pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
- }
- break;
-
- /* Enter the DIAG mode in the driver. */
- case SK_DIAG_RUNNING:
- RetCode = SK_PNMI_ERR_OK;
-
- /*
- * If DiagAttached is set, we can tell the driver
- * to enter the DIAG mode.
- */
- if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
- /* If DiagMode is not active, we can enter it. */
- if (!pAC->DiagModeActive) {
-
- RetCode = SkDrvEnterDiagMode(pAC);
- }
- else {
-
- RetCode = SK_PNMI_ERR_GENERAL;
- }
- }
- else {
-
- RetCode = SK_PNMI_ERR_GENERAL;
- }
-
- if (RetCode == SK_PNMI_ERR_OK) {
-
- pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
- }
- break;
-
- case SK_DIAG_IDLE:
- /* Check if we come from running */
- if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
-
- RetCode = SkDrvLeaveDiagMode(pAC);
-
- }
- else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
-
- RetCode = SK_PNMI_ERR_OK;
- }
-
- else {
-
- RetCode = SK_PNMI_ERR_GENERAL;
-
- }
-
- if (RetCode == SK_PNMI_ERR_OK) {
-
- pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
- }
- break;
-
- default:
- RetCode = SK_PNMI_ERR_BAD_VALUE;
- break;
- }
- break;
-
- default:
- RetCode = SK_PNMI_ERR_GENERAL;
- }
-
- if (RetCode == SK_PNMI_ERR_OK) {
- *pLen = sizeof(SK_U32);
- }
- else {
-
- *pLen = 0;
- }
- return (RetCode);
-}
-#endif /* SK_DIAG_SUPPORT */
-
-/*****************************************************************************
- *
- * Vct - OID handler function of OIDs
- *
- * Description:
- * The code is simple. No description necessary.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was performed successfully.
- * SK_PNMI_ERR_GENERAL A general severe internal error occured.
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
- * the correct data (e.g. a 32bit value is
- * needed, but a 16 bit value was passed).
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter).
- * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
- *
- */
-
-PNMI_STATIC int Vct(
-SK_AC *pAC, /* Pointer to adapter context */
-SK_IOC IoC, /* IO context handle */
-int Action, /* GET/PRESET/SET action */
-SK_U32 Id, /* Object ID that is to be processed */
-char *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
-SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
-unsigned int TableIndex, /* Index to the Id table */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
- SK_GEPORT *pPrt;
- SK_PNMI_VCT *pVctBackupData;
- SK_U32 LogPortMax;
- SK_U32 PhysPortMax;
- SK_U32 PhysPortIndex;
- SK_U32 Limit;
- SK_U32 Offset;
- SK_BOOL Link;
- SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
- int i;
- SK_EVPARA Para;
- SK_U32 CableLength;
-
- /*
- * Calculate the port indexes from the instance.
- */
- PhysPortMax = pAC->GIni.GIMacsFound;
- LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
-
- /* Dual net mode? */
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- LogPortMax--;
- }
-
- if ((Instance != (SK_U32) (-1))) {
- /* Check instance range. */
- if ((Instance < 2) || (Instance > LogPortMax)) {
- *pLen = 0;
- return (SK_PNMI_ERR_UNKNOWN_INST);
- }
-
- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
- PhysPortIndex = NetIndex;
- }
- else {
- PhysPortIndex = Instance - 2;
- }
- Limit = PhysPortIndex + 1;
- }
- else {
- /*
- * Instance == (SK_U32) (-1), get all Instances of that OID.
- *
- * Not implemented yet. May be used in future releases.
- */
- PhysPortIndex = 0;
- Limit = PhysPortMax;
- }
-
- pPrt = &pAC->GIni.GP[PhysPortIndex];
- if (pPrt->PHWLinkUp) {
- Link = SK_TRUE;
- }
- else {
- Link = SK_FALSE;
- }
-
- /* Check MAC type */
- if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /* Initialize backup data pointer. */
- pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-
- /* Check action type */
- if (Action == SK_PNMI_GET) {
- /* Check length */
- switch (Id) {
-
- case OID_SKGE_VCT_GET:
- if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
- *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- case OID_SKGE_VCT_STATUS:
- if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
- *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /* Get value */
- Offset = 0;
- for (; PhysPortIndex < Limit; PhysPortIndex++) {
- switch (Id) {
-
- case OID_SKGE_VCT_GET:
- if ((Link == SK_FALSE) &&
- (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
- RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
- if (RetCode == 0) {
- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
- pAC->Pnmi.VctStatus[PhysPortIndex] |=
- (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
-
- /* Copy results for later use to PNMI struct. */
- for (i = 0; i < 4; i++) {
- if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
- if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
- pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
- }
- }
- if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
- CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
- }
- else {
- CableLength = 0;
- }
- pVctBackupData->PMdiPairLen[i] = CableLength;
- pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
- }
-
- Para.Para32[0] = PhysPortIndex;
- Para.Para32[1] = -1;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
- SkEventDispatcher(pAC, IoC);
- }
- else {
- ; /* VCT test is running. */
- }
- }
-
- /* Get all results. */
- CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
- Offset += sizeof(SK_U8);
- *(pBuf + Offset) = pPrt->PCableLen;
- Offset += sizeof(SK_U8);
- for (i = 0; i < 4; i++) {
- SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
- Offset += sizeof(SK_U32);
- }
- for (i = 0; i < 4; i++) {
- *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
- Offset += sizeof(SK_U8);
- }
-
- RetCode = SK_PNMI_ERR_OK;
- break;
-
- case OID_SKGE_VCT_STATUS:
- CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
- Offset += sizeof(SK_U8);
- RetCode = SK_PNMI_ERR_OK;
- break;
-
- default:
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- } /* for */
- *pLen = Offset;
- return (RetCode);
-
- } /* if SK_PNMI_GET */
-
- /*
- * From here SET or PRESET action. Check if the passed
- * buffer length is plausible.
- */
-
- /* Check length */
- switch (Id) {
- case OID_SKGE_VCT_SET:
- if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
- *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
- return (SK_PNMI_ERR_TOO_SHORT);
- }
- break;
-
- default:
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
-
- /*
- * Perform preset or set.
- */
-
- /* VCT does not support PRESET action. */
- if (Action == SK_PNMI_PRESET) {
- return (SK_PNMI_ERR_OK);
- }
-
- Offset = 0;
- for (; PhysPortIndex < Limit; PhysPortIndex++) {
- switch (Id) {
- case OID_SKGE_VCT_SET: /* Start VCT test. */
- if (Link == SK_FALSE) {
- SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
-
- RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
- if (RetCode == 0) { /* RetCode: 0 => Start! */
- pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
-
- /*
- * Start VCT timer counter.
- */
- SK_MEMSET((char *) &Para, 0, sizeof(Para));
- Para.Para32[0] = PhysPortIndex;
- Para.Para32[1] = -1;
- SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
- 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
- SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
- RetCode = SK_PNMI_ERR_OK;
- }
- else { /* RetCode: 2 => Running! */
- SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
- RetCode = SK_PNMI_ERR_OK;
- }
- }
- else { /* RetCode: 4 => Link! */
- RetCode = 4;
- SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
- RetCode = SK_PNMI_ERR_OK;
- }
- Offset += sizeof(SK_U32);
- break;
-
- default:
- *pLen = 0;
- return (SK_PNMI_ERR_GENERAL);
- }
- } /* for */
- *pLen = Offset;
- return (RetCode);
-
-} /* Vct */
-
-
-PNMI_STATIC void CheckVctStatus(
-SK_AC *pAC,
-SK_IOC IoC,
-char *pBuf,
-SK_U32 Offset,
-SK_U32 PhysPortIndex)
-{
- SK_GEPORT *pPrt;
- SK_PNMI_VCT *pVctData;
- SK_U32 RetCode;
-
- pPrt = &pAC->GIni.GP[PhysPortIndex];
-
- pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
- pVctData->VctStatus = SK_PNMI_VCT_NONE;
-
- if (!pPrt->PHWLinkUp) {
-
- /* Was a VCT test ever made before? */
- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
- if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
- pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
- }
- else {
- pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
- }
- }
-
- /* Check VCT test status. */
- RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
- if (RetCode == 2) { /* VCT test is running. */
- pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
- }
- else { /* VCT data was copied to pAC here. Check PENDING state. */
- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
- pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
- }
- }
-
- if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
- pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
- }
- }
- else {
-
- /* Was a VCT test ever made before? */
- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
- pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
- pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
- }
-
- /* DSP only valid in 100/1000 modes. */
- if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
- SK_LSPEED_STAT_10MBPS) {
- pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
- }
- }
-} /* CheckVctStatus */
-
-
-/*****************************************************************************
- *
- * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
- * PNMI function depending on the subcommand and
- * returns all data belonging to the complete database
- * or OID request.
- *
- * Description:
- * Looks up the requested subcommand, calls the corresponding handler
- * function and passes all required parameters to it.
- * The function is called by the driver. It is needed to handle the new
- * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
- * the OID and a subcommand to decide what kind of request has to be done.
- *
- * Returns:
- * SK_PNMI_ERR_OK The request was successfully performed
- * SK_PNMI_ERR_GENERAL A general severe internal error occured
- * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
- * the data.
- * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
- * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
- * exist (e.g. port instance 3 on a two port
- * adapter.
- */
-int SkPnmiGenIoctl(
-SK_AC *pAC, /* Pointer to adapter context struct */
-SK_IOC IoC, /* I/O context */
-void *pBuf, /* Buffer used for the management data transfer */
-unsigned int *pLen, /* Length of buffer */
-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
-{
-SK_I32 Mode; /* Store value of subcommand. */
-SK_U32 Oid; /* Store value of OID. */
-int ReturnCode; /* Store return value to show status of PNMI action. */
-int HeaderLength; /* Length of desired action plus OID. */
-
- ReturnCode = SK_PNMI_ERR_GENERAL;
-
- SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
- SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
- HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
- *pLen = *pLen - HeaderLength;
- SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
-
- switch(Mode) {
- case SK_GET_SINGLE_VAR:
- ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
- (char *) pBuf + sizeof(SK_I32), pLen,
- ((SK_U32) (-1)), NetIndex);
- SK_PNMI_STORE_U32(pBuf, ReturnCode);
- *pLen = *pLen + sizeof(SK_I32);
- break;
- case SK_PRESET_SINGLE_VAR:
- ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
- (char *) pBuf + sizeof(SK_I32), pLen,
- ((SK_U32) (-1)), NetIndex);
- SK_PNMI_STORE_U32(pBuf, ReturnCode);
- *pLen = *pLen + sizeof(SK_I32);
- break;
- case SK_SET_SINGLE_VAR:
- ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
- (char *) pBuf + sizeof(SK_I32), pLen,
- ((SK_U32) (-1)), NetIndex);
- SK_PNMI_STORE_U32(pBuf, ReturnCode);
- *pLen = *pLen + sizeof(SK_I32);
- break;
- case SK_GET_FULL_MIB:
- ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
- break;
- case SK_PRESET_FULL_MIB:
- ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
- break;
- case SK_SET_FULL_MIB:
- ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
- break;
- default:
- break;
- }
-
- return (ReturnCode);
-
-} /* SkGeIocGen */
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
deleted file mode 100644
index 3e7aa49afd00..000000000000
--- a/drivers/net/sk98lin/skgesirq.c
+++ /dev/null
@@ -1,2229 +0,0 @@
-/******************************************************************************
- *
- * Name: skgesirq.c
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.92 $
- * Date: $Date: 2003/09/16 14:37:07 $
- * Purpose: Special IRQ module
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * Special Interrupt handler
- *
- * The following abstract should show how this module is included
- * in the driver path:
- *
- * In the ISR of the driver the bits for frame transmission complete and
- * for receive complete are checked and handled by the driver itself.
- * The bits of the slow path mask are checked after that and then the
- * entry into the so-called "slow path" is prepared. It is an implementors
- * decision whether this is executed directly or just scheduled by
- * disabling the mask. In the interrupt service routine some events may be
- * generated, so it would be a good idea to call the EventDispatcher
- * right after this ISR.
- *
- * The Interrupt source register of the adapter is NOT read by this module.
- * SO if the drivers implementor needs a while loop around the
- * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
- * each loop entered.
- *
- * However, the MAC Interrupt status registers are read in a while loop.
- *
- */
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h" /* Driver Specific Definitions */
-#ifndef SK_SLIM
-#include "h/skgepnmi.h" /* PNMI Definitions */
-#include "h/skrlmt.h" /* RLMT Definitions */
-#endif
-#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
-
-/* local function prototypes */
-#ifdef GENESIS
-static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);
-static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* GENESIS */
-#ifdef YUKON
-static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* YUKON */
-#ifdef OTHER_PHY
-static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);
-static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);
-static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
-#endif /* OTHER_PHY */
-
-#ifdef GENESIS
-/*
- * array of Rx counter from XMAC which are checked
- * in AutoSense mode to check whether a link is not able to auto-negotiate.
- */
-static const SK_U16 SkGeRxRegs[]= {
- XM_RXF_64B,
- XM_RXF_127B,
- XM_RXF_255B,
- XM_RXF_511B,
- XM_RXF_1023B,
- XM_RXF_MAX_SZ
-} ;
-#endif /* GENESIS */
-
-#ifdef __C2MAN__
-/*
- * Special IRQ function
- *
- * General Description:
- *
- */
-intro()
-{}
-#endif
-
-/******************************************************************************
- *
- * SkHWInitDefSense() - Default Autosensing mode initialization
- *
- * Description: sets the PLinkMode for HWInit
- *
- * Returns: N/A
- */
-static void SkHWInitDefSense(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
-
- pPrt = &pAC->GIni.GP[Port];
-
- pPrt->PAutoNegTimeOut = 0;
-
- if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
- pPrt->PLinkMode = pPrt->PLinkModeConf;
- return;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("AutoSensing: First mode %d on Port %d\n",
- (int)SK_LMODE_AUTOFULL, Port));
-
- pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
-
- return;
-} /* SkHWInitDefSense */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkHWSenseGetNext() - Get Next Autosensing Mode
- *
- * Description: gets the appropriate next mode
- *
- * Note:
- *
- */
-static SK_U8 SkHWSenseGetNext(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
-
- pPrt = &pAC->GIni.GP[Port];
-
- pPrt->PAutoNegTimeOut = 0;
-
- if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
- /* Leave all as configured */
- return(pPrt->PLinkModeConf);
- }
-
- if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
- /* Return next mode AUTOBOTH */
- return ((SK_U8)SK_LMODE_AUTOBOTH);
- }
-
- /* Return default autofull */
- return ((SK_U8)SK_LMODE_AUTOFULL);
-} /* SkHWSenseGetNext */
-
-
-/******************************************************************************
- *
- * SkHWSenseSetNext() - Autosensing Set next mode
- *
- * Description: sets the appropriate next mode
- *
- * Returns: N/A
- */
-static void SkHWSenseSetNext(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_U8 NewMode) /* New Mode to be written in sense mode */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
-
- pPrt = &pAC->GIni.GP[Port];
-
- pPrt->PAutoNegTimeOut = 0;
-
- if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
- return;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("AutoSensing: next mode %d on Port %d\n",
- (int)NewMode, Port));
-
- pPrt->PLinkMode = NewMode;
-
- return;
-} /* SkHWSenseSetNext */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- * SkHWLinkDown() - Link Down handling
- *
- * Description: handles the hardware link down signal
- *
- * Returns: N/A
- */
-void SkHWLinkDown(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* Disable all MAC interrupts */
- SkMacIrqDisable(pAC, IoC, Port);
-
- /* Disable Receiver and Transmitter */
- SkMacRxTxDisable(pAC, IoC, Port);
-
- /* Init default sense mode */
- SkHWInitDefSense(pAC, IoC, Port);
-
- if (pPrt->PHWLinkUp == SK_FALSE) {
- return;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link down Port %d\n", Port));
-
- /* Set Link to DOWN */
- pPrt->PHWLinkUp = SK_FALSE;
-
- /* Reset Port stati */
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
- pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
-
- /* Re-init Phy especially when the AutoSense default is set now */
- SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
-
- /* GP0: used for workaround of Rev. C Errata 2 */
-
- /* Do NOT signal to RLMT */
-
- /* Do NOT start the timer here */
-} /* SkHWLinkDown */
-
-
-/******************************************************************************
- *
- * SkHWLinkUp() - Link Up handling
- *
- * Description: handles the hardware link up signal
- *
- * Returns: N/A
- */
-static void SkHWLinkUp(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PHWLinkUp) {
- /* We do NOT need to proceed on active link */
- return;
- }
-
- pPrt->PHWLinkUp = SK_TRUE;
- pPrt->PAutoNegFail = SK_FALSE;
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
-
- if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
- pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
- pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
- /* Link is up and no Auto-negotiation should be done */
-
- /* Link speed should be the configured one */
- switch (pPrt->PLinkSpeed) {
- case SK_LSPEED_AUTO:
- /* default is 1000 Mbps */
- case SK_LSPEED_1000MBPS:
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
- break;
- case SK_LSPEED_100MBPS:
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
- break;
- case SK_LSPEED_10MBPS:
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
- break;
- }
-
- /* Set Link Mode Status */
- if (pPrt->PLinkMode == SK_LMODE_FULL) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
- }
- else {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
- }
-
- /* No flow control without auto-negotiation */
- pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
-
- /* enable Rx/Tx */
- (void)SkMacRxTxEnable(pAC, IoC, Port);
- }
-} /* SkHWLinkUp */
-
-
-/******************************************************************************
- *
- * SkMacParity() - MAC parity workaround
- *
- * Description: handles MAC parity errors correctly
- *
- * Returns: N/A
- */
-static void SkMacParity(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index of the port failed */
-{
- SK_EVPARA Para;
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- SK_U32 TxMax; /* Tx Max Size Counter */
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* Clear IRQ Tx Parity Error */
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
- SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
- (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&
- pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
- }
-#endif /* YUKON */
-
- if (pPrt->PCheckPar) {
-
- if (Port == MAC_1) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
- }
- else {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
- }
- Para.Para64 = Port;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-
- Para.Para32[0] = Port;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
- return;
- }
-
- /* Check whether frames with a size of 1k were sent */
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* Snap statistic counters */
- (void)SkXmUpdateStats(pAC, IoC, Port);
-
- (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
- }
-#endif /* YUKON */
-
- if (TxMax > 0) {
- /* From now on check the parity */
- pPrt->PCheckPar = SK_TRUE;
- }
-} /* SkMacParity */
-
-
-/******************************************************************************
- *
- * SkGeHwErr() - Hardware Error service routine
- *
- * Description: handles all HW Error interrupts
- *
- * Returns: N/A
- */
-static void SkGeHwErr(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-SK_U32 HwStatus) /* Interrupt status word */
-{
- SK_EVPARA Para;
- SK_U16 Word;
-
- if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
- /* PCI Errors occured */
- if ((HwStatus & IS_IRQ_STAT) != 0) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
- }
- else {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
- }
-
- /* Reset all bits in the PCI STATUS register */
- SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-
- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
- Para.Para64 = 0;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
- }
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- if ((HwStatus & IS_NO_STAT_M1) != 0) {
- /* Ignore it */
- /* This situation is also indicated in the descriptor */
- SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
- }
-
- if ((HwStatus & IS_NO_STAT_M2) != 0) {
- /* Ignore it */
- /* This situation is also indicated in the descriptor */
- SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
- }
-
- if ((HwStatus & IS_NO_TIST_M1) != 0) {
- /* Ignore it */
- /* This situation is also indicated in the descriptor */
- SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
- }
-
- if ((HwStatus & IS_NO_TIST_M2) != 0) {
- /* Ignore it */
- /* This situation is also indicated in the descriptor */
- SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* This is necessary only for Rx timing measurements */
- if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
- /* increment Time Stamp Timer counter (high) */
- pAC->GIni.GITimeStampCnt++;
-
- /* Clear Time Stamp Timer IRQ */
- SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
- }
-
- if ((HwStatus & IS_IRQ_SENSOR) != 0) {
- /* no sensors on 32-bit Yukon */
- if (pAC->GIni.GIYukon32Bit) {
- /* disable HW Error IRQ */
- pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
- }
- }
- }
-#endif /* YUKON */
-
- if ((HwStatus & IS_RAM_RD_PAR) != 0) {
- SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
- Para.Para64 = 0;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
- }
-
- if ((HwStatus & IS_RAM_WR_PAR) != 0) {
- SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
- Para.Para64 = 0;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
- }
-
- if ((HwStatus & IS_M1_PAR_ERR) != 0) {
- SkMacParity(pAC, IoC, MAC_1);
- }
-
- if ((HwStatus & IS_M2_PAR_ERR) != 0) {
- SkMacParity(pAC, IoC, MAC_2);
- }
-
- if ((HwStatus & IS_R1_PAR_ERR) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
-
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
- Para.Para64 = MAC_1;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-
- Para.Para32[0] = MAC_1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((HwStatus & IS_R2_PAR_ERR) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
-
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
- Para.Para64 = MAC_2;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-
- Para.Para32[0] = MAC_2;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-} /* SkGeHwErr */
-
-
-/******************************************************************************
- *
- * SkGeSirqIsr() - Special Interrupt Service Routine
- *
- * Description: handles all non data transfer specific interrupts (slow path)
- *
- * Returns: N/A
- */
-void SkGeSirqIsr(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-SK_U32 Istatus) /* Interrupt status word */
-{
- SK_EVPARA Para;
- SK_U32 RegVal32; /* Read register value */
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- SK_U16 PhyInt;
- int i;
-
- if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
- /* read the HW Error Interrupt source */
- SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
-
- SkGeHwErr(pAC, IoC, RegVal32);
- }
-
- /*
- * Packet Timeout interrupts
- */
- /* Check whether MACs are correctly initialized */
- if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
- pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
- /* MAC 1 was not initialized but Packet timeout occured */
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
- SKERR_SIRQ_E004MSG);
- }
-
- if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
- pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
- /* MAC 2 was not initialized but Packet timeout occured */
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
- SKERR_SIRQ_E005MSG);
- }
-
- if ((Istatus & IS_PA_TO_RX1) != 0) {
- /* Means network is filling us up */
- SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
- SKERR_SIRQ_E002MSG);
- SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
- }
-
- if ((Istatus & IS_PA_TO_RX2) != 0) {
- /* Means network is filling us up */
- SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
- SKERR_SIRQ_E003MSG);
- SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
- }
-
- if ((Istatus & IS_PA_TO_TX1) != 0) {
-
- pPrt = &pAC->GIni.GP[0];
-
- /* May be a normal situation in a server with a slow network */
- SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /*
- * workaround: if in half duplex mode, check for Tx hangup.
- * Read number of TX'ed bytes, wait for 10 ms, then compare
- * the number with current value. If nothing changed, we assume
- * that Tx is hanging and do a FIFO flush (see event routine).
- */
- if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
- pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
- !pPrt->HalfDupTimerActive) {
- /*
- * many more pack. arb. timeouts may come in between,
- * we ignore those
- */
- pPrt->HalfDupTimerActive = SK_TRUE;
- /* Snap statistic counters */
- (void)SkXmUpdateStats(pAC, IoC, 0);
-
- (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
-
- pPrt->LastOctets = (SK_U64)RegVal32 << 32;
-
- (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
-
- pPrt->LastOctets += RegVal32;
-
- Para.Para32[0] = 0;
- SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
- SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
- }
- }
-#endif /* GENESIS */
- }
-
- if ((Istatus & IS_PA_TO_TX2) != 0) {
-
- pPrt = &pAC->GIni.GP[1];
-
- /* May be a normal situation in a server with a slow network */
- SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* workaround: see above */
- if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
- pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
- !pPrt->HalfDupTimerActive) {
- pPrt->HalfDupTimerActive = SK_TRUE;
- /* Snap statistic counters */
- (void)SkXmUpdateStats(pAC, IoC, 1);
-
- (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
-
- pPrt->LastOctets = (SK_U64)RegVal32 << 32;
-
- (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
-
- pPrt->LastOctets += RegVal32;
-
- Para.Para32[0] = 1;
- SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
- SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
- }
- }
-#endif /* GENESIS */
- }
-
- /* Check interrupts of the particular queues */
- if ((Istatus & IS_R1_C) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
- SKERR_SIRQ_E006MSG);
- Para.Para64 = MAC_1;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
- Para.Para32[0] = MAC_1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((Istatus & IS_R2_C) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
- SKERR_SIRQ_E007MSG);
- Para.Para64 = MAC_2;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
- Para.Para32[0] = MAC_2;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((Istatus & IS_XS1_C) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
- SKERR_SIRQ_E008MSG);
- Para.Para64 = MAC_1;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
- Para.Para32[0] = MAC_1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((Istatus & IS_XA1_C) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
- SKERR_SIRQ_E009MSG);
- Para.Para64 = MAC_1;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
- Para.Para32[0] = MAC_1;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((Istatus & IS_XS2_C) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
- SKERR_SIRQ_E010MSG);
- Para.Para64 = MAC_2;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
- Para.Para32[0] = MAC_2;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((Istatus & IS_XA2_C) != 0) {
- /* Clear IRQ */
- SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
- SKERR_SIRQ_E011MSG);
- Para.Para64 = MAC_2;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
- Para.Para32[0] = MAC_2;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- /* External reg interrupt */
- if ((Istatus & IS_EXT_REG) != 0) {
- /* Test IRQs from PHY */
- for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-
- pPrt = &pAC->GIni.GP[i];
-
- if (pPrt->PState == SK_PRT_RESET) {
- continue;
- }
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- switch (pPrt->PhyType) {
-
- case SK_PHY_XMAC:
- break;
-
- case SK_PHY_BCOM:
- SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
-
- if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Port %d Bcom Int: 0x%04X\n",
- i, PhyInt));
- SkPhyIsrBcom(pAC, IoC, i, PhyInt);
- }
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
-
- if ((PhyInt & PHY_L_DEF_MSK) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Port %d Lone Int: %x\n",
- i, PhyInt));
- SkPhyIsrLone(pAC, IoC, i, PhyInt);
- }
- break;
-#endif /* OTHER_PHY */
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* Read PHY Interrupt Status */
- SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
-
- if ((PhyInt & PHY_M_DEF_MSK) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Port %d Marv Int: 0x%04X\n",
- i, PhyInt));
- SkPhyIsrGmac(pAC, IoC, i, PhyInt);
- }
- }
-#endif /* YUKON */
- }
- }
-
- /* I2C Ready interrupt */
- if ((Istatus & IS_I2C_READY) != 0) {
-#ifdef SK_SLIM
- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-#else
- SkI2cIsr(pAC, IoC);
-#endif
- }
-
- /* SW forced interrupt */
- if ((Istatus & IS_IRQ_SW) != 0) {
- /* clear the software IRQ */
- SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
- }
-
- if ((Istatus & IS_LNK_SYNC_M1) != 0) {
- /*
- * We do NOT need the Link Sync interrupt, because it shows
- * us only a link going down.
- */
- /* clear interrupt */
- SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
- }
-
- /* Check MAC after link sync counter */
- if ((Istatus & IS_MAC1) != 0) {
- /* IRQ from MAC 1 */
- SkMacIrq(pAC, IoC, MAC_1);
- }
-
- if ((Istatus & IS_LNK_SYNC_M2) != 0) {
- /*
- * We do NOT need the Link Sync interrupt, because it shows
- * us only a link going down.
- */
- /* clear interrupt */
- SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
- }
-
- /* Check MAC after link sync counter */
- if ((Istatus & IS_MAC2) != 0) {
- /* IRQ from MAC 2 */
- SkMacIrq(pAC, IoC, MAC_2);
- }
-
- /* Timer interrupt (served last) */
- if ((Istatus & IS_TIMINT) != 0) {
- /* check for HW Errors */
- if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
- /* read the HW Error Interrupt source */
- SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
-
- SkGeHwErr(pAC, IoC, RegVal32);
- }
-
- SkHwtIsr(pAC, IoC);
- }
-
-} /* SkGeSirqIsr */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- */
-static int SkGePortCheckShorts(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port) /* Which port should be checked */
-{
- SK_U32 Shorts; /* Short Event Counter */
- SK_U32 CheckShorts; /* Check value for Short Event Counter */
- SK_U64 RxCts; /* Rx Counter (packets on network) */
- SK_U32 RxTmp; /* Rx temp. Counter */
- SK_U32 FcsErrCts; /* FCS Error Counter */
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- int Rtv; /* Return value */
- int i;
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* Default: no action */
- Rtv = SK_HW_PS_NONE;
-
- (void)SkXmUpdateStats(pAC, IoC, Port);
-
- /* Extra precaution: check for short Event counter */
- (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
-
- /*
- * Read Rx counters (packets seen on the network and not necessarily
- * really received.
- */
- RxCts = 0;
-
- for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
-
- (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
-
- RxCts += (SK_U64)RxTmp;
- }
-
- /* On default: check shorts against zero */
- CheckShorts = 0;
-
- /* Extra precaution on active links */
- if (pPrt->PHWLinkUp) {
- /* Reset Link Restart counter */
- pPrt->PLinkResCt = 0;
- pPrt->PAutoNegTOCt = 0;
-
- /* If link is up check for 2 */
- CheckShorts = 2;
-
- (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
-
- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
- pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
- (pPrt->PLinkMode == SK_LMODE_HALF ||
- pPrt->PLinkMode == SK_LMODE_FULL)) {
- /*
- * This is autosensing and we are in the fallback
- * manual full/half duplex mode.
- */
- if (RxCts == pPrt->PPrevRx) {
- /* Nothing received, restart link */
- pPrt->PPrevFcs = FcsErrCts;
- pPrt->PPrevShorts = Shorts;
-
- return(SK_HW_PS_RESTART);
- }
- else {
- pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
- }
- }
-
- if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
- (!(FcsErrCts - pPrt->PPrevFcs))) {
- /*
- * Note: The compare with zero above has to be done the way shown,
- * otherwise the Linux driver will have a problem.
- */
- /*
- * We received a bunch of frames or no CRC error occured on the
- * network -> ok.
- */
- pPrt->PPrevRx = RxCts;
- pPrt->PPrevFcs = FcsErrCts;
- pPrt->PPrevShorts = Shorts;
-
- return(SK_HW_PS_NONE);
- }
-
- pPrt->PPrevFcs = FcsErrCts;
- }
-
-
- if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Short Event Count Restart Port %d \n", Port));
- Rtv = SK_HW_PS_RESTART;
- }
-
- pPrt->PPrevShorts = Shorts;
- pPrt->PPrevRx = RxCts;
-
- return(Rtv);
-} /* SkGePortCheckShorts */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUp() - Check if the link is up
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- * 2 Link came up
- */
-static int SkGePortCheckUp(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port) /* Which port should be checked */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
- int Rtv; /* Return value */
-
- Rtv = SK_HW_PS_NONE;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
- AutoNeg = SK_FALSE;
- }
- else {
- AutoNeg = SK_TRUE;
- }
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- switch (pPrt->PhyType) {
-
- case SK_PHY_XMAC:
- Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
- break;
- case SK_PHY_BCOM:
- Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
- break;
- case SK_PHY_NAT:
- Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
- break;
-#endif /* OTHER_PHY */
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
- }
-#endif /* YUKON */
-
- return(Rtv);
-} /* SkGePortCheckUp */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- * 2 Link came up
- */
-static int SkGePortCheckUpXmac(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port, /* Which port should be checked */
-SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
-{
- SK_U32 Shorts; /* Short Event Counter */
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- int Done;
- SK_U32 GpReg; /* General Purpose register value */
- SK_U16 Isrc; /* Interrupt source register */
- SK_U16 IsrcSum; /* Interrupt source register sum */
- SK_U16 LpAb; /* Link Partner Ability */
- SK_U16 ResAb; /* Resolved Ability */
- SK_U16 ExtStat; /* Extended Status Register */
- SK_U8 NextMode; /* Next AutoSensing Mode */
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PHWLinkUp) {
- if (pPrt->PhyType != SK_PHY_XMAC) {
- return(SK_HW_PS_NONE);
- }
- else {
- return(SkGePortCheckShorts(pAC, IoC, Port));
- }
- }
-
- IsrcSum = pPrt->PIsave;
- pPrt->PIsave = 0;
-
- /* Now wait for each port's link */
- if (pPrt->PLinkBroken) {
- /* Link was broken */
- XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
-
- if ((GpReg & XM_GP_INP_ASS) == 0) {
- /* The Link is in sync */
- XM_IN16(IoC, Port, XM_ISRC, &Isrc);
- IsrcSum |= Isrc;
- SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-
- if ((Isrc & XM_IS_INP_ASS) == 0) {
- /* It has been in sync since last time */
- /* Restart the PORT */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link in sync Restart Port %d\n", Port));
-
- (void)SkXmUpdateStats(pAC, IoC, Port);
-
- /* We now need to reinitialize the PrevShorts counter */
- (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
- pPrt->PPrevShorts = Shorts;
-
- pPrt->PLinkBroken = SK_FALSE;
-
- /*
- * Link Restart Workaround:
- * it may be possible that the other Link side
- * restarts its link as well an we detect
- * another LinkBroken. To prevent this
- * happening we check for a maximum number
- * of consecutive restart. If those happens,
- * we do NOT restart the active link and
- * check whether the link is now o.k.
- */
- pPrt->PLinkResCt++;
-
- pPrt->PAutoNegTimeOut = 0;
-
- if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
- return(SK_HW_PS_RESTART);
- }
-
- pPrt->PLinkResCt = 0;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
- }
- else {
- pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
-
- /* Do nothing more if link is broken */
- return(SK_HW_PS_NONE);
- }
- }
- else {
- /* Do nothing more if link is broken */
- return(SK_HW_PS_NONE);
- }
-
- }
- else {
- /* Link was not broken, check if it is */
- XM_IN16(IoC, Port, XM_ISRC, &Isrc);
- IsrcSum |= Isrc;
- if ((Isrc & XM_IS_INP_ASS) != 0) {
- XM_IN16(IoC, Port, XM_ISRC, &Isrc);
- IsrcSum |= Isrc;
- if ((Isrc & XM_IS_INP_ASS) != 0) {
- XM_IN16(IoC, Port, XM_ISRC, &Isrc);
- IsrcSum |= Isrc;
- if ((Isrc & XM_IS_INP_ASS) != 0) {
- pPrt->PLinkBroken = SK_TRUE;
- /* Re-Init Link partner Autoneg flag */
- pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link broken Port %d\n", Port));
-
- /* Cable removed-> reinit sense mode */
- SkHWInitDefSense(pAC, IoC, Port);
-
- return(SK_HW_PS_RESTART);
- }
- }
- }
- else {
- SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
-
- if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
- return(SK_HW_PS_RESTART);
- }
- }
- }
-
- /*
- * here we usually can check whether the link is in sync and
- * auto-negotiation is done.
- */
- XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
- XM_IN16(IoC, Port, XM_ISRC, &Isrc);
- IsrcSum |= Isrc;
-
- SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-
- if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
- if ((GpReg & XM_GP_INP_ASS) == 0) {
- /* Save Auto-negotiation Done interrupt only if link is in sync */
- pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
- }
-#ifdef DEBUG
- if ((pPrt->PIsave & XM_IS_AND) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg done rescheduled Port %d\n", Port));
- }
-#endif /* DEBUG */
- return(SK_HW_PS_NONE);
- }
-
- if (AutoNeg) {
- if ((IsrcSum & XM_IS_AND) != 0) {
- SkHWLinkUp(pAC, IoC, Port);
- Done = SkMacAutoNegDone(pAC, IoC, Port);
- if (Done != SK_AND_OK) {
- /* Get PHY parameters, for debugging only */
- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
- Port, LpAb, ResAb));
-
- /* Try next possible mode */
- NextMode = SkHWSenseGetNext(pAC, IoC, Port);
- SkHWLinkDown(pAC, IoC, Port);
- if (Done == SK_AND_DUP_CAP) {
- /* GoTo next mode */
- SkHWSenseSetNext(pAC, IoC, Port, NextMode);
- }
-
- return(SK_HW_PS_RESTART);
- }
- /*
- * Dummy Read extended status to prevent extra link down/ups
- * (clear Page Received bit if set)
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
-
- return(SK_HW_PS_LINK);
- }
-
- /* AutoNeg not done, but HW link is up. Check for timeouts */
- pPrt->PAutoNegTimeOut++;
- if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
- /* Increase the Timeout counter */
- pPrt->PAutoNegTOCt++;
-
- /* Timeout occured */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("AutoNeg timeout Port %d\n", Port));
- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
- pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
- /* Set Link manually up */
- SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Set manual full duplex Port %d\n", Port));
- }
-
- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
- pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
- pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
- /*
- * This is rather complicated.
- * we need to check here whether the LIPA_AUTO
- * we saw before is false alert. We saw at one
- * switch ( SR8800) that on boot time it sends
- * just one auto-neg packet and does no further
- * auto-negotiation.
- * Solution: we restart the autosensing after
- * a few timeouts.
- */
- pPrt->PAutoNegTOCt = 0;
- pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
- SkHWInitDefSense(pAC, IoC, Port);
- }
-
- /* Do the restart */
- return(SK_HW_PS_RESTART);
- }
- }
- else {
- /* Link is up and we don't need more */
-#ifdef DEBUG
- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("ERROR: Lipa auto detected on port %d\n", Port));
- }
-#endif /* DEBUG */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link sync(GP), Port %d\n", Port));
- SkHWLinkUp(pAC, IoC, Port);
-
- /*
- * Link sync (GP) and so assume a good connection. But if not received
- * a bunch of frames received in a time slot (maybe broken tx cable)
- * the port is restart.
- */
- return(SK_HW_PS_LINK);
- }
-
- return(SK_HW_PS_NONE);
-} /* SkGePortCheckUpXmac */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- * 2 Link came up
- */
-static int SkGePortCheckUpBcom(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port, /* Which port should be checked */
-SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- int Done;
- SK_U16 Isrc; /* Interrupt source register */
- SK_U16 PhyStat; /* Phy Status Register */
- SK_U16 ResAb; /* Master/Slave resolution */
- SK_U16 Ctrl; /* Broadcom control flags */
-#ifdef DEBUG
- SK_U16 LpAb;
- SK_U16 ExtStat;
-#endif /* DEBUG */
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* Check for No HCD Link events (#10523) */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
-
-#ifdef xDEBUG
- if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) ==
- (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
-
- SK_U32 Stat1, Stat2, Stat3;
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "CheckUp1 - Stat: %x, Mask: %x",
- (void *)Isrc,
- (void *)Stat1);
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
- Stat1 = Stat1 << 16 | Stat2;
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
- Stat3 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
- Stat2 = Stat2 << 16 | Stat3;
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "Ctrl/Stat: %x, AN Adv/LP: %x",
- (void *)Stat1,
- (void *)Stat2);
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
- Stat1 = Stat1 << 16 | Stat2;
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
- Stat3 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
- Stat2 = Stat2 << 16 | Stat3;
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
- (void *)Stat1,
- (void *)Stat2);
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
- Stat1 = Stat1 << 16 | Stat2;
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
- Stat3 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
- Stat2 = Stat2 << 16 | Stat3;
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
- (void *)Stat1,
- (void *)Stat2);
- }
-#endif /* DEBUG */
-
- if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
- /*
- * Workaround BCom Errata:
- * enable and disable loopback mode if "NO HCD" occurs.
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
- (SK_U16)(Ctrl | PHY_CT_LOOP));
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
- (SK_U16)(Ctrl & ~PHY_CT_LOOP));
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("No HCD Link event, Port %d\n", Port));
-#ifdef xDEBUG
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "No HCD link event, port %d.",
- (void *)Port,
- (void *)NULL);
-#endif /* DEBUG */
- }
-
- /* Not obsolete: link status bit is latched to 0 and autoclearing! */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-
- if (pPrt->PHWLinkUp) {
- return(SK_HW_PS_NONE);
- }
-
-#ifdef xDEBUG
- {
- SK_U32 Stat1, Stat2, Stat3;
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "CheckUp1a - Stat: %x, Mask: %x",
- (void *)Isrc,
- (void *)Stat1);
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
- Stat1 = Stat1 << 16 | PhyStat;
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
- Stat3 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
- Stat2 = Stat2 << 16 | Stat3;
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "Ctrl/Stat: %x, AN Adv/LP: %x",
- (void *)Stat1,
- (void *)Stat2);
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
- Stat1 = Stat1 << 16 | Stat2;
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
- Stat3 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
- Stat2 = Stat2 << 16 | ResAb;
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
- (void *)Stat1,
- (void *)Stat2);
-
- Stat1 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
- Stat1 = Stat1 << 16 | Stat2;
- Stat2 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
- Stat3 = 0;
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
- Stat2 = Stat2 << 16 | Stat3;
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
- (void *)Stat1,
- (void *)Stat2);
- }
-#endif /* DEBUG */
-
- /*
- * Here we usually can check whether the link is in sync and
- * auto-negotiation is done.
- */
-
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-
- SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
-
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-
- if ((ResAb & PHY_B_1000S_MSF) != 0) {
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Master/Slave Fault port %d\n", Port));
-
- pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PMSStatus = SK_MS_STAT_FAULT;
-
- return(SK_HW_PS_RESTART);
- }
-
- if ((PhyStat & PHY_ST_LSYNC) == 0) {
- return(SK_HW_PS_NONE);
- }
-
- pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
- SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
-
- if (AutoNeg) {
- if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-
- SkHWLinkUp(pAC, IoC, Port);
-
- Done = SkMacAutoNegDone(pAC, IoC, Port);
-
- if (Done != SK_AND_OK) {
-#ifdef DEBUG
- /* Get PHY parameters, for debugging only */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
- Port, LpAb, ExtStat));
-#endif /* DEBUG */
- return(SK_HW_PS_RESTART);
- }
- else {
-#ifdef xDEBUG
- /* Dummy read ISR to prevent extra link downs/ups */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
- if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "CheckUp2 - Stat: %x",
- (void *)ExtStat,
- (void *)NULL);
- }
-#endif /* DEBUG */
- return(SK_HW_PS_LINK);
- }
- }
- }
- else { /* !AutoNeg */
- /* Link is up and we don't need more. */
-#ifdef DEBUG
- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("ERROR: Lipa auto detected on port %d\n", Port));
- }
-#endif /* DEBUG */
-
-#ifdef xDEBUG
- /* Dummy read ISR to prevent extra link downs/ups */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
- if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
- CMSMPrintString(
- pAC->pConfigTable,
- MSG_TYPE_RUNTIME_INFO,
- "CheckUp3 - Stat: %x",
- (void *)ExtStat,
- (void *)NULL);
- }
-#endif /* DEBUG */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link sync(GP), Port %d\n", Port));
- SkHWLinkUp(pAC, IoC, Port);
-
- return(SK_HW_PS_LINK);
- }
-
- return(SK_HW_PS_NONE);
-} /* SkGePortCheckUpBcom */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- * 2 Link came up
- */
-static int SkGePortCheckUpGmac(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port, /* Which port should be checked */
-SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- int Done;
- SK_U16 PhyIsrc; /* PHY Interrupt source */
- SK_U16 PhyStat; /* PPY Status */
- SK_U16 PhySpecStat;/* PHY Specific Status */
- SK_U16 ResAb; /* Master/Slave resolution */
- SK_EVPARA Para;
-#ifdef DEBUG
- SK_U16 Word; /* I/O helper */
-#endif /* DEBUG */
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PHWLinkUp) {
- return(SK_HW_PS_NONE);
- }
-
- /* Read PHY Status */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
-
- /* Read PHY Interrupt Status */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
-
- if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
- }
-
- if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
- }
-
- SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-
- if ((ResAb & PHY_B_1000S_MSF) != 0) {
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Master/Slave Fault port %d\n", Port));
-
- pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PMSStatus = SK_MS_STAT_FAULT;
-
- return(SK_HW_PS_RESTART);
- }
-
- /* Read PHY Specific Status */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
-
-#ifdef DEBUG
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
-
- if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
- (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) {
- /* Read PHY Next Page Link Partner */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Page Received, NextPage: 0x%04X\n", Word));
- }
-#endif /* DEBUG */
-
- if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
- return(SK_HW_PS_NONE);
- }
-
- if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
- (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
- /* Downshift detected */
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
-
- Para.Para64 = Port;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
- }
-
- pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
- SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-
- pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
-
- if (AutoNeg) {
- /* Auto-Negotiation Over ? */
- if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-
- SkHWLinkUp(pAC, IoC, Port);
-
- Done = SkMacAutoNegDone(pAC, IoC, Port);
-
- if (Done != SK_AND_OK) {
- return(SK_HW_PS_RESTART);
- }
-
- return(SK_HW_PS_LINK);
- }
- }
- else { /* !AutoNeg */
- /* Link is up and we don't need more */
-#ifdef DEBUG
- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("ERROR: Lipa auto detected on port %d\n", Port));
- }
-#endif /* DEBUG */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link sync, Port %d\n", Port));
- SkHWLinkUp(pAC, IoC, Port);
-
- return(SK_HW_PS_LINK);
- }
-
- return(SK_HW_PS_NONE);
-} /* SkGePortCheckUpGmac */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- * 2 Link came up
- */
-static int SkGePortCheckUpLone(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port, /* Which port should be checked */
-SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- int Done;
- SK_U16 Isrc; /* Interrupt source register */
- SK_U16 LpAb; /* Link Partner Ability */
- SK_U16 ExtStat; /* Extended Status Register */
- SK_U16 PhyStat; /* Phy Status Register */
- SK_U16 StatSum;
- SK_U8 NextMode; /* Next AutoSensing Mode */
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PHWLinkUp) {
- return(SK_HW_PS_NONE);
- }
-
- StatSum = pPrt->PIsave;
- pPrt->PIsave = 0;
-
- /*
- * here we usually can check whether the link is in sync and
- * auto-negotiation is done.
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
- StatSum |= PhyStat;
-
- SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-
- if ((PhyStat & PHY_ST_LSYNC) == 0) {
- /* Save Auto-negotiation Done bit */
- pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
-#ifdef DEBUG
- if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg done rescheduled Port %d\n", Port));
- }
-#endif /* DEBUG */
- return(SK_HW_PS_NONE);
- }
-
- if (AutoNeg) {
- if ((StatSum & PHY_ST_AN_OVER) != 0) {
- SkHWLinkUp(pAC, IoC, Port);
- Done = SkMacAutoNegDone(pAC, IoC, Port);
- if (Done != SK_AND_OK) {
- /* Get PHY parameters, for debugging only */
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
- Port, LpAb, ExtStat));
-
- /* Try next possible mode */
- NextMode = SkHWSenseGetNext(pAC, IoC, Port);
- SkHWLinkDown(pAC, IoC, Port);
- if (Done == SK_AND_DUP_CAP) {
- /* GoTo next mode */
- SkHWSenseSetNext(pAC, IoC, Port, NextMode);
- }
-
- return(SK_HW_PS_RESTART);
-
- }
- else {
- /*
- * Dummy Read interrupt status to prevent
- * extra link down/ups
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
- return(SK_HW_PS_LINK);
- }
- }
-
- /* AutoNeg not done, but HW link is up. Check for timeouts */
- pPrt->PAutoNegTimeOut++;
- if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
- /* Timeout occured */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("AutoNeg timeout Port %d\n", Port));
- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
- pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
- /* Set Link manually up */
- SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Set manual full duplex Port %d\n", Port));
- }
-
- /* Do the restart */
- return(SK_HW_PS_RESTART);
- }
- }
- else {
- /* Link is up and we don't need more */
-#ifdef DEBUG
- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("ERROR: Lipa auto detected on port %d\n", Port));
- }
-#endif /* DEBUG */
-
- /*
- * Dummy Read interrupt status to prevent
- * extra link down/ups
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("Link sync(GP), Port %d\n", Port));
- SkHWLinkUp(pAC, IoC, Port);
-
- return(SK_HW_PS_LINK);
- }
-
- return(SK_HW_PS_NONE);
-} /* SkGePortCheckUpLone */
-
-
-/******************************************************************************
- *
- * SkGePortCheckUpNat() - Check if the link is up on National PHY
- *
- * return:
- * 0 o.k. nothing needed
- * 1 Restart needed on this port
- * 2 Link came up
- */
-static int SkGePortCheckUpNat(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO Context */
-int Port, /* Which port should be checked */
-SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
-{
- /* todo: National */
- return(SK_HW_PS_NONE);
-} /* SkGePortCheckUpNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- * SkGeSirqEvent() - Event Service Routine
- *
- * Description:
- *
- * Notes:
- */
-int SkGeSirqEvent(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* Io Context */
-SK_U32 Event, /* Module specific Event */
-SK_EVPARA Para) /* Event specific Parameter */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- SK_U32 Port;
- SK_U32 Val32;
- int PortStat;
- SK_U8 Val8;
-#ifdef GENESIS
- SK_U64 Octets;
-#endif /* GENESIS */
-
- Port = Para.Para32[0];
- pPrt = &pAC->GIni.GP[Port];
-
- switch (Event) {
- case SK_HWEV_WATIM:
- if (pPrt->PState == SK_PRT_RESET) {
-
- PortStat = SK_HW_PS_NONE;
- }
- else {
- /* Check whether port came up */
- PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
- }
-
- switch (PortStat) {
- case SK_HW_PS_RESTART:
- if (pPrt->PHWLinkUp) {
- /* Set Link to down */
- SkHWLinkDown(pAC, IoC, (int)Port);
-
- /*
- * Signal directly to RLMT to ensure correct
- * sequence of SWITCH and RESET event.
- */
- SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
- }
-
- /* Restart needed */
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
- break;
-
- case SK_HW_PS_LINK:
- /* Signal to RLMT */
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
- break;
- }
-
- /* Start again the check Timer */
- if (pPrt->PHWLinkUp) {
- Val32 = SK_WA_ACT_TIME;
- }
- else {
- Val32 = SK_WA_INA_TIME;
- }
-
- /* Todo: still needed for non-XMAC PHYs??? */
- /* Start workaround Errata #2 timer */
- SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
- SKGE_HWAC, SK_HWEV_WATIM, Para);
- break;
-
- case SK_HWEV_PORT_START:
- if (pPrt->PHWLinkUp) {
- /*
- * Signal directly to RLMT to ensure correct
- * sequence of SWITCH and RESET event.
- */
- SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
- }
-
- SkHWLinkDown(pAC, IoC, (int)Port);
-
- /* Schedule Port RESET */
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-
- /* Start workaround Errata #2 timer */
- SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
- SKGE_HWAC, SK_HWEV_WATIM, Para);
- break;
-
- case SK_HWEV_PORT_STOP:
- if (pPrt->PHWLinkUp) {
- /*
- * Signal directly to RLMT to ensure correct
- * sequence of SWITCH and RESET event.
- */
- SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
- }
-
- /* Stop Workaround Timer */
- SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
-
- SkHWLinkDown(pAC, IoC, (int)Port);
- break;
-
- case SK_HWEV_UPDATE_STAT:
- /* We do NOT need to update any statistics */
- break;
-
- case SK_HWEV_CLEAR_STAT:
- /* We do NOT need to clear any statistics */
- for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
- pPrt->PPrevRx = 0;
- pPrt->PPrevFcs = 0;
- pPrt->PPrevShorts = 0;
- }
- break;
-
- case SK_HWEV_SET_LMODE:
- Val8 = (SK_U8)Para.Para32[1];
- if (pPrt->PLinkModeConf != Val8) {
- /* Set New link mode */
- pPrt->PLinkModeConf = Val8;
-
- /* Restart Port */
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
- }
- break;
-
- case SK_HWEV_SET_FLOWMODE:
- Val8 = (SK_U8)Para.Para32[1];
- if (pPrt->PFlowCtrlMode != Val8) {
- /* Set New Flow Control mode */
- pPrt->PFlowCtrlMode = Val8;
-
- /* Restart Port */
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
- }
- break;
-
- case SK_HWEV_SET_ROLE:
- /* not possible for fiber */
- if (!pAC->GIni.GICopperType) {
- break;
- }
- Val8 = (SK_U8)Para.Para32[1];
- if (pPrt->PMSMode != Val8) {
- /* Set New Role (Master/Slave) mode */
- pPrt->PMSMode = Val8;
-
- /* Restart Port */
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
- }
- break;
-
- case SK_HWEV_SET_SPEED:
- if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
- break;
- }
- Val8 = (SK_U8)Para.Para32[1];
- if (pPrt->PLinkSpeed != Val8) {
- /* Set New Speed parameter */
- pPrt->PLinkSpeed = Val8;
-
- /* Restart Port */
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
- }
- break;
-
-#ifdef GENESIS
- case SK_HWEV_HALFDUP_CHK:
- if (pAC->GIni.GIGenesis) {
- /*
- * half duplex hangup workaround.
- * See packet arbiter timeout interrupt for description
- */
- pPrt->HalfDupTimerActive = SK_FALSE;
- if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
- pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
- /* Snap statistic counters */
- (void)SkXmUpdateStats(pAC, IoC, Port);
-
- (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
-
- Octets = (SK_U64)Val32 << 32;
-
- (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
-
- Octets += Val32;
-
- if (pPrt->LastOctets == Octets) {
- /* Tx hanging, a FIFO flush restarts it */
- SkMacFlushTxFifo(pAC, IoC, Port);
- }
- }
- }
- break;
-#endif /* GENESIS */
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
- break;
- }
-
- return(0);
-} /* SkGeSirqEvent */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkPhyIsrBcom() - PHY interrupt service routine
- *
- * Description: handles all interrupts from BCom PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrBcom(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* Io Context */
-int Port, /* Port Num = PHY Num */
-SK_U16 IStatus) /* Interrupt Status */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- SK_EVPARA Para;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if ((IStatus & PHY_B_IS_PSE) != 0) {
- /* Incorrectable pair swap error */
- SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
- SKERR_SIRQ_E022MSG);
- }
-
- if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
-
- SkHWLinkDown(pAC, IoC, Port);
-
- Para.Para32[0] = (SK_U32)Port;
- /* Signal to RLMT */
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
- /* Start workaround Errata #2 timer */
- SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
- SKGE_HWAC, SK_HWEV_WATIM, Para);
- }
-
-} /* SkPhyIsrBcom */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkPhyIsrGmac() - PHY interrupt service routine
- *
- * Description: handles all interrupts from Marvell PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrGmac(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* Io Context */
-int Port, /* Port Num = PHY Num */
-SK_U16 IStatus) /* Interrupt Status */
-{
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
- SK_EVPARA Para;
- SK_U16 Word;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
-
- SkHWLinkDown(pAC, IoC, Port);
-
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg.Adv: 0x%04X\n", Word));
-
- /* Set Auto-negotiation advertisement */
- if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
- /* restore Asymmetric Pause bit */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
- (SK_U16)(Word | PHY_M_AN_ASP));
- }
-
- Para.Para32[0] = (SK_U32)Port;
- /* Signal to RLMT */
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
- if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
- /* Auto-Negotiation Error */
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
- }
-
- if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
- /* FIFO Overflow/Underrun Error */
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
- }
-
-} /* SkPhyIsrGmac */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- * SkPhyIsrLone() - PHY interrupt service routine
- *
- * Description: handles all interrupts from LONE PHY
- *
- * Returns: N/A
- */
-static void SkPhyIsrLone(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* Io Context */
-int Port, /* Port Num = PHY Num */
-SK_U16 IStatus) /* Interrupt Status */
-{
- SK_EVPARA Para;
-
- if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
-
- SkHWLinkDown(pAC, IoC, Port);
-
- Para.Para32[0] = (SK_U32)Port;
- /* Signal to RLMT */
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
- }
-
-} /* SkPhyIsrLone */
-#endif /* OTHER_PHY */
-
-/* End of File */
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
deleted file mode 100644
index 79bf57cb5326..000000000000
--- a/drivers/net/sk98lin/ski2c.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/******************************************************************************
- *
- * Name: ski2c.c
- * Project: Gigabit Ethernet Adapters, TWSI-Module
- * Version: $Revision: 1.59 $
- * Date: $Date: 2003/10/20 09:07:25 $
- * Purpose: Functions to access Voltage and Temperature Sensor
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- * I2C Protocol
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
-#endif
-
-#include "h/skdrv1st.h" /* Driver Specific Definitions */
-#include "h/lm80.h"
-#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
- I2C protocol implementation.
-
- General Description:
-
- The I2C protocol is used for the temperature sensors and for
- the serial EEPROM which hold the configuration.
-
- This file covers functions that allow to read write and do
- some bulk requests a specified I2C address.
-
- The Genesis has 2 I2C buses. One for the EEPROM which holds
- the VPD Data and one for temperature and voltage sensor.
- The following picture shows the I2C buses, I2C devices and
- their control registers.
-
- Note: The VPD functions are in skvpd.c
-.
-. PCI Config I2C Bus for VPD Data:
-.
-. +------------+
-. | VPD EEPROM |
-. +------------+
-. |
-. | <-- I2C
-. |
-. +-----------+-----------+
-. | |
-. +-----------------+ +-----------------+
-. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
-. +-----------------+ +-----------------+
-.
-.
-. I2C Bus for LM80 sensor:
-.
-. +-----------------+
-. | Temperature and |
-. | Voltage Sensor |
-. | LM80 |
-. +-----------------+
-. |
-. |
-. I2C --> |
-. |
-. +----+
-. +-------------->| OR |<--+
-. | +----+ |
-. +------+------+ |
-. | | |
-. +--------+ +--------+ +----------+
-. | B2_I2C | | B2_I2C | | B2_I2C |
-. | _CTRL | | _DATA | | _SW |
-. +--------+ +--------+ +----------+
-.
- The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
- and B2_I2C_DATA registers.
- For driver software it is recommended to use the I2C control and
- data register, because I2C bus timing is done by the ASIC and
- an interrupt may be received when the I2C request is completed.
-
- Clock Rate Timing: MIN MAX generated by
- VPD EEPROM: 50 kHz 100 kHz HW
- LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
- LM80 over B2_I2C_SW register 0 400 kHz SW
-
- Note: The clock generated by the hardware is dependend on the
- PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
- clock is 50 kHz.
- */
-intro()
-{}
-#endif
-
-#ifdef SK_DIAG
-/*
- * I2C Fast Mode timing values used by the LM80.
- * If new devices are added to the I2C bus the timing values have to be checked.
- */
-#ifndef I2C_SLOW_TIMING
-#define T_CLK_LOW 1300L /* clock low time in ns */
-#define T_CLK_HIGH 600L /* clock high time in ns */
-#define T_DATA_IN_SETUP 100L /* data in Set-up Time */
-#define T_START_HOLD 600L /* start condition hold time */
-#define T_START_SETUP 600L /* start condition Set-up time */
-#define T_STOP_SETUP 600L /* stop condition Set-up time */
-#define T_BUS_IDLE 1300L /* time the bus must free after Tx */
-#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
-#else /* I2C_SLOW_TIMING */
-/* I2C Standard Mode Timing */
-#define T_CLK_LOW 4700L /* clock low time in ns */
-#define T_CLK_HIGH 4000L /* clock high time in ns */
-#define T_DATA_IN_SETUP 250L /* data in Set-up Time */
-#define T_START_HOLD 4000L /* start condition hold time */
-#define T_START_SETUP 4700L /* start condition Set-up time */
-#define T_STOP_SETUP 4000L /* stop condition Set-up time */
-#define T_BUS_IDLE 4700L /* time the bus must free after Tx */
-#endif /* !I2C_SLOW_TIMING */
-
-#define NS2BCLK(x) (((x)*125)/10000)
-
-/*
- * I2C Wire Operations
- *
- * About I2C_CLK_LOW():
- *
- * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
- * clock to low, to prevent the ASIC and the I2C data client from driving the
- * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
- * send an 'ACK'). See also Concentrator Bugreport No. 10192.
- */
-#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
-#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
-#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
-#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
-#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
-#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
-#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
-
-#define NS2CLKT(x) ((x*125L)/10000)
-
-/*--------------- I2C Interface Register Functions --------------- */
-
-/*
- * sending one bit
- */
-void SkI2cSndBit(
-SK_IOC IoC, /* I/O Context */
-SK_U8 Bit) /* Bit to send */
-{
- I2C_DATA_OUT(IoC);
- if (Bit) {
- I2C_DATA_HIGH(IoC);
- }
- else {
- I2C_DATA_LOW(IoC);
- }
- SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
- I2C_CLK_HIGH(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
- I2C_CLK_LOW(IoC);
-} /* SkI2cSndBit*/
-
-
-/*
- * Signal a start to the I2C Bus.
- *
- * A start is signaled when data goes to low in a high clock cycle.
- *
- * Ends with Clock Low.
- *
- * Status: not tested
- */
-void SkI2cStart(
-SK_IOC IoC) /* I/O Context */
-{
- /* Init data and Clock to output lines */
- /* Set Data high */
- I2C_DATA_OUT(IoC);
- I2C_DATA_HIGH(IoC);
- /* Set Clock high */
- I2C_CLK_HIGH(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
-
- /* Set Data Low */
- I2C_DATA_LOW(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
-
- /* Clock low without Data to Input */
- I2C_START_COND(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
-} /* SkI2cStart */
-
-
-void SkI2cStop(
-SK_IOC IoC) /* I/O Context */
-{
- /* Init data and Clock to output lines */
- /* Set Data low */
- I2C_DATA_OUT(IoC);
- I2C_DATA_LOW(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
-
- /* Set Clock high */
- I2C_CLK_HIGH(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
-
- /*
- * Set Data High: Do it by setting the Data Line to Input.
- * Because of a pull up resistor the Data Line
- * floods to high.
- */
- I2C_DATA_IN(IoC);
-
- /*
- * When I2C activity is stopped
- * o DATA should be set to input and
- * o CLOCK should be set to high!
- */
- SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
-} /* SkI2cStop */
-
-
-/*
- * Receive just one bit via the I2C bus.
- *
- * Note: Clock must be set to LOW before calling this function.
- *
- * Returns The received bit.
- */
-int SkI2cRcvBit(
-SK_IOC IoC) /* I/O Context */
-{
- int Bit;
- SK_U8 I2cSwCtrl;
-
- /* Init data as input line */
- I2C_DATA_IN(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
-
- I2C_CLK_HIGH(IoC);
-
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
-
- SK_I2C_GET_SW(IoC, &I2cSwCtrl);
-
- Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
-
- I2C_CLK_LOW(IoC);
- SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
-
- return(Bit);
-} /* SkI2cRcvBit */
-
-
-/*
- * Receive an ACK.
- *
- * returns 0 If acknowledged
- * 1 in case of an error
- */
-int SkI2cRcvAck(
-SK_IOC IoC) /* I/O Context */
-{
- /*
- * Received bit must be zero.
- */
- return(SkI2cRcvBit(IoC) != 0);
-} /* SkI2cRcvAck */
-
-
-/*
- * Send an NACK.
- */
-void SkI2cSndNAck(
-SK_IOC IoC) /* I/O Context */
-{
- /*
- * Received bit must be zero.
- */
- SkI2cSndBit(IoC, 1);
-} /* SkI2cSndNAck */
-
-
-/*
- * Send an ACK.
- */
-void SkI2cSndAck(
-SK_IOC IoC) /* I/O Context */
-{
- /*
- * Received bit must be zero.
- */
- SkI2cSndBit(IoC, 0);
-} /* SkI2cSndAck */
-
-
-/*
- * Send one byte to the I2C device and wait for ACK.
- *
- * Return acknowleged status.
- */
-int SkI2cSndByte(
-SK_IOC IoC, /* I/O Context */
-int Byte) /* byte to send */
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- if (Byte & (1<<(7-i))) {
- SkI2cSndBit(IoC, 1);
- }
- else {
- SkI2cSndBit(IoC, 0);
- }
- }
-
- return(SkI2cRcvAck(IoC));
-} /* SkI2cSndByte */
-
-
-/*
- * Receive one byte and ack it.
- *
- * Return byte.
- */
-int SkI2cRcvByte(
-SK_IOC IoC, /* I/O Context */
-int Last) /* Last Byte Flag */
-{
- int i;
- int Byte = 0;
-
- for (i = 0; i < 8; i++) {
- Byte <<= 1;
- Byte |= SkI2cRcvBit(IoC);
- }
-
- if (Last) {
- SkI2cSndNAck(IoC);
- }
- else {
- SkI2cSndAck(IoC);
- }
-
- return(Byte);
-} /* SkI2cRcvByte */
-
-
-/*
- * Start dialog and send device address
- *
- * Return 0 if acknowleged, 1 in case of an error
- */
-int SkI2cSndDev(
-SK_IOC IoC, /* I/O Context */
-int Addr, /* Device Address */
-int Rw) /* Read / Write Flag */
-{
- SkI2cStart(IoC);
- Rw = ~Rw;
- Rw &= I2C_WRITE;
- return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
-} /* SkI2cSndDev */
-
-#endif /* SK_DIAG */
-
-/*----------------- I2C CTRL Register Functions ----------*/
-
-/*
- * waits for a completion of an I2C transfer
- *
- * returns 0: success, transfer completes
- * 1: error, transfer does not complete, I2C transfer
- * killed, wait loop terminated.
- */
-static int SkI2cWait(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
-{
- SK_U64 StartTime;
- SK_U64 CurrentTime;
- SK_U32 I2cCtrl;
-
- StartTime = SkOsGetTime(pAC);
-
- do {
- CurrentTime = SkOsGetTime(pAC);
-
- if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
-
- SK_I2C_STOP(IoC);
-#ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
-#endif /* !SK_DIAG */
- return(1);
- }
-
- SK_I2C_GET_CTL(IoC, &I2cCtrl);
-
-#ifdef xYUKON_DBG
- printf("StartTime=%lu, CurrentTime=%lu\n",
- StartTime, CurrentTime);
- if (kbhit()) {
- return(1);
- }
-#endif /* YUKON_DBG */
-
- } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
-
- return(0);
-} /* SkI2cWait */
-
-
-/*
- * waits for a completion of an I2C transfer
- *
- * Returns
- * Nothing
- */
-void SkI2cWaitIrq(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC) /* I/O Context */
-{
- SK_SENSOR *pSen;
- SK_U64 StartTime;
- SK_U32 IrqSrc;
-
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
-
- if (pSen->SenState == SK_SEN_IDLE) {
- return;
- }
-
- StartTime = SkOsGetTime(pAC);
-
- do {
- if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
-
- SK_I2C_STOP(IoC);
-#ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
-#endif /* !SK_DIAG */
- return;
- }
-
- SK_IN32(IoC, B0_ISRC, &IrqSrc);
-
- } while ((IrqSrc & IS_I2C_READY) == 0);
-
- pSen->SenState = SK_SEN_IDLE;
- return;
-} /* SkI2cWaitIrq */
-
-/*
- * writes a single byte or 4 bytes into the I2C device
- *
- * returns 0: success
- * 1: error
- */
-static int SkI2cWrite(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 I2cData, /* I2C Data to write */
-int I2cDev, /* I2C Device Address */
-int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
-int I2cReg, /* I2C Device Register Address */
-int I2cBurst) /* I2C Burst Flag */
-{
- SK_OUT32(IoC, B2_I2C_DATA, I2cData);
-
- SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
-
- return(SkI2cWait(pAC, IoC, I2C_WRITE));
-} /* SkI2cWrite*/
-
-
-#ifdef SK_DIAG
-/*
- * reads a single byte or 4 bytes from the I2C device
- *
- * returns the word read
- */
-SK_U32 SkI2cRead(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int I2cDev, /* I2C Device Address */
-int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
-int I2cReg, /* I2C Device Register Address */
-int I2cBurst) /* I2C Burst Flag */
-{
- SK_U32 Data;
-
- SK_OUT32(IoC, B2_I2C_DATA, 0);
- SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
-
- if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
- w_print("%s\n", SKERR_I2C_E002MSG);
- }
-
- SK_IN32(IoC, B2_I2C_DATA, &Data);
-
- return(Data);
-} /* SkI2cRead */
-#endif /* SK_DIAG */
-
-
-/*
- * read a sensor's value
- *
- * This function reads a sensor's value from the I2C sensor chip. The sensor
- * is defined by its index into the sensors database in the struct pAC points
- * to.
- * Returns
- * 1 if the read is completed
- * 0 if the read must be continued (I2C Bus still allocated)
- */
-static int SkI2cReadSensor(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_SENSOR *pSen) /* Sensor to be read */
-{
- if (pSen->SenRead != NULL) {
- return((*pSen->SenRead)(pAC, IoC, pSen));
- }
- else {
- return(0); /* no success */
- }
-} /* SkI2cReadSensor */
-
-/*
- * Do the Init state 0 initialization
- */
-static int SkI2cInit0(
-SK_AC *pAC) /* Adapter Context */
-{
- int i;
-
- /* Begin with first sensor */
- pAC->I2c.CurrSens = 0;
-
- /* Begin with timeout control for state machine */
- pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
-
- /* Set sensor number to zero */
- pAC->I2c.MaxSens = 0;
-
-#ifndef SK_DIAG
- /* Initialize Number of Dummy Reads */
- pAC->I2c.DummyReads = SK_MAX_SENSORS;
-#endif
-
- for (i = 0; i < SK_MAX_SENSORS; i++) {
- pAC->I2c.SenTable[i].SenDesc = "unknown";
- pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
- pAC->I2c.SenTable[i].SenThreErrHigh = 0;
- pAC->I2c.SenTable[i].SenThreErrLow = 0;
- pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
- pAC->I2c.SenTable[i].SenThreWarnLow = 0;
- pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
- pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
- pAC->I2c.SenTable[i].SenValue = 0;
- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
- pAC->I2c.SenTable[i].SenErrCts = 0;
- pAC->I2c.SenTable[i].SenBegErrTS = 0;
- pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
- pAC->I2c.SenTable[i].SenRead = NULL;
- pAC->I2c.SenTable[i].SenDev = 0;
- }
-
- /* Now we are "INIT data"ed */
- pAC->I2c.InitLevel = SK_INIT_DATA;
- return(0);
-} /* SkI2cInit0*/
-
-
-/*
- * Do the init state 1 initialization
- *
- * initialize the following register of the LM80:
- * Configuration register:
- * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
- *
- * Interrupt Mask Register 1:
- * - all interrupts are Disabled (0xff)
- *
- * Interrupt Mask Register 2:
- * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
- *
- * Fan Divisor/RST_OUT register:
- * - Divisors set to 1 (bits 00), all others 0s.
- *
- * OS# Configuration/Temperature resolution Register:
- * - all 0s
- *
- */
-static int SkI2cInit1(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC) /* I/O Context */
-{
- int i;
- SK_U8 I2cSwCtrl;
- SK_GEPORT *pPrt; /* GIni Port struct pointer */
-
- if (pAC->I2c.InitLevel != SK_INIT_DATA) {
- /* ReInit not needed in I2C module */
- return(0);
- }
-
- /* Set the Direction of I2C-Data Pin to IN */
- SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
- /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
- SK_I2C_GET_SW(IoC, &I2cSwCtrl);
-
- if ((I2cSwCtrl & I2C_DATA) == 0) {
- /* this is a 32-Bit board */
- pAC->GIni.GIYukon32Bit = SK_TRUE;
- return(0);
- }
-
- /* Check for 64 Bit Yukon without sensors */
- if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
- return(0);
- }
-
- (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
-
- (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
-
- (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
-
- (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
-
- (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
- LM80_CFG, 0);
-
- /*
- * MaxSens has to be updated here, because PhyType is not
- * set when performing Init Level 0
- */
- pAC->I2c.MaxSens = 5;
-
- pPrt = &pAC->GIni.GP[0];
-
- if (pAC->GIni.GIGenesis) {
- if (pPrt->PhyType == SK_PHY_BCOM) {
- if (pAC->GIni.GIMacsFound == 1) {
- pAC->I2c.MaxSens += 1;
- }
- else {
- pAC->I2c.MaxSens += 3;
- }
- }
- }
- else {
- pAC->I2c.MaxSens += 3;
- }
-
- for (i = 0; i < pAC->I2c.MaxSens; i++) {
- switch (i) {
- case 0:
- pAC->I2c.SenTable[i].SenDesc = "Temperature";
- pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
- break;
- case 1:
- pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
- break;
- case 2:
- pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
- pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
- break;
- case 3:
- pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
- break;
- case 4:
- if (pAC->GIni.GIGenesis) {
- if (pPrt->PhyType == SK_PHY_BCOM) {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
- }
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
- if (pAC->GIni.GIVauxAvail) {
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
- }
- else {
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
- }
- }
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
- break;
- case 5:
- if (pAC->GIni.GIGenesis) {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
- }
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
- break;
- case 6:
- if (pAC->GIni.GIGenesis) {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
- }
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
- break;
- case 7:
- if (pAC->GIni.GIGenesis) {
- pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
- pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
- }
- else {
- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
- pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
- }
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
- SKERR_I2C_E001, SKERR_I2C_E001MSG);
- break;
- }
-
- pAC->I2c.SenTable[i].SenValue = 0;
- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
- pAC->I2c.SenTable[i].SenErrCts = 0;
- pAC->I2c.SenTable[i].SenBegErrTS = 0;
- pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
- pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
- pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
- }
-
-#ifndef SK_DIAG
- pAC->I2c.DummyReads = pAC->I2c.MaxSens;
-#endif /* !SK_DIAG */
-
- /* Clear I2C IRQ */
- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-
- /* Now we are I/O initialized */
- pAC->I2c.InitLevel = SK_INIT_IO;
- return(0);
-} /* SkI2cInit1 */
-
-
-/*
- * Init level 2: Start first sensor read.
- */
-static int SkI2cInit2(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC) /* I/O Context */
-{
- int ReadComplete;
- SK_SENSOR *pSen;
-
- if (pAC->I2c.InitLevel != SK_INIT_IO) {
- /* ReInit not needed in I2C module */
- /* Init0 and Init2 not permitted */
- return(0);
- }
-
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
- if (ReadComplete) {
- SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
- }
-
- /* Now we are correctly initialized */
- pAC->I2c.InitLevel = SK_INIT_RUN;
-
- return(0);
-} /* SkI2cInit2*/
-
-
-/*
- * Initialize I2C devices
- *
- * Get the first voltage value and discard it.
- * Go into temperature read mode. A default pointer is not set.
- *
- * The things to be done depend on the init level in the parameter list:
- * Level 0:
- * Initialize only the data structures. Do NOT access hardware.
- * Level 1:
- * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
- * Level 2:
- * Everything is possible. Interrupts may be used from now on.
- *
- * return:
- * 0 = success
- * other = error.
- */
-int SkI2cInit(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
-int Level) /* Init Level */
-{
-
- switch (Level) {
- case SK_INIT_DATA:
- return(SkI2cInit0(pAC));
- case SK_INIT_IO:
- return(SkI2cInit1(pAC, IoC));
- case SK_INIT_RUN:
- return(SkI2cInit2(pAC, IoC));
- default:
- break;
- }
-
- return(0);
-} /* SkI2cInit */
-
-
-#ifndef SK_DIAG
-
-/*
- * Interrupt service function for the I2C Interface
- *
- * Clears the Interrupt source
- *
- * Reads the register and check it for sending a trap.
- *
- * Starts the timer if necessary.
- */
-void SkI2cIsr(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC) /* I/O Context */
-{
- SK_EVPARA Para;
-
- /* Clear I2C IRQ */
- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-
- Para.Para64 = 0;
- SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
-} /* SkI2cIsr */
-
-
-/*
- * Check this sensors Value against the threshold and send events.
- */
-static void SkI2cCheckSensor(
-SK_AC *pAC, /* Adapter Context */
-SK_SENSOR *pSen)
-{
- SK_EVPARA ParaLocal;
- SK_BOOL TooHigh; /* Is sensor too high? */
- SK_BOOL TooLow; /* Is sensor too low? */
- SK_U64 CurrTime; /* Current Time */
- SK_BOOL DoTrapSend; /* We need to send a trap */
- SK_BOOL DoErrLog; /* We need to log the error */
- SK_BOOL IsError; /* We need to log the error */
-
- /* Check Dummy Reads first */
- if (pAC->I2c.DummyReads > 0) {
- pAC->I2c.DummyReads--;
- return;
- }
-
- /* Get the current time */
- CurrTime = SkOsGetTime(pAC);
-
- /* Set para to the most useful setting: The current sensor. */
- ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
-
- /* Check the Value against the thresholds. First: Error Thresholds */
- TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
- TooLow = (pSen->SenValue < pSen->SenThreErrLow);
-
- IsError = SK_FALSE;
- if (TooHigh || TooLow) {
- /* Error condition is satisfied */
- DoTrapSend = SK_TRUE;
- DoErrLog = SK_TRUE;
-
- /* Now error condition is satisfied */
- IsError = SK_TRUE;
-
- if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
- /* This state is the former one */
-
- /* So check first whether we have to send a trap */
- if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
- CurrTime) {
- /*
- * Do NOT send the Trap. The hold back time
- * has to run out first.
- */
- DoTrapSend = SK_FALSE;
- }
-
- /* Check now whether we have to log an Error */
- if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
- CurrTime) {
- /*
- * Do NOT log the error. The hold back time
- * has to run out first.
- */
- DoErrLog = SK_FALSE;
- }
- }
- else {
- /* We came from a different state -> Set Begin Time Stamp */
- pSen->SenBegErrTS = CurrTime;
- pSen->SenErrFlag = SK_SEN_ERR_ERR;
- }
-
- if (DoTrapSend) {
- /* Set current Time */
- pSen->SenLastErrTrapTS = CurrTime;
- pSen->SenErrCts++;
-
- /* Queue PNMI Event */
- SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
- SK_PNMI_EVT_SEN_ERR_UPP :
- SK_PNMI_EVT_SEN_ERR_LOW),
- ParaLocal);
- }
-
- if (DoErrLog) {
- /* Set current Time */
- pSen->SenLastErrLogTS = CurrTime;
-
- if (pSen->SenType == SK_SEN_TEMP) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
- }
- else if (pSen->SenType == SK_SEN_VOLT) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
- }
- else {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
- }
- }
- }
-
- /* Check the Value against the thresholds */
- /* 2nd: Warning thresholds */
- TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
- TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
-
- if (!IsError && (TooHigh || TooLow)) {
- /* Error condition is satisfied */
- DoTrapSend = SK_TRUE;
- DoErrLog = SK_TRUE;
-
- if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
- /* This state is the former one */
-
- /* So check first whether we have to send a trap */
- if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
- /*
- * Do NOT send the Trap. The hold back time
- * has to run out first.
- */
- DoTrapSend = SK_FALSE;
- }
-
- /* Check now whether we have to log an Error */
- if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
- /*
- * Do NOT log the error. The hold back time
- * has to run out first.
- */
- DoErrLog = SK_FALSE;
- }
- }
- else {
- /* We came from a different state -> Set Begin Time Stamp */
- pSen->SenBegWarnTS = CurrTime;
- pSen->SenErrFlag = SK_SEN_ERR_WARN;
- }
-
- if (DoTrapSend) {
- /* Set current Time */
- pSen->SenLastWarnTrapTS = CurrTime;
- pSen->SenWarnCts++;
-
- /* Queue PNMI Event */
- SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
- SK_PNMI_EVT_SEN_WAR_UPP :
- SK_PNMI_EVT_SEN_WAR_LOW),
- ParaLocal);
- }
-
- if (DoErrLog) {
- /* Set current Time */
- pSen->SenLastWarnLogTS = CurrTime;
-
- if (pSen->SenType == SK_SEN_TEMP) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
- }
- else if (pSen->SenType == SK_SEN_VOLT) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
- }
- else {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
- }
- }
- }
-
- /* Check for NO error at all */
- if (!IsError && !TooHigh && !TooLow) {
- /* Set o.k. Status if no error and no warning condition */
- pSen->SenErrFlag = SK_SEN_ERR_OK;
- }
-
- /* End of check against the thresholds */
-
- /* Bug fix AF: 16.Aug.2001: Correct the init base
- * of LM80 sensor.
- */
- if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
-
- pSen->SenInit = SK_SEN_DYN_INIT_NONE;
-
- if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
- /* 5V PCI-IO Voltage */
- pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
- pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
- }
- else {
- /* 3.3V PCI-IO Voltage */
- pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
- pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
- }
- }
-
-#ifdef TEST_ONLY
- /* Dynamic thresholds also for VAUX of LM80 sensor */
- if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
-
- pSen->SenInit = SK_SEN_DYN_INIT_NONE;
-
- /* 3.3V VAUX Voltage */
- if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
- pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
- pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
- }
- /* 0V VAUX Voltage */
- else {
- pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
- pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
- }
- }
-
- /*
- * Check initialization state:
- * The VIO Thresholds need adaption
- */
- if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
- pSen->SenValue > SK_SEN_WARNLOW2C &&
- pSen->SenValue < SK_SEN_WARNHIGH2) {
- pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
- pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
- pSen->SenInit = SK_TRUE;
- }
-
- if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
- pSen->SenValue > SK_SEN_WARNLOW2 &&
- pSen->SenValue < SK_SEN_WARNHIGH2C) {
- pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
- pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
- pSen->SenInit = SK_TRUE;
- }
-#endif
-
- if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
- }
-} /* SkI2cCheckSensor */
-
-
-/*
- * The only Event to be served is the timeout event
- *
- */
-int SkI2cEvent(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Event, /* Module specific Event */
-SK_EVPARA Para) /* Event specific Parameter */
-{
- int ReadComplete;
- SK_SENSOR *pSen;
- SK_U32 Time;
- SK_EVPARA ParaLocal;
- int i;
-
- /* New case: no sensors */
- if (pAC->I2c.MaxSens == 0) {
- return(0);
- }
-
- switch (Event) {
- case SK_I2CEV_IRQ:
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
- if (ReadComplete) {
- /* Check sensor against defined thresholds */
- SkI2cCheckSensor(pAC, pSen);
-
- /* Increment Current sensor and set appropriate Timeout */
- pAC->I2c.CurrSens++;
- if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
- pAC->I2c.CurrSens = 0;
- Time = SK_I2C_TIM_LONG;
- }
- else {
- Time = SK_I2C_TIM_SHORT;
- }
-
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
-
- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- else {
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
-
- pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
-
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- break;
- case SK_I2CEV_TIM:
- if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
-
- ParaLocal.Para64 = (SK_U64)0;
- SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
-
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
-
- if (ReadComplete) {
- /* Check sensor against defined thresholds */
- SkI2cCheckSensor(pAC, pSen);
-
- /* Increment Current sensor and set appropriate Timeout */
- pAC->I2c.CurrSens++;
- if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
- pAC->I2c.CurrSens = 0;
- Time = SK_I2C_TIM_LONG;
- }
- else {
- Time = SK_I2C_TIM_SHORT;
- }
-
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
-
- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- }
- else {
- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
- SK_I2C_STOP(IoC);
-
- /* Increment Current sensor and set appropriate Timeout */
- pAC->I2c.CurrSens++;
- if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
- pAC->I2c.CurrSens = 0;
- Time = SK_I2C_TIM_LONG;
- }
- else {
- Time = SK_I2C_TIM_SHORT;
- }
-
- /* Start Timer */
- ParaLocal.Para64 = (SK_U64)0;
-
- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
-
- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
- }
- break;
- case SK_I2CEV_CLEAR:
- for (i = 0; i < SK_MAX_SENSORS; i++) {
- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
- pAC->I2c.SenTable[i].SenErrCts = 0;
- pAC->I2c.SenTable[i].SenWarnCts = 0;
- pAC->I2c.SenTable[i].SenBegErrTS = 0;
- pAC->I2c.SenTable[i].SenBegWarnTS = 0;
- pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
- pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
- pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
- pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
- }
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
- }
-
- return(0);
-} /* SkI2cEvent*/
-
-#endif /* !SK_DIAG */
diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
deleted file mode 100644
index a204f5bb55d4..000000000000
--- a/drivers/net/sk98lin/sklm80.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/******************************************************************************
- *
- * Name: sklm80.c
- * Project: Gigabit Ethernet Adapters, TWSI-Module
- * Version: $Revision: 1.22 $
- * Date: $Date: 2003/10/20 09:08:21 $
- * Purpose: Functions to access Voltage and Temperature Sensor (LM80)
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- LM80 functions
-*/
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
-#endif
-
-#include "h/skdrv1st.h" /* Driver Specific Definitions */
-#include "h/lm80.h"
-#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
-
-#define BREAK_OR_WAIT(pAC,IoC,Event) break
-
-/*
- * read a sensors value (LM80 specific)
- *
- * This function reads a sensors value from the I2C sensor chip LM80.
- * The sensor is defined by its index into the sensors database in the struct
- * pAC points to.
- *
- * Returns 1 if the read is completed
- * 0 if the read must be continued (I2C Bus still allocated)
- */
-int SkLm80ReadSensor(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context needed in level 1 and 2 */
-SK_SENSOR *pSen) /* Sensor to be read */
-{
- SK_I32 Value;
-
- switch (pSen->SenState) {
- case SK_SEN_IDLE:
- /* Send address to ADDR register */
- SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
-
- pSen->SenState = SK_SEN_VALUE ;
- BREAK_OR_WAIT(pAC, IoC, I2C_READ);
-
- case SK_SEN_VALUE:
- /* Read value from data register */
- SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
-
- Value &= 0xff; /* only least significant byte is valid */
-
- /* Do NOT check the Value against the thresholds */
- /* Checking is done in the calling instance */
-
- if (pSen->SenType == SK_SEN_VOLT) {
- /* Voltage sensor */
- pSen->SenValue = Value * SK_LM80_VT_LSB;
- pSen->SenState = SK_SEN_IDLE ;
- return(1);
- }
-
- if (pSen->SenType == SK_SEN_FAN) {
- if (Value != 0 && Value != 0xff) {
- /* Fan speed counter */
- pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
- }
- else {
- /* Indicate Fan error */
- pSen->SenValue = 0;
- }
- pSen->SenState = SK_SEN_IDLE ;
- return(1);
- }
-
- /* First: correct the value: it might be negative */
- if ((Value & 0x80) != 0) {
- /* Value is negative */
- Value = Value - 256;
- }
-
- /* We have a temperature sensor and need to get the signed extension.
- * For now we get the extension from the last reading, so in the normal
- * case we won't see flickering temperatures.
- */
- pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
- (pSen->SenValue % SK_LM80_TEMP_LSB);
-
- /* Send address to ADDR register */
- SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
-
- pSen->SenState = SK_SEN_VALEXT ;
- BREAK_OR_WAIT(pAC, IoC, I2C_READ);
-
- case SK_SEN_VALEXT:
- /* Read value from data register */
- SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
- Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
-
- /* cut the LSB bit */
- pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
- SK_LM80_TEMP_LSB);
-
- if (pSen->SenValue < 0) {
- /* Value negative: The bit value must be subtracted */
- pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
- }
- else {
- /* Value positive: The bit value must be added */
- pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
- }
-
- pSen->SenState = SK_SEN_IDLE ;
- return(1);
-
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
- return(1);
- }
-
- /* Not completed */
- return(0);
-}
-
diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
deleted file mode 100644
index 0275b4f71d9b..000000000000
--- a/drivers/net/sk98lin/skqueue.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/******************************************************************************
- *
- * Name: skqueue.c
- * Project: Gigabit Ethernet Adapters, Event Scheduler Module
- * Version: $Revision: 1.20 $
- * Date: $Date: 2003/09/16 13:44:00 $
- * Purpose: Management of an event queue.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-/*
- * Event queue and dispatcher
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h" /* Driver Specific Definitions */
-#include "h/skqueue.h" /* Queue Definitions */
-#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
- Event queue management.
-
- General Description:
-
- */
-intro()
-{}
-#endif
-
-#define PRINTF(a,b,c)
-
-/*
- * init event queue management
- *
- * Must be called during init level 0.
- */
-void SkEventInit(
-SK_AC *pAC, /* Adapter context */
-SK_IOC Ioc, /* IO context */
-int Level) /* Init level */
-{
- switch (Level) {
- case SK_INIT_DATA:
- pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
- break;
- default:
- break;
- }
-}
-
-/*
- * add event to queue
- */
-void SkEventQueue(
-SK_AC *pAC, /* Adapters context */
-SK_U32 Class, /* Event Class */
-SK_U32 Event, /* Event to be queued */
-SK_EVPARA Para) /* Event parameter */
-{
- pAC->Event.EvPut->Class = Class;
- pAC->Event.EvPut->Event = Event;
- pAC->Event.EvPut->Para = Para;
-
- if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
- pAC->Event.EvPut = pAC->Event.EvQueue;
-
- if (pAC->Event.EvPut == pAC->Event.EvGet) {
- SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
- }
-}
-
-/*
- * event dispatcher
- * while event queue is not empty
- * get event from queue
- * send command to state machine
- * end
- * return error reported by individual Event function
- * 0 if no error occured.
- */
-int SkEventDispatcher(
-SK_AC *pAC, /* Adapters Context */
-SK_IOC Ioc) /* Io context */
-{
- SK_EVENTELEM *pEv; /* pointer into queue */
- SK_U32 Class;
- int Rtv;
-
- pEv = pAC->Event.EvGet;
-
- PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
-
- while (pEv != pAC->Event.EvPut) {
- PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
-
- switch (Class = pEv->Class) {
-#ifndef SK_USE_LAC_EV
-#ifndef SK_SLIM
- case SKGE_RLMT: /* RLMT Event */
- Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
- case SKGE_I2C: /* I2C Event */
- Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
- case SKGE_PNMI: /* PNMI Event */
- Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
-#endif /* not SK_SLIM */
-#endif /* not SK_USE_LAC_EV */
- case SKGE_DRV: /* Driver Event */
- Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
-#ifndef SK_USE_SW_TIMER
- case SKGE_HWAC:
- Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
-#else /* !SK_USE_SW_TIMER */
- case SKGE_SWT :
- Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
-#endif /* !SK_USE_SW_TIMER */
-#ifdef SK_USE_LAC_EV
- case SKGE_LACP :
- Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
- case SKGE_RSF :
- Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
- case SKGE_MARKER :
- Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
- case SKGE_FD :
- Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
-#endif /* SK_USE_LAC_EV */
-#ifdef SK_USE_CSUM
- case SKGE_CSUM :
- Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
- break;
-#endif /* SK_USE_CSUM */
- default :
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
- Rtv = 0;
- }
-
- if (Rtv != 0) {
- return(Rtv);
- }
-
- if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
- pEv = pAC->Event.EvQueue;
-
- /* Renew get: it is used in queue_events to detect overruns */
- pAC->Event.EvGet = pEv;
- }
-
- return(0);
-}
-
-/* End of file */
diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
deleted file mode 100644
index be8d1ccddf6d..000000000000
--- a/drivers/net/sk98lin/skrlmt.c
+++ /dev/null
@@ -1,3257 +0,0 @@
-/******************************************************************************
- *
- * Name: skrlmt.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.69 $
- * Date: $Date: 2003/04/15 09:39:22 $
- * Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
- * It is mainly intended for adapters with more than one link.
- * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
- *
- * Include File Hierarchy:
- *
- * "skdrv1st.h"
- * "skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef lint
-static const char SysKonnectFileId[] =
- "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
-#endif /* !defined(lint) */
-
-#define __SKRLMT_C
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* cplusplus */
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-#ifndef SK_HWAC_LINK_LED
-#define SK_HWAC_LINK_LED(a,b,c,d)
-#endif /* !defined(SK_HWAC_LINK_LED) */
-
-#ifndef DEBUG
-#define RLMT_STATIC static
-#else /* DEBUG */
-#define RLMT_STATIC
-
-#ifndef SK_LITTLE_ENDIAN
-/* First 32 bits */
-#define OFFS_LO32 1
-
-/* Second 32 bits */
-#define OFFS_HI32 0
-#else /* SK_LITTLE_ENDIAN */
-/* First 32 bits */
-#define OFFS_LO32 0
-
-/* Second 32 bits */
-#define OFFS_HI32 1
-#endif /* SK_LITTLE_ENDIAN */
-
-#endif /* DEBUG */
-
-/* ----- Private timeout values ----- */
-
-#define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */
-#define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */
-#define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */
-#define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */
-#define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */
-#define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. */
-
-/* Assume tick counter increment is 1 - may be set OS-dependent. */
-#ifndef SK_TICK_INCR
-#define SK_TICK_INCR SK_CONSTU64(1)
-#endif /* !defined(SK_TICK_INCR) */
-
-/*
- * Amount that a time stamp must be later to be recognized as "substantially
- * later". This is about 1/128 sec, but above 1 tick counter increment.
- */
-#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
- (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
-
-/* ----- Private RLMT defaults ----- */
-
-#define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */
-#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. */
-
-/* ----- Private RLMT checking states ----- */
-
-#define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */
-#define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */
-#define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */
-#define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. */
-
-/* ----- Private PORT checking states ----- */
-
-#define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */
-#define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. */
-
-/* ----- Private PORT events ----- */
-
-/* Note: Update simulation when changing these. */
-#define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */
-#define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */
-#define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */
-#define SK_RLMT_PORTDOWN 1103 /* Port went down. */
-#define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... */
-
-/* ----- Private RLMT events ----- */
-
-/* Note: Update simulation when changing these. */
-#define SK_RLMT_TIM 2100 /* RLMT timeout. */
-#define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */
-
-#define TO_SHORTEN(tim) ((tim) / 2)
-
-/* Error numbers and messages. */
-#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0)
-#define SKERR_RLMT_E001_MSG "No Packet."
-#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1)
-#define SKERR_RLMT_E002_MSG "Short Packet."
-#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1)
-#define SKERR_RLMT_E003_MSG "Unknown RLMT event."
-#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1)
-#define SKERR_RLMT_E004_MSG "PortsUp incorrect."
-#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1)
-#define SKERR_RLMT_E005_MSG \
- "Net seems to be segmented (different root bridges are reported on the ports)."
-#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1)
-#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected."
-#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1)
-#define SKERR_RLMT_E007_MSG "LinksUp incorrect."
-#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1)
-#define SKERR_RLMT_E008_MSG "Port not started but link came up."
-#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1)
-#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port."
-#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1)
-#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port."
-
-/* LLC field values. */
-#define LLC_COMMAND_RESPONSE_BIT 1
-#define LLC_TEST_COMMAND 0xE3
-#define LLC_UI 0x03
-
-/* RLMT Packet fields. */
-#define SK_RLMT_DSAP 0
-#define SK_RLMT_SSAP 0
-#define SK_RLMT_CTRL (LLC_TEST_COMMAND)
-#define SK_RLMT_INDICATOR0 0x53 /* S */
-#define SK_RLMT_INDICATOR1 0x4B /* K */
-#define SK_RLMT_INDICATOR2 0x2D /* - */
-#define SK_RLMT_INDICATOR3 0x52 /* R */
-#define SK_RLMT_INDICATOR4 0x4C /* L */
-#define SK_RLMT_INDICATOR5 0x4D /* M */
-#define SK_RLMT_INDICATOR6 0x54 /* T */
-#define SK_RLMT_PACKET_VERSION 0
-
-/* RLMT SPT Flag values. */
-#define SK_RLMT_SPT_FLAG_CHANGE 0x01
-#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80
-
-/* RLMT SPT Packet fields. */
-#define SK_RLMT_SPT_DSAP 0x42
-#define SK_RLMT_SPT_SSAP 0x42
-#define SK_RLMT_SPT_CTRL (LLC_UI)
-#define SK_RLMT_SPT_PROTOCOL_ID0 0x00
-#define SK_RLMT_SPT_PROTOCOL_ID1 0x00
-#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
-#define SK_RLMT_SPT_BPDU_TYPE 0x00
-#define SK_RLMT_SPT_FLAGS 0x00 /* ?? */
-#define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */
-#define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. */
-
-/* Remaining 6 bytes will be the current port address. */
-#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00
-#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00
-#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00
-#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00
-#define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */
-#define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. */
-
-/* Remaining 6 bytes will be the current port address. */
-#define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */
-#define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */
-#define SK_RLMT_SPT_MSG_AGE0 0x00
-#define SK_RLMT_SPT_MSG_AGE1 0x00
-#define SK_RLMT_SPT_MAX_AGE0 0x00
-#define SK_RLMT_SPT_MAX_AGE1 0xFF
-#define SK_RLMT_SPT_HELLO_TIME0 0x00
-#define SK_RLMT_SPT_HELLO_TIME1 0xFF
-#define SK_RLMT_SPT_FWD_DELAY0 0x00
-#define SK_RLMT_SPT_FWD_DELAY1 0x40
-
-/* Size defines. */
-#define SK_RLMT_MIN_PACKET_SIZE 34
-#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE)
-#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \
- SK_RLMT_MIN_PACKET_SIZE)
-
-/* ----- RLMT packet types ----- */
-#define SK_PACKET_ANNOUNCE 1 /* Port announcement. */
-#define SK_PACKET_ALIVE 2 /* Alive packet to port. */
-#define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */
-#define SK_PACKET_CHECK_TX 4 /* Check your tx line. */
-
-#ifdef SK_LITTLE_ENDIAN
-#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
- SK_U8 *_Addr = (SK_U8*)(Addr); \
- SK_U16 _Val = (SK_U16)(Val); \
- *_Addr++ = (SK_U8)(_Val >> 8); \
- *_Addr = (SK_U8)(_Val & 0xFF); \
-}
-#endif /* SK_LITTLE_ENDIAN */
-
-#ifdef SK_BIG_ENDIAN
-#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
-#endif /* SK_BIG_ENDIAN */
-
-#define AUTONEG_FAILED SK_FALSE
-#define AUTONEG_SUCCESS SK_TRUE
-
-
-/* typedefs *******************************************************************/
-
-/* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
-typedef struct s_RlmtPacket {
- SK_U8 DstAddr[SK_MAC_ADDR_LEN];
- SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
- SK_U8 TypeLen[2];
- SK_U8 DSap;
- SK_U8 SSap;
- SK_U8 Ctrl;
- SK_U8 Indicator[7];
- SK_U8 RlmtPacketType[2];
- SK_U8 Align1[2];
- SK_U8 Random[4]; /* Random value of requesting(!) station. */
- SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */
- SK_U8 Data[SK_PACKET_DATA_LEN];
-} SK_RLMT_PACKET;
-
-typedef struct s_SpTreeRlmtPacket {
- SK_U8 DstAddr[SK_MAC_ADDR_LEN];
- SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
- SK_U8 TypeLen[2];
- SK_U8 DSap;
- SK_U8 SSap;
- SK_U8 Ctrl;
- SK_U8 ProtocolId[2];
- SK_U8 ProtocolVersionId;
- SK_U8 BpduType;
- SK_U8 Flags;
- SK_U8 RootId[8];
- SK_U8 RootPathCost[4];
- SK_U8 BridgeId[8];
- SK_U8 PortId[2];
- SK_U8 MessageAge[2];
- SK_U8 MaxAge[2];
- SK_U8 HelloTime[2];
- SK_U8 ForwardDelay[2];
-} SK_SPTREE_PACKET;
-
-/* global variables ***********************************************************/
-
-SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}};
-SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}};
-
-/* local variables ************************************************************/
-
-/* None. */
-
-/* functions ******************************************************************/
-
-RLMT_STATIC void SkRlmtCheckSwitch(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 NetIdx);
-RLMT_STATIC void SkRlmtCheckSeg(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_U32 NetIdx);
-RLMT_STATIC void SkRlmtEvtSetNets(
- SK_AC *pAC,
- SK_IOC IoC,
- SK_EVPARA Para);
-
-/******************************************************************************
- *
- * SkRlmtInit - initialize data, set state to init
- *
- * Description:
- *
- * SK_INIT_DATA
- * ============
- *
- * This routine initializes all RLMT-related variables to a known state.
- * The initial state is SK_RLMT_RS_INIT.
- * All ports are initialized to SK_RLMT_PS_INIT.
- *
- *
- * SK_INIT_IO
- * ==========
- *
- * Nothing.
- *
- *
- * SK_INIT_RUN
- * ===========
- *
- * Determine the adapter's random value.
- * Set the hw registers, the "logical MAC address", the
- * RLMT multicast address, and eventually the BPDU multicast address.
- *
- * Context:
- * init, pageable
- *
- * Returns:
- * Nothing.
- */
-void SkRlmtInit(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Level) /* Initialization Level */
-{
- SK_U32 i, j;
- SK_U64 Random;
- SK_EVPARA Para;
- SK_MAC_ADDR VirtualMacAddress;
- SK_MAC_ADDR PhysicalAMacAddress;
- SK_BOOL VirtualMacAddressSet;
- SK_BOOL PhysicalAMacAddressSet;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
- ("RLMT Init level %d.\n", Level))
-
- switch (Level) {
- case SK_INIT_DATA: /* Initialize data structures. */
- SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
-
- for (i = 0; i < SK_MAX_MACS; i++) {
- pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
- pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
- pAC->Rlmt.Port[i].PortDown = SK_TRUE;
- pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
- pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
- pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
- pAC->Rlmt.Port[i].PortNumber = i;
- pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
- pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
- }
-
- pAC->Rlmt.NumNets = 1;
- for (i = 0; i < SK_MAX_NETS; i++) {
- pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
- pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
- pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
- pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */
- /* Just assuming. */
- pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
- pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
- pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
- pAC->Rlmt.Net[i].NetNumber = i;
- }
-
- pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
- pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
-#if SK_MAX_NETS > 1
- pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
-#endif /* SK_MAX_NETS > 1 */
- break;
-
- case SK_INIT_IO: /* GIMacsFound first available here. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
- ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
-
- pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
-
- /* Initialize HW registers? */
- if (pAC->GIni.GIMacsFound == 1) {
- Para.Para32[0] = SK_RLMT_MODE_CLS;
- Para.Para32[1] = 0;
- (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
- }
- break;
-
- case SK_INIT_RUN:
- /* Ensure RLMT is set to one net. */
- if (pAC->Rlmt.NumNets > 1) {
- Para.Para32[0] = 1;
- Para.Para32[1] = -1;
- SkRlmtEvtSetNets(pAC, IoC, Para);
- }
-
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- Random = SkOsGetTime(pAC);
- *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
-
- for (j = 0; j < 4; j++) {
- pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
- CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
- }
-
- (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-
- /* Add RLMT MC address. */
- (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
-
- if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
- /* Add BPDU MC address. */
- (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
- }
-
- (void)SkAddrMcUpdate(pAC, IoC, i);
- }
-
- VirtualMacAddressSet = SK_FALSE;
- /* Read virtual MAC address from Control Register File. */
- for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-
- SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
- VirtualMacAddressSet |= VirtualMacAddress.a[j];
- }
-
- PhysicalAMacAddressSet = SK_FALSE;
- /* Read physical MAC address for MAC A from Control Register File. */
- for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-
- SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
- PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
- }
-
- /* check if the two mac addresses contain reasonable values */
- if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
-
- pAC->Rlmt.RlmtOff = SK_TRUE;
- }
-
- /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
- and the RLMT_LOOKAHEAD macros */
- else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
-
- pAC->Rlmt.RlmtOff = SK_TRUE;
- }
- else {
- pAC->Rlmt.RlmtOff = SK_FALSE;
- }
- break;
-
- default: /* error */
- break;
- }
- return;
-} /* SkRlmtInit */
-
-
-/******************************************************************************
- *
- * SkRlmtBuildCheckChain - build the check chain
- *
- * Description:
- * This routine builds the local check chain:
- * - Each port that is up checks the next port.
- * - The last port that is up checks the first port that is up.
- *
- * Notes:
- * - Currently only local ports are considered when building the chain.
- * - Currently the SuspectState is just reset;
- * it would be better to save it ...
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtBuildCheckChain(
-SK_AC *pAC, /* Adapter Context */
-SK_U32 NetIdx) /* Net Number */
-{
- SK_U32 i;
- SK_U32 NumMacsUp;
- SK_RLMT_PORT * FirstMacUp;
- SK_RLMT_PORT * PrevMacUp;
-
- FirstMacUp = NULL;
- PrevMacUp = NULL;
-
- if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
- for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
- pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
- }
- return; /* Done. */
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SkRlmtBuildCheckChain.\n"))
-
- NumMacsUp = 0;
-
- for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
- pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
- pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
- pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
- ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
-
- /*
- * If more than two links are detected we should consider
- * checking at least two other ports:
- * 1. the next port that is not LinkDown and
- * 2. the next port that is not PortDown.
- */
- if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
- if (NumMacsUp == 0) {
- FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
- }
- else {
- PrevMacUp->PortCheck[
- pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
- pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
- PrevMacUp->PortCheck[
- PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
- PrevMacUp->PortsChecked++;
- }
- PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
- NumMacsUp++;
- }
- }
-
- if (NumMacsUp > 1) {
- PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
- FirstMacUp->AddrPort->CurrentMacAddress;
- PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
- SK_FALSE;
- PrevMacUp->PortsChecked++;
- }
-
-#ifdef DEBUG
- for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Port %d checks %d other ports: %2X.\n", i,
- pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
- pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
- }
-#endif /* DEBUG */
-
- return;
-} /* SkRlmtBuildCheckChain */
-
-
-/******************************************************************************
- *
- * SkRlmtBuildPacket - build an RLMT packet
- *
- * Description:
- * This routine sets up an RLMT packet.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * NULL or pointer to RLMT mbuf
- */
-RLMT_STATIC SK_MBUF *SkRlmtBuildPacket(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 PortNumber, /* Sending port */
-SK_U16 PacketType, /* RLMT packet type */
-SK_MAC_ADDR *SrcAddr, /* Source address */
-SK_MAC_ADDR *DestAddr) /* Destination address */
-{
- int i;
- SK_U16 Length;
- SK_MBUF *pMb;
- SK_RLMT_PACKET *pPacket;
-
-#ifdef DEBUG
- SK_U8 CheckSrc = 0;
- SK_U8 CheckDest = 0;
-
- for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
- CheckSrc |= SrcAddr->a[i];
- CheckDest |= DestAddr->a[i];
- }
-
- if ((CheckSrc == 0) || (CheckDest == 0)) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
- ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
- (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
- }
-#endif
-
- if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
- pPacket = (SK_RLMT_PACKET*)pMb->pData;
- for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
- pPacket->DstAddr[i] = DestAddr->a[i];
- pPacket->SrcAddr[i] = SrcAddr->a[i];
- }
- pPacket->DSap = SK_RLMT_DSAP;
- pPacket->SSap = SK_RLMT_SSAP;
- pPacket->Ctrl = SK_RLMT_CTRL;
- pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
- pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
- pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
- pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
- pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
- pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
- pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
-
- SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
-
- for (i = 0; i < 4; i++) {
- pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
- }
-
- SK_U16_TO_NETWORK_ORDER(
- SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
-
- for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
- pPacket->Data[i] = 0x00;
- }
-
- Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
- pMb->Length = Length;
- pMb->PortIdx = PortNumber;
- Length -= 14;
- SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
-
- if (PacketType == SK_PACKET_ALIVE) {
- pAC->Rlmt.Port[PortNumber].TxHelloCts++;
- }
- }
-
- return (pMb);
-} /* SkRlmtBuildPacket */
-
-
-/******************************************************************************
- *
- * SkRlmtBuildSpanningTreePacket - build spanning tree check packet
- *
- * Description:
- * This routine sets up a BPDU packet for spanning tree check.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * NULL or pointer to RLMT mbuf
- */
-RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 PortNumber) /* Sending port */
-{
- unsigned i;
- SK_U16 Length;
- SK_MBUF *pMb;
- SK_SPTREE_PACKET *pSPacket;
-
- if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
- NULL) {
- pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
- for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
- pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
- pSPacket->SrcAddr[i] =
- pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
- }
- pSPacket->DSap = SK_RLMT_SPT_DSAP;
- pSPacket->SSap = SK_RLMT_SPT_SSAP;
- pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
-
- pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
- pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
- pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
- pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
- pSPacket->Flags = SK_RLMT_SPT_FLAGS;
- pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
- pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
- pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
- pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
- pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
- pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
- pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
- pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
-
- /*
- * Use logical MAC address as bridge ID and filter these packets
- * on receive.
- */
- for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
- pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
- pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
- CurrentMacAddress.a[i];
- }
- pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
- pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
- pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
- pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
- pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
- pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
- pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
- pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
- pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
- pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
-
- Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
- pMb->Length = Length;
- pMb->PortIdx = PortNumber;
- Length -= 14;
- SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
-
- pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
- }
-
- return (pMb);
-} /* SkRlmtBuildSpanningTreePacket */
-
-
-/******************************************************************************
- *
- * SkRlmtSend - build and send check packets
- *
- * Description:
- * Depending on the RLMT state and the checking state, several packets
- * are sent through the indicated port.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing.
- */
-RLMT_STATIC void SkRlmtSend(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 PortNumber) /* Sending port */
-{
- unsigned j;
- SK_EVPARA Para;
- SK_RLMT_PORT *pRPort;
-
- pRPort = &pAC->Rlmt.Port[PortNumber];
- if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
- if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
- /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
- if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
- SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
- &SkRlmtMcAddr)) != NULL) {
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- }
- }
- else {
- /*
- * Send a directed RLMT packet to all ports that are
- * checked by the indicated port.
- */
- for (j = 0; j < pRPort->PortsChecked; j++) {
- if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
- SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
- &pRPort->PortCheck[j].CheckAddr)) != NULL) {
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- }
- }
- }
- }
-
- if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
- (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
- /*
- * Send a BPDU packet to make a connected switch tell us
- * the correct root bridge.
- */
- if ((Para.pParaPtr =
- SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
- pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
- pRPort->RootIdSet = SK_FALSE;
-
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
- ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
- }
- }
- return;
-} /* SkRlmtSend */
-
-
-/******************************************************************************
- *
- * SkRlmtPortReceives - check if port is (going) down and bring it up
- *
- * Description:
- * This routine checks if a port who received a non-BPDU packet
- * needs to go up or needs to be stopped going down.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing.
- */
-RLMT_STATIC void SkRlmtPortReceives(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 PortNumber) /* Port to check */
-{
- SK_RLMT_PORT *pRPort;
- SK_EVPARA Para;
-
- pRPort = &pAC->Rlmt.Port[PortNumber];
- pRPort->PortNoRx = SK_FALSE;
-
- if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
- !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
- /*
- * Port is marked down (rx), but received a non-BPDU packet.
- * Bring it up.
- */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Received on PortDown.\n"))
-
- pRPort->PortState = SK_RLMT_PS_GOING_UP;
- pRPort->GuTimeStamp = SkOsGetTime(pAC);
- Para.Para32[0] = PortNumber;
- Para.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
- SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
- pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
- /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
- SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
- } /* PortDown && !SuspectTx */
- else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Stop bringing port down.\n"))
- SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
- pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
- /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
- SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
- } /* PortGoingDown */
-
- return;
-} /* SkRlmtPortReceives */
-
-
-/******************************************************************************
- *
- * SkRlmtPacketReceive - receive a packet for closer examination
- *
- * Description:
- * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing.
- */
-RLMT_STATIC void SkRlmtPacketReceive(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_MBUF *pMb) /* Received packet */
-{
-#ifdef xDEBUG
- extern void DumpData(char *p, int size);
-#endif /* DEBUG */
- int i;
- unsigned j;
- SK_U16 PacketType;
- SK_U32 PortNumber;
- SK_ADDR_PORT *pAPort;
- SK_RLMT_PORT *pRPort;
- SK_RLMT_PACKET *pRPacket;
- SK_SPTREE_PACKET *pSPacket;
- SK_EVPARA Para;
-
- PortNumber = pMb->PortIdx;
- pAPort = &pAC->Addr.Port[PortNumber];
- pRPort = &pAC->Rlmt.Port[PortNumber];
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
-
- pRPacket = (SK_RLMT_PACKET*)pMb->pData;
- pSPacket = (SK_SPTREE_PACKET*)pRPacket;
-
-#ifdef xDEBUG
- DumpData((char *)pRPacket, 32);
-#endif /* DEBUG */
-
- if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
- SkRlmtPortReceives(pAC, IoC, PortNumber);
- }
-
- /* Check destination address. */
-
- if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
- !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
- !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
-
- /* Not sent to current MAC or registered MC address => Trash it. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Not for me.\n"))
-
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- return;
- }
- else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
-
- /*
- * Was sent by same port (may happen during port switching
- * or in case of duplicate MAC addresses).
- */
-
- /*
- * Check for duplicate address here:
- * If Packet.Random != My.Random => DupAddr.
- */
- for (i = 3; i >= 0; i--) {
- if (pRPort->Random[i] != pRPacket->Random[i]) {
- break;
- }
- }
-
- /*
- * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
- * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
- * pRPacket->SSap).
- */
- if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
- pRPacket->Ctrl == SK_RLMT_CTRL &&
- pRPacket->SSap == SK_RLMT_SSAP &&
- pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
- pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
- pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
- pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
- pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
- pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
- pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
-
- /* Error Log entry. */
- SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
- }
- else {
- /* Simply trash it. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Sent by me.\n"))
- }
-
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- return;
- }
-
- /* Check SuspectTx entries. */
- if (pRPort->PortsSuspect > 0) {
- for (j = 0; j < pRPort->PortsChecked; j++) {
- if (pRPort->PortCheck[j].SuspectTx &&
- SK_ADDR_EQUAL(
- pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
- pRPort->PortCheck[j].SuspectTx = SK_FALSE;
- pRPort->PortsSuspect--;
- break;
- }
- }
- }
-
- /* Determine type of packet. */
- if (pRPacket->DSap == SK_RLMT_DSAP &&
- pRPacket->Ctrl == SK_RLMT_CTRL &&
- (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
- pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
- pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
- pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
- pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
- pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
- pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
- pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
-
- /* It's an RLMT packet. */
- PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
- pRPacket->RlmtPacketType[1]);
-
- switch (PacketType) {
- case SK_PACKET_ANNOUNCE: /* Not yet used. */
-#if 0
- /* Build the check chain. */
- SkRlmtBuildCheckChain(pAC);
-#endif /* 0 */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Announce.\n"))
-
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- break;
-
- case SK_PACKET_ALIVE:
- if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Alive Reply.\n"))
-
- if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
- SK_ADDR_EQUAL(
- pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
- /* Obviously we could send something. */
- if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
- pRPort->CheckingState &= ~SK_RLMT_PCS_TX;
- SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
- }
-
- if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
- !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
- pRPort->PortState = SK_RLMT_PS_GOING_UP;
- pRPort->GuTimeStamp = SkOsGetTime(pAC);
-
- SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
- Para.Para32[0] = PortNumber;
- Para.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->UpTimer,
- SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
- SK_RLMT_PORTUP_TIM, Para);
- }
- }
-
- /* Mark sending port as alive? */
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- }
- else { /* Alive Request Packet. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Alive Request.\n"))
-
- pRPort->RxHelloCts++;
-
- /* Answer. */
- for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
- pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
- pRPacket->SrcAddr[i] =
- pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
- }
- pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
-
- Para.pParaPtr = pMb;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- }
- break;
-
- case SK_PACKET_CHECK_TX:
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Check your tx line.\n"))
-
- /* A port checking us requests us to check our tx line. */
- pRPort->CheckingState |= SK_RLMT_PCS_TX;
-
- /* Start PortDownTx timer. */
- Para.Para32[0] = PortNumber;
- Para.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
- SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
- SK_RLMT_PORTDOWN_TX_TIM, Para);
-
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
-
- if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
- SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
- &SkRlmtMcAddr)) != NULL) {
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- }
- break;
-
- case SK_PACKET_ADDR_CHANGED:
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Address Change.\n"))
-
- /* Build the check chain. */
- SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- break;
-
- default:
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
-
- /* RA;:;: ??? */
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- }
- }
- else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
- pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
- (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: BPDU Packet.\n"))
-
- /* Spanning Tree packet. */
- pRPort->RxSpHelloCts++;
-
- if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
- Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
- /*
- * Check segmentation if a new root bridge is set and
- * the segmentation check is not currently running.
- */
- if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
- (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
- (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
- != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
- SK_RLMT_RCS_SEG) == 0) {
- pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
- SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
- }
-
- /* Store tree view of this port. */
- for (i = 0; i < 8; i++) {
- pRPort->Root.Id[i] = pSPacket->RootId[i];
- }
- pRPort->RootIdSet = SK_TRUE;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
- ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
- PortNumber,
- pRPort->Root.Id[0], pRPort->Root.Id[1],
- pRPort->Root.Id[2], pRPort->Root.Id[3],
- pRPort->Root.Id[4], pRPort->Root.Id[5],
- pRPort->Root.Id[6], pRPort->Root.Id[7]))
- }
-
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
- SK_RLMT_RCS_REPORT_SEG) != 0) {
- SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
- }
- }
- else {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
- ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
-
- /* Unknown packet. */
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- }
- return;
-} /* SkRlmtPacketReceive */
-
-
-/******************************************************************************
- *
- * SkRlmtCheckPort - check if a port works
- *
- * Description:
- * This routine checks if a port whose link is up received something
- * and if it seems to transmit successfully.
- *
- * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
- * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
- * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
- *
- * if (Rx - RxBpdu == 0) { # No rx.
- * if (state == PsUp) {
- * PortCheckingState |= ChkRx
- * }
- * if (ModeCheckSeg && (Timeout ==
- * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
- * RlmtCheckingState |= ChkSeg)
- * PortCheckingState |= ChkSeg
- * }
- * NewTimeout = TO_SHORTEN(Timeout)
- * if (NewTimeout < RLMT_MIN_TIMEOUT) {
- * NewTimeout = RLMT_MIN_TIMEOUT
- * PortState = PsDown
- * ...
- * }
- * }
- * else { # something was received
- * # Set counter to 0 at LinkDown?
- * # No - rx may be reported after LinkDown ???
- * PortCheckingState &= ~ChkRx
- * NewTimeout = RLMT_DEFAULT_TIMEOUT
- * if (RxAck == 0) {
- * possible reasons:
- * is my tx line bad? --
- * send RLMT multicast and report
- * back internally? (only possible
- * between ports on same adapter)
- * }
- * if (RxChk == 0) {
- * possible reasons:
- * - tx line of port set to check me
- * maybe bad
- * - no other port/adapter available or set
- * to check me
- * - adapter checking me has a longer
- * timeout
- * ??? anything that can be done here?
- * }
- * }
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * New timeout value.
- */
-RLMT_STATIC SK_U32 SkRlmtCheckPort(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 PortNumber) /* Port to check */
-{
- unsigned i;
- SK_U32 NewTimeout;
- SK_RLMT_PORT *pRPort;
- SK_EVPARA Para;
-
- pRPort = &pAC->Rlmt.Port[PortNumber];
-
- if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
- PortNumber, pRPort->PacketsPerTimeSlot))
-
- /*
- * Check segmentation if there was no receive at least twice
- * in a row (PortNoRx is already set) and the segmentation
- * check is not currently running.
- */
-
- if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
- (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
- !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
- pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
- SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
- pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
-
- if (pRPort->PortState != SK_RLMT_PS_DOWN) {
- NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
- if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
- NewTimeout = SK_RLMT_MIN_TO_VAL;
- }
-
- if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
- Para.Para32[0] = PortNumber;
- pRPort->CheckingState |= SK_RLMT_PCS_RX;
-
- /*
- * What shall we do if the port checked by this one receives
- * our request frames? What's bad - our rx line or his tx line?
- */
- Para.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
- SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
- SK_RLMT_PORTDOWN_RX_TIM, Para);
-
- for (i = 0; i < pRPort->PortsChecked; i++) {
- if (pRPort->PortCheck[i].SuspectTx) {
- continue;
- }
- pRPort->PortCheck[i].SuspectTx = SK_TRUE;
- pRPort->PortsSuspect++;
- if ((Para.pParaPtr =
- SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
- &pAC->Addr.Port[PortNumber].CurrentMacAddress,
- &pRPort->PortCheck[i].CheckAddr)) != NULL) {
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- }
- }
- }
- }
- else { /* PortDown -- or all partners suspect. */
- NewTimeout = SK_RLMT_DEF_TO_VAL;
- }
- pRPort->PortNoRx = SK_TRUE;
- }
- else { /* A non-BPDU packet was received. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
- PortNumber,
- pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
- pRPort->PacketsPerTimeSlot))
-
- SkRlmtPortReceives(pAC, IoC, PortNumber);
- if (pAC->Rlmt.CheckSwitch) {
- SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
- }
-
- NewTimeout = SK_RLMT_DEF_TO_VAL;
- }
-
- return (NewTimeout);
-} /* SkRlmtCheckPort */
-
-
-/******************************************************************************
- *
- * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
- *
- * Description:
- * This routine selects the port that received a broadcast frame
- * substantially later than all other ports.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * SK_BOOL
- */
-RLMT_STATIC SK_BOOL SkRlmtSelectBcRx(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Active, /* Active port */
-SK_U32 PrefPort, /* Preferred port */
-SK_U32 *pSelect) /* New active port */
-{
- SK_U64 BcTimeStamp;
- SK_U32 i;
- SK_BOOL PortFound;
-
- BcTimeStamp = 0; /* Not totally necessary, but feeling better. */
- PortFound = SK_FALSE;
-
- /* Select port with the latest TimeStamp. */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
- i,
- pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
- *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
- *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
-
- if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
- if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
- BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
- *pSelect = i;
- PortFound = SK_TRUE;
- }
- }
- }
-
- if (PortFound) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Port %d received the last broadcast.\n", *pSelect))
-
- /* Look if another port's time stamp is similar. */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- if (i == *pSelect) {
- continue;
- }
- if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
- (pAC->Rlmt.Port[i].BcTimeStamp >
- BcTimeStamp - SK_RLMT_BC_DELTA ||
- pAC->Rlmt.Port[i].BcTimeStamp +
- SK_RLMT_BC_DELTA > BcTimeStamp)) {
- PortFound = SK_FALSE;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Port %d received a broadcast at a similar time.\n", i))
- break;
- }
- }
- }
-
-#ifdef DEBUG
- if (PortFound) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
- "latest broadcast (%u).\n",
- *pSelect,
- BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
- }
-#endif /* DEBUG */
-
- return (PortFound);
-} /* SkRlmtSelectBcRx */
-
-
-/******************************************************************************
- *
- * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
- *
- * Description:
- * This routine selects a good port (it is PortUp && !SuspectRx).
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * SK_BOOL
- */
-RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Active, /* Active port */
-SK_U32 PrefPort, /* Preferred port */
-SK_U32 *pSelect) /* New active port */
-{
- SK_U32 i;
- SK_BOOL PortFound;
-
- PortFound = SK_FALSE;
-
- /* Select first port that is PortUp && !SuspectRx. */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- if (!pAC->Rlmt.Port[i].PortDown &&
- !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
- *pSelect = i;
- if (!pAC->Rlmt.Port[Active].PortDown &&
- !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
- *pSelect = Active;
- }
- if (!pAC->Rlmt.Port[PrefPort].PortDown &&
- !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
- *pSelect = PrefPort;
- }
- PortFound = SK_TRUE;
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
- *pSelect))
- break;
- }
- }
- return (PortFound);
-} /* SkRlmtSelectNotSuspect */
-
-
-/******************************************************************************
- *
- * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
- *
- * Description:
- * This routine selects a port that is up.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * SK_BOOL
- */
-RLMT_STATIC SK_BOOL SkRlmtSelectUp(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Active, /* Active port */
-SK_U32 PrefPort, /* Preferred port */
-SK_U32 *pSelect, /* New active port */
-SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
-{
- SK_U32 i;
- SK_BOOL PortFound;
-
- PortFound = SK_FALSE;
-
- /* Select first port that is PortUp. */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
- pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
- *pSelect = i;
- if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
- pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
- *pSelect = Active;
- }
- if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
- pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
- *pSelect = PrefPort;
- }
- PortFound = SK_TRUE;
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
- break;
- }
- }
- return (PortFound);
-} /* SkRlmtSelectUp */
-
-
-/******************************************************************************
- *
- * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
- *
- * Description:
- * This routine selects the port that is going up for the longest time.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * SK_BOOL
- */
-RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Active, /* Active port */
-SK_U32 PrefPort, /* Preferred port */
-SK_U32 *pSelect, /* New active port */
-SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
-{
- SK_U64 GuTimeStamp;
- SK_U32 i;
- SK_BOOL PortFound;
-
- GuTimeStamp = 0;
- PortFound = SK_FALSE;
-
- /* Select port that is PortGoingUp for the longest time. */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
- pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
- GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
- *pSelect = i;
- PortFound = SK_TRUE;
- break;
- }
- }
-
- if (!PortFound) {
- return (SK_FALSE);
- }
-
- for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
- pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
- pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
- GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
- *pSelect = i;
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
- return (SK_TRUE);
-} /* SkRlmtSelectGoingUp */
-
-
-/******************************************************************************
- *
- * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
- *
- * Description:
- * This routine selects a port that is down.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * SK_BOOL
- */
-RLMT_STATIC SK_BOOL SkRlmtSelectDown(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Active, /* Active port */
-SK_U32 PrefPort, /* Preferred port */
-SK_U32 *pSelect, /* New active port */
-SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
-{
- SK_U32 i;
- SK_BOOL PortFound;
-
- PortFound = SK_FALSE;
-
- /* Select first port that is PortDown. */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
- pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
- *pSelect = i;
- if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
- pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
- *pSelect = Active;
- }
- if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
- pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
- *pSelect = PrefPort;
- }
- PortFound = SK_TRUE;
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
- break;
- }
- }
- return (PortFound);
-} /* SkRlmtSelectDown */
-
-
-/******************************************************************************
- *
- * SkRlmtCheckSwitch - select new active port and switch to it
- *
- * Description:
- * This routine decides which port should be the active one and queues
- * port switching if necessary.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing.
- */
-RLMT_STATIC void SkRlmtCheckSwitch(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 NetIdx) /* Net index */
-{
- SK_EVPARA Para;
- SK_U32 Active;
- SK_U32 PrefPort;
- SK_U32 i;
- SK_BOOL PortFound;
-
- Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */
- PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */
- PortFound = SK_FALSE;
- pAC->Rlmt.CheckSwitch = SK_FALSE;
-
-#if 0 /* RW 2001/10/18 - active port becomes always prefered one */
- if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
- /* disable auto-fail back */
- PrefPort = Active;
- }
-#endif
-
- if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
- /* Last link went down - shut down the net. */
- pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
- Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
- Para.Para32[1] = NetIdx;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
-
- Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
- Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
- Para.Para32[1] = NetIdx;
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
- return;
- } /* pAC->Rlmt.LinksUp == 0 */
- else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
- pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
- /* First link came up - get the net up. */
- pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
-
- /*
- * If pAC->Rlmt.ActivePort != Para.Para32[0],
- * the DRV switches to the port that came up.
- */
- for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
- if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
- if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
- i = Active;
- }
- if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
- i = PrefPort;
- }
- PortFound = SK_TRUE;
- break;
- }
- }
-
- if (PortFound) {
- Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
- Para.Para32[1] = NetIdx;
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
-
- pAC->Rlmt.Net[NetIdx].ActivePort = i;
- Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
- Para.Para32[1] = NetIdx;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
-
- if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
- (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
- pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
- SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
- CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
- /*
- * Send announce packet to RLMT multicast address to force
- * switches to learn the new location of the logical MAC address.
- */
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- }
- }
- else {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
- }
-
- return;
- } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
- else { /* Cannot be reached in dual-net mode. */
- Para.Para32[0] = Active;
-
- /*
- * Preselection:
- * If RLMT Mode != CheckLinkState
- * select port that received a broadcast frame substantially later
- * than all other ports
- * else select first port that is not SuspectRx
- * else select first port that is PortUp
- * else select port that is PortGoingUp for the longest time
- * else select first port that is PortDown
- * else stop.
- *
- * For the preselected port:
- * If ActivePort is equal in quality, select ActivePort.
- *
- * If PrefPort is equal in quality, select PrefPort.
- *
- * If ActivePort != SelectedPort,
- * If old ActivePort is LinkDown,
- * SwitchHard
- * else
- * SwitchSoft
- */
- /* check of ChgBcPrio flag added */
- if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
- (!pAC->Rlmt.Net[0].ChgBcPrio)) {
-
- if (!PortFound) {
- PortFound = SkRlmtSelectBcRx(
- pAC, IoC, Active, PrefPort, &Para.Para32[1]);
- }
-
- if (!PortFound) {
- PortFound = SkRlmtSelectNotSuspect(
- pAC, IoC, Active, PrefPort, &Para.Para32[1]);
- }
- } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
- /* with changed priority for last broadcast received */
- if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
- (pAC->Rlmt.Net[0].ChgBcPrio)) {
- if (!PortFound) {
- PortFound = SkRlmtSelectNotSuspect(
- pAC, IoC, Active, PrefPort, &Para.Para32[1]);
- }
-
- if (!PortFound) {
- PortFound = SkRlmtSelectBcRx(
- pAC, IoC, Active, PrefPort, &Para.Para32[1]);
- }
- } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
- if (!PortFound) {
- PortFound = SkRlmtSelectUp(
- pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
- }
-
- if (!PortFound) {
- PortFound = SkRlmtSelectUp(
- pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
- }
-
- if (!PortFound) {
- PortFound = SkRlmtSelectGoingUp(
- pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
- }
-
- if (!PortFound) {
- PortFound = SkRlmtSelectGoingUp(
- pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
- }
-
- if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
- if (!PortFound) {
- PortFound = SkRlmtSelectDown(pAC, IoC,
- Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
- }
-
- if (!PortFound) {
- PortFound = SkRlmtSelectDown(pAC, IoC,
- Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
- }
- } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
-
- if (PortFound) {
-
- if (Para.Para32[1] != Active) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
- pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
- Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
- Port[Para.Para32[0]]->PortNumber;
- Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
- Port[Para.Para32[1]]->PortNumber;
- SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
- if (pAC->Rlmt.Port[Active].LinkDown) {
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
- }
- else {
- SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
- }
- Para.Para32[1] = NetIdx;
- Para.Para32[0] =
- pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
- Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
- Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
- if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
- (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
- SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
- &SkRlmtMcAddr)) != NULL) {
- /*
- * Send announce packet to RLMT multicast address to force
- * switches to learn the new location of the logical
- * MAC address.
- */
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
- } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
- } /* Para.Para32[1] != Active */
- } /* PortFound */
- else {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
- }
- } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
- return;
-} /* SkRlmtCheckSwitch */
-
-
-/******************************************************************************
- *
- * SkRlmtCheckSeg - Report if segmentation is detected
- *
- * Description:
- * This routine checks if the ports see different root bridges and reports
- * segmentation in such a case.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing.
- */
-RLMT_STATIC void SkRlmtCheckSeg(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 NetIdx) /* Net number */
-{
- SK_EVPARA Para;
- SK_RLMT_NET *pNet;
- SK_U32 i, j;
- SK_BOOL Equal;
-
- pNet = &pAC->Rlmt.Net[NetIdx];
- pNet->RootIdSet = SK_FALSE;
- Equal = SK_TRUE;
-
- for (i = 0; i < pNet->NumPorts; i++) {
- if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
- continue;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
- ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
- pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
- pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
- pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
- pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
-
- if (!pNet->RootIdSet) {
- pNet->Root = pNet->Port[i]->Root;
- pNet->RootIdSet = SK_TRUE;
- continue;
- }
-
- for (j = 0; j < 8; j ++) {
- Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
- if (!Equal) {
- break;
- }
- }
-
- if (!Equal) {
- SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
- Para.Para32[0] = NetIdx;
- Para.Para32[1] = (SK_U32)-1;
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
-
- pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
-
- /* 2000-03-06 RA: New. */
- Para.Para32[0] = NetIdx;
- Para.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
- SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
- break;
- }
- } /* for (i = 0; i < pNet->NumPorts; i++) */
-
- /* 2000-03-06 RA: Moved here. */
- /* Segmentation check not running anymore. */
- pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
-
-} /* SkRlmtCheckSeg */
-
-
-/******************************************************************************
- *
- * SkRlmtPortStart - initialize port variables and start port
- *
- * Description:
- * This routine initializes a port's variables and issues a PORT_START
- * to the HWAC module. This handles retries if the start fails or the
- * link eventually goes down.
- *
- * Context:
- * runtime, pageable?
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtPortStart(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 PortNumber) /* Port number */
-{
- SK_EVPARA Para;
-
- pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
- pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
- pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
- pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
- pAC->Rlmt.Port[PortNumber].CheckingState = 0;
- pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
- Para.Para32[0] = PortNumber;
- Para.Para32[1] = (SK_U32)-1;
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
-} /* SkRlmtPortStart */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtPortStartTim - PORT_START_TIM
- *
- * Description:
- * This routine handles PORT_START_TIM events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtPortStartTim(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
-{
- SK_U32 i;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
- return;
- }
-
- /*
- * Used to start non-preferred ports if the preferred one
- * does not come up.
- * This timeout needs only be set when starting the first
- * (preferred) port.
- */
- if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
- /* PORT_START failed. */
- for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
- if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
- SkRlmtPortStart(pAC, IoC,
- pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
- }
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
-} /* SkRlmtEvtPortStartTim */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtLinkUp - LINK_UP
- *
- * Description:
- * This routine handles LLINK_UP events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtLinkUp(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
-{
- SK_U32 i;
- SK_RLMT_PORT *pRPort;
- SK_EVPARA Para2;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
-
- pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
- if (!pRPort->PortStarted) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_LINK_UP Event EMPTY.\n"))
- return;
- }
-
- if (!pRPort->LinkDown) {
- /* RA;:;: Any better solution? */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_LINK_UP Event EMPTY.\n"))
- return;
- }
-
- SkTimerStop(pAC, IoC, &pRPort->UpTimer);
- SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
- SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
- /* Do something if timer already fired? */
-
- pRPort->LinkDown = SK_FALSE;
- pRPort->PortState = SK_RLMT_PS_GOING_UP;
- pRPort->GuTimeStamp = SkOsGetTime(pAC);
- pRPort->BcTimeStamp = 0;
- pRPort->Net->LinksUp++;
- if (pRPort->Net->LinksUp == 1) {
- SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
- }
- else {
- SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
- }
-
- for (i = 0; i < pRPort->Net->NumPorts; i++) {
- if (!pRPort->Net->Port[i]->PortStarted) {
- SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
- }
- }
-
- SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
-
- if (pRPort->Net->LinksUp >= 2) {
- if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
- /* Build the check chain. */
- SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
- }
- }
-
- /* If the first link comes up, start the periodical RLMT timeout. */
- if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
- (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
- Para2.Para32[0] = pRPort->Net->NetNumber;
- Para2.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
- pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
- }
-
- Para2 = Para;
- Para2.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
- SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
-
- /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
- if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
- (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
- (Para2.pParaPtr =
- SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
- &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
- ) != NULL) {
- /* Send "new" packet to RLMT multicast address. */
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
- }
-
- if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
- if ((Para2.pParaPtr =
- SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
- pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
- pRPort->Net->CheckingState |=
- SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
-
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
-
- Para.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
- SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_LINK_UP Event END.\n"))
-} /* SkRlmtEvtLinkUp */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtPortUpTim - PORT_UP_TIM
- *
- * Description:
- * This routine handles PORT_UP_TIM events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtPortUpTim(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
-{
- SK_RLMT_PORT *pRPort;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
- return;
- }
-
- pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
- if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
- return;
- }
-
- pRPort->PortDown = SK_FALSE;
- pRPort->PortState = SK_RLMT_PS_UP;
- pRPort->Net->PortsUp++;
- if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
- if (pAC->Rlmt.NumNets <= 1) {
- SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
- }
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTUP_TIM Event END.\n"))
-} /* SkRlmtEvtPortUpTim */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtPortDownTim - PORT_DOWN_*
- *
- * Description:
- * This routine handles PORT_DOWN_* events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtPortDownX(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Event, /* Event code */
-SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
-{
- SK_RLMT_PORT *pRPort;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
- Para.Para32[0], Event))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
- return;
- }
-
- pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
- if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
- !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
- return;
- }
-
- /* Stop port's timers. */
- SkTimerStop(pAC, IoC, &pRPort->UpTimer);
- SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
- SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
-
- if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
- pRPort->PortState = SK_RLMT_PS_DOWN;
- }
-
- if (!pRPort->PortDown) {
- pRPort->Net->PortsUp--;
- pRPort->PortDown = SK_TRUE;
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
- }
-
- pRPort->PacketsPerTimeSlot = 0;
- /* pRPort->DataPacketsPerTimeSlot = 0; */
- pRPort->BpduPacketsPerTimeSlot = 0;
- pRPort->BcTimeStamp = 0;
-
- /*
- * RA;:;: To be checked:
- * - actions at RLMT_STOP: We should not switch anymore.
- */
- if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
- if (Para.Para32[0] ==
- pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
- /* Active Port went down. */
- SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
-} /* SkRlmtEvtPortDownX */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtLinkDown - LINK_DOWN
- *
- * Description:
- * This routine handles LINK_DOWN events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtLinkDown(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
-{
- SK_RLMT_PORT *pRPort;
-
- pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
-
- if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
- pRPort->Net->LinksUp--;
- pRPort->LinkDown = SK_TRUE;
- pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
- SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
-
- if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
- /* Build the check chain. */
- SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
- }
-
- /* Ensure that port is marked down. */
- Para.Para32[1] = -1;
- (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_LINK_DOWN Event END.\n"))
-} /* SkRlmtEvtLinkDown */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtPortAddr - PORT_ADDR
- *
- * Description:
- * This routine handles PORT_ADDR events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtPortAddr(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
-{
- SK_U32 i, j;
- SK_RLMT_PORT *pRPort;
- SK_MAC_ADDR *pOldMacAddr;
- SK_MAC_ADDR *pNewMacAddr;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
- return;
- }
-
- /* Port's physical MAC address changed. */
- pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
- pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
-
- /*
- * NOTE: This is not scalable for solutions where ports are
- * checked remotely. There, we need to send an RLMT
- * address change packet - and how do we ensure delivery?
- */
- for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
- pRPort = &pAC->Rlmt.Port[i];
- for (j = 0; j < pRPort->PortsChecked; j++) {
- if (SK_ADDR_EQUAL(
- pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
- pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
- }
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PORT_ADDR Event END.\n"))
-} /* SkRlmtEvtPortAddr */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtStart - START
- *
- * Description:
- * This routine handles START events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtStart(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
-{
- SK_EVPARA Para2;
- SK_U32 PortIdx;
- SK_U32 PortNumber;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_START Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad NetNumber %d.\n", Para.Para32[0]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_START Event EMPTY.\n"))
- return;
- }
-
- if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_START Event EMPTY.\n"))
- return;
- }
-
- if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("All nets should have been started.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_START Event EMPTY.\n"))
- return;
- }
-
- if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
- pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
-
- /* Change PrefPort to internal default. */
- Para2.Para32[0] = 0xFFFFFFFF;
- Para2.Para32[1] = Para.Para32[0];
- (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
- }
-
- PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
- PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
-
- pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
- pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
- pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
- pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
-
- /* Start preferred port. */
- SkRlmtPortStart(pAC, IoC, PortNumber);
-
- /* Start Timer (for first port only). */
- Para2.Para32[0] = PortNumber;
- Para2.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
- SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
-
- pAC->Rlmt.NetsStarted++;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_START Event END.\n"))
-} /* SkRlmtEvtStart */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtStop - STOP
- *
- * Description:
- * This routine handles STOP events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtStop(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
-{
- SK_EVPARA Para2;
- SK_U32 PortNumber;
- SK_U32 i;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STOP Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad NetNumber %d.\n", Para.Para32[0]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STOP Event EMPTY.\n"))
- return;
- }
-
- if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STOP Event EMPTY.\n"))
- return;
- }
-
- if (pAC->Rlmt.NetsStarted == 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("All nets are stopped.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STOP Event EMPTY.\n"))
- return;
- }
-
- /* Stop RLMT timers. */
- SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
- SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
-
- /* Stop net. */
- pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
- pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
- Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
- Para2.Para32[1] = Para.Para32[0]; /* Net# */
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
-
- /* Stop ports. */
- for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
- PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
- if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
- SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
- SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
- SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
-
- pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
- pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
- pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
- Para2.Para32[0] = PortNumber;
- Para2.Para32[1] = (SK_U32)-1;
- SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
- }
- }
-
- pAC->Rlmt.NetsStarted--;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STOP Event END.\n"))
-} /* SkRlmtEvtStop */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtTim - TIM
- *
- * Description:
- * This routine handles TIM events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtTim(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
-{
- SK_RLMT_PORT *pRPort;
- SK_U32 Timeout;
- SK_U32 NewTimeout;
- SK_U32 PortNumber;
- SK_U32 i;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_TIM Event BEGIN.\n"))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_TIM Event EMPTY.\n"))
- return;
- }
-
- if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
- pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
- /* Mode changed or all links down: No more link checking. */
- return;
- }
-
-#if 0
- pAC->Rlmt.SwitchCheckCounter--;
- if (pAC->Rlmt.SwitchCheckCounter == 0) {
- pAC->Rlmt.SwitchCheckCounter;
- }
-#endif /* 0 */
-
- NewTimeout = SK_RLMT_DEF_TO_VAL;
- for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
- PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
- pRPort = &pAC->Rlmt.Port[PortNumber];
- if (!pRPort->LinkDown) {
- Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
- if (Timeout < NewTimeout) {
- NewTimeout = Timeout;
- }
-
- /*
- * These counters should be set to 0 for all ports before the
- * first frame is sent in the next loop.
- */
- pRPort->PacketsPerTimeSlot = 0;
- /* pRPort->DataPacketsPerTimeSlot = 0; */
- pRPort->BpduPacketsPerTimeSlot = 0;
- }
- }
- pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
-
- if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
- /*
- * If checking remote ports, also send packets if
- * (LinksUp == 1) &&
- * this port checks at least one (remote) port.
- */
-
- /*
- * Must be new loop, as SkRlmtCheckPort can request to
- * check segmentation when e.g. checking the last port.
- */
- for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
- if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
- SkRlmtSend(pAC, IoC,
- pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
- }
- }
- }
-
- SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
- pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
- Para);
-
- if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
- (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
- (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
- SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
- SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
- pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
- pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
- SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_TIM Event END.\n"))
-} /* SkRlmtEvtTim */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtSegTim - SEG_TIM
- *
- * Description:
- * This routine handles SEG_TIM events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtSegTim(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
-{
-#ifdef xDEBUG
- int j;
-#endif /* DEBUG */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
- return;
- }
-
-#ifdef xDEBUG
- for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
- SK_ADDR_PORT *pAPort;
- SK_U32 k;
- SK_U16 *InAddr;
- SK_U8 InAddr8[6];
-
- InAddr = (SK_U16 *)&InAddr8[0];
- pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
- for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
- /* Get exact match address k from port j. */
- XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
- XM_EXM(k), InAddr);
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n",
- k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
- InAddr8[0], InAddr8[1], InAddr8[2],
- InAddr8[3], InAddr8[4], InAddr8[5],
- pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
- pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
- pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
- }
- }
-#endif /* xDEBUG */
-
- SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SEG_TIM Event END.\n"))
-} /* SkRlmtEvtSegTim */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtPacketRx - PACKET_RECEIVED
- *
- * Description:
- * This routine handles PACKET_RECEIVED events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtPacketRx(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_MBUF *pMb */
-{
- SK_MBUF *pMb;
- SK_MBUF *pNextMb;
- SK_U32 NetNumber;
-
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
-
- /* Should we ignore frames during port switching? */
-
-#ifdef DEBUG
- pMb = Para.pParaPtr;
- if (pMb == NULL) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
- }
- else if (pMb->pNext != NULL) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("More than one mbuf or pMb->pNext not set.\n"))
- }
-#endif /* DEBUG */
-
- for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
- pNextMb = pMb->pNext;
- pMb->pNext = NULL;
-
- NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
- if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
- SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
- }
- else {
- SkRlmtPacketReceive(pAC, IoC, pMb);
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
-} /* SkRlmtEvtPacketRx */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtStatsClear - STATS_CLEAR
- *
- * Description:
- * This routine handles STATS_CLEAR events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtStatsClear(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
-{
- SK_U32 i;
- SK_RLMT_PORT *pRPort;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad NetNumber %d.\n", Para.Para32[0]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
- return;
- }
-
- /* Clear statistics for logical and physical ports. */
- for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
- pRPort =
- &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
- pRPort->TxHelloCts = 0;
- pRPort->RxHelloCts = 0;
- pRPort->TxSpHelloReqCts = 0;
- pRPort->RxSpHelloCts = 0;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_CLEAR Event END.\n"))
-} /* SkRlmtEvtStatsClear */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtStatsUpdate - STATS_UPDATE
- *
- * Description:
- * This routine handles STATS_UPDATE events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtStatsUpdate(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad NetNumber %d.\n", Para.Para32[0]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
- return;
- }
-
- /* Update statistics - currently always up-to-date. */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_STATS_UPDATE Event END.\n"))
-} /* SkRlmtEvtStatsUpdate */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtPrefportChange - PREFPORT_CHANGE
- *
- * Description:
- * This routine handles PREFPORT_CHANGE events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtPrefportChange(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */
-{
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
-
- if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad NetNumber %d.\n", Para.Para32[1]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
- return;
- }
-
- /* 0xFFFFFFFF == auto-mode. */
- if (Para.Para32[0] == 0xFFFFFFFF) {
- pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
- }
- else {
- if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
- return;
- }
-
- pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
- }
-
- pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
-
- if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
- SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
-} /* SkRlmtEvtPrefportChange */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtSetNets - SET_NETS
- *
- * Description:
- * This routine handles SET_NETS events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtSetNets(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NumNets; SK_U32 -1 */
-{
- int i;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event BEGIN.\n"))
-
- if (Para.Para32[1] != (SK_U32)-1) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad Parameter.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
- Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad number of nets: %d.\n", Para.Para32[0]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event EMPTY.\n"))
- return;
- }
-
- /* Entering and leaving dual mode only allowed while nets are stopped. */
- if (pAC->Rlmt.NetsStarted > 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Changing dual mode only allowed while all nets are stopped.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event EMPTY.\n"))
- return;
- }
-
- if (Para.Para32[0] == 1) {
- if (pAC->Rlmt.NumNets > 1) {
- /* Clear logical MAC addr from second net's active port. */
- (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
- Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
- pAC->Rlmt.Net[1].NumPorts = 0;
- }
-
- pAC->Rlmt.NumNets = Para.Para32[0];
- for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
- pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
- pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
- pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
- pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
- /* Just assuming. */
- pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
- pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
- pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
- pAC->Rlmt.Net[i].NetNumber = i;
- }
-
- pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
- pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
-
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("RLMT: Changed to one net with two ports.\n"))
- }
- else if (Para.Para32[0] == 2) {
- pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
- pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
- pAC->Rlmt.Net[0].NumPorts =
- pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
-
- pAC->Rlmt.NumNets = Para.Para32[0];
- for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
- pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
- pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
- pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
- pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
- /* Just assuming. */
- pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
- pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
- pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
-
- pAC->Rlmt.Net[i].NetNumber = i;
- }
-
- /* Set logical MAC addr on second net's active port. */
- (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
- Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
-
- SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("RLMT: Changed to two nets with one port each.\n"))
- }
- else {
- /* Not implemented for more than two nets. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SetNets not implemented for more than two nets.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event EMPTY.\n"))
- return;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_SET_NETS Event END.\n"))
-} /* SkRlmtSetNets */
-
-
-/******************************************************************************
- *
- * SkRlmtEvtModeChange - MODE_CHANGE
- *
- * Description:
- * This routine handles MODE_CHANGE events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * Nothing
- */
-RLMT_STATIC void SkRlmtEvtModeChange(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_EVPARA Para) /* SK_U32 NewMode; SK_U32 NetNumber */
-{
- SK_EVPARA Para2;
- SK_U32 i;
- SK_U32 PrevRlmtMode;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
-
- if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Bad NetNumber %d.\n", Para.Para32[1]))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
- return;
- }
-
- Para.Para32[0] |= SK_RLMT_CHECK_LINK;
-
- if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
- Para.Para32[0] != SK_RLMT_MODE_CLS) {
- pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Forced RLMT mode to CLS on single port net.\n"))
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
- return;
- }
-
- /* Update RLMT mode. */
- PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
- pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
-
- if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
- (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
- /* SK_RLMT_CHECK_LOC_LINK bit changed. */
- if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
- pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
- pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
- /* 20001207 RA: Was "PortsUp == 1". */
- Para2.Para32[0] = Para.Para32[1];
- Para2.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
- pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
- SKGE_RLMT, SK_RLMT_TIM, Para2);
- }
- }
-
- if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
- (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
- /* SK_RLMT_CHECK_SEG bit changed. */
- for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
- (void)SkAddrMcClear(pAC, IoC,
- pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
- SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
-
- /* Add RLMT MC address. */
- (void)SkAddrMcAdd(pAC, IoC,
- pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
- &SkRlmtMcAddr, SK_ADDR_PERMANENT);
-
- if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
- SK_RLMT_CHECK_SEG) != 0) {
- /* Add BPDU MC address. */
- (void)SkAddrMcAdd(pAC, IoC,
- pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
- &BridgeMcAddr, SK_ADDR_PERMANENT);
-
- if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
- if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
- (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
- pAC, IoC, i)) != NULL) {
- pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
- SK_FALSE;
- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
- }
- }
- }
- (void)SkAddrMcUpdate(pAC, IoC,
- pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
- } /* for ... */
-
- if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
- Para2.Para32[0] = Para.Para32[1];
- Para2.Para32[1] = (SK_U32)-1;
- SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
- SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
- }
- } /* SK_RLMT_CHECK_SEG bit changed. */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("SK_RLMT_MODE_CHANGE Event END.\n"))
-} /* SkRlmtEvtModeChange */
-
-
-/******************************************************************************
- *
- * SkRlmtEvent - a PORT- or an RLMT-specific event happened
- *
- * Description:
- * This routine calls subroutines to handle PORT- and RLMT-specific events.
- *
- * Context:
- * runtime, pageable?
- * may be called after SK_INIT_IO
- *
- * Returns:
- * 0
- */
-int SkRlmtEvent(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-SK_U32 Event, /* Event code */
-SK_EVPARA Para) /* Event-specific parameter */
-{
- switch (Event) {
-
- /* ----- PORT events ----- */
-
- case SK_RLMT_PORTSTART_TIM: /* From RLMT via TIME. */
- SkRlmtEvtPortStartTim(pAC, IoC, Para);
- break;
- case SK_RLMT_LINK_UP: /* From SIRQ. */
- SkRlmtEvtLinkUp(pAC, IoC, Para);
- break;
- case SK_RLMT_PORTUP_TIM: /* From RLMT via TIME. */
- SkRlmtEvtPortUpTim(pAC, IoC, Para);
- break;
- case SK_RLMT_PORTDOWN: /* From RLMT. */
- case SK_RLMT_PORTDOWN_RX_TIM: /* From RLMT via TIME. */
- case SK_RLMT_PORTDOWN_TX_TIM: /* From RLMT via TIME. */
- SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
- break;
- case SK_RLMT_LINK_DOWN: /* From SIRQ. */
- SkRlmtEvtLinkDown(pAC, IoC, Para);
- break;
- case SK_RLMT_PORT_ADDR: /* From ADDR. */
- SkRlmtEvtPortAddr(pAC, IoC, Para);
- break;
-
- /* ----- RLMT events ----- */
-
- case SK_RLMT_START: /* From DRV. */
- SkRlmtEvtStart(pAC, IoC, Para);
- break;
- case SK_RLMT_STOP: /* From DRV. */
- SkRlmtEvtStop(pAC, IoC, Para);
- break;
- case SK_RLMT_TIM: /* From RLMT via TIME. */
- SkRlmtEvtTim(pAC, IoC, Para);
- break;
- case SK_RLMT_SEG_TIM:
- SkRlmtEvtSegTim(pAC, IoC, Para);
- break;
- case SK_RLMT_PACKET_RECEIVED: /* From DRV. */
- SkRlmtEvtPacketRx(pAC, IoC, Para);
- break;
- case SK_RLMT_STATS_CLEAR: /* From PNMI. */
- SkRlmtEvtStatsClear(pAC, IoC, Para);
- break;
- case SK_RLMT_STATS_UPDATE: /* From PNMI. */
- SkRlmtEvtStatsUpdate(pAC, IoC, Para);
- break;
- case SK_RLMT_PREFPORT_CHANGE: /* From PNMI. */
- SkRlmtEvtPrefportChange(pAC, IoC, Para);
- break;
- case SK_RLMT_MODE_CHANGE: /* From PNMI. */
- SkRlmtEvtModeChange(pAC, IoC, Para);
- break;
- case SK_RLMT_SET_NETS: /* From DRV. */
- SkRlmtEvtSetNets(pAC, IoC, Para);
- break;
-
- /* ----- Unknown events ----- */
-
- default: /* Create error log entry. */
- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
- ("Unknown RLMT Event %d.\n", Event))
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
- break;
- } /* switch() */
-
- return (0);
-} /* SkRlmtEvent */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
deleted file mode 100644
index 4e462955ecd8..000000000000
--- a/drivers/net/sk98lin/sktimer.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/******************************************************************************
- *
- * Name: sktimer.c
- * Project: Gigabit Ethernet Adapters, Event Scheduler Module
- * Version: $Revision: 1.14 $
- * Date: $Date: 2003/09/16 13:46:51 $
- * Purpose: High level timer functions.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect GmbH.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-/*
- * Event queue and dispatcher
- */
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#include "h/skdrv1st.h" /* Driver Specific Definitions */
-#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
-
-#ifdef __C2MAN__
-/*
- Event queue management.
-
- General Description:
-
- */
-intro()
-{}
-#endif
-
-
-/* Forward declaration */
-static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
-
-
-/*
- * Inits the software timer
- *
- * needs to be called during Init level 1.
- */
-void SkTimerInit(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc, /* IoContext */
-int Level) /* Init Level */
-{
- switch (Level) {
- case SK_INIT_DATA:
- pAC->Tim.StQueue = NULL;
- break;
- case SK_INIT_IO:
- SkHwtInit(pAC, Ioc);
- SkTimerDone(pAC, Ioc);
- break;
- default:
- break;
- }
-}
-
-/*
- * Stops a high level timer
- * - If a timer is not in the queue the function returns normally, too.
- */
-void SkTimerStop(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc, /* IoContext */
-SK_TIMER *pTimer) /* Timer Pointer to be started */
-{
- SK_TIMER **ppTimPrev;
- SK_TIMER *pTm;
-
- /*
- * remove timer from queue
- */
- pTimer->TmActive = SK_FALSE;
-
- if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
- SkHwtStop(pAC, Ioc);
- }
-
- for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
- ppTimPrev = &pTm->TmNext ) {
-
- if (pTm == pTimer) {
- /*
- * Timer found in queue
- * - dequeue it and
- * - correct delta of the next timer
- */
- *ppTimPrev = pTm->TmNext;
-
- if (pTm->TmNext) {
- /* correct delta of next timer in queue */
- pTm->TmNext->TmDelta += pTm->TmDelta;
- }
- return;
- }
- }
-}
-
-/*
- * Start a high level software timer
- */
-void SkTimerStart(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc, /* IoContext */
-SK_TIMER *pTimer, /* Timer Pointer to be started */
-SK_U32 Time, /* Time value */
-SK_U32 Class, /* Event Class for this timer */
-SK_U32 Event, /* Event Value for this timer */
-SK_EVPARA Para) /* Event Parameter for this timer */
-{
- SK_TIMER **ppTimPrev;
- SK_TIMER *pTm;
- SK_U32 Delta;
-
- Time /= 16; /* input is uS, clock ticks are 16uS */
-
- if (!Time)
- Time = 1;
-
- SkTimerStop(pAC, Ioc, pTimer);
-
- pTimer->TmClass = Class;
- pTimer->TmEvent = Event;
- pTimer->TmPara = Para;
- pTimer->TmActive = SK_TRUE;
-
- if (!pAC->Tim.StQueue) {
- /* First Timer to be started */
- pAC->Tim.StQueue = pTimer;
- pTimer->TmNext = NULL;
- pTimer->TmDelta = Time;
-
- SkHwtStart(pAC, Ioc, Time);
-
- return;
- }
-
- /*
- * timer correction
- */
- timer_done(pAC, Ioc, 0);
-
- /*
- * find position in queue
- */
- Delta = 0;
- for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
- ppTimPrev = &pTm->TmNext ) {
-
- if (Delta + pTm->TmDelta > Time) {
- /* Position found */
- /* Here the timer needs to be inserted. */
- break;
- }
- Delta += pTm->TmDelta;
- }
-
- /* insert in queue */
- *ppTimPrev = pTimer;
- pTimer->TmNext = pTm;
- pTimer->TmDelta = Time - Delta;
-
- if (pTm) {
- /* There is a next timer
- * -> correct its Delta value.
- */
- pTm->TmDelta -= pTimer->TmDelta;
- }
-
- /* restart with first */
- SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
-}
-
-
-void SkTimerDone(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc) /* IoContext */
-{
- timer_done(pAC, Ioc, 1);
-}
-
-
-static void timer_done(
-SK_AC *pAC, /* Adapters context */
-SK_IOC Ioc, /* IoContext */
-int Restart) /* Do we need to restart the Hardware timer ? */
-{
- SK_U32 Delta;
- SK_TIMER *pTm;
- SK_TIMER *pTComp; /* Timer completed now now */
- SK_TIMER **ppLast; /* Next field of Last timer to be deq */
- int Done = 0;
-
- Delta = SkHwtRead(pAC, Ioc);
-
- ppLast = &pAC->Tim.StQueue;
- pTm = pAC->Tim.StQueue;
- while (pTm && !Done) {
- if (Delta >= pTm->TmDelta) {
- /* Timer ran out */
- pTm->TmActive = SK_FALSE;
- Delta -= pTm->TmDelta;
- ppLast = &pTm->TmNext;
- pTm = pTm->TmNext;
- }
- else {
- /* We found the first timer that did not run out */
- pTm->TmDelta -= Delta;
- Delta = 0;
- Done = 1;
- }
- }
- *ppLast = NULL;
- /*
- * pTm points to the first Timer that did not run out.
- * StQueue points to the first Timer that run out.
- */
-
- for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
- SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
- }
-
- /* Set head of timer queue to the first timer that did not run out */
- pAC->Tim.StQueue = pTm;
-
- if (Restart && pAC->Tim.StQueue) {
- /* Restart HW timer */
- SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
- }
-}
-
-/* End of file */
diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
deleted file mode 100644
index 1e662aaebf84..000000000000
--- a/drivers/net/sk98lin/skvpd.c
+++ /dev/null
@@ -1,1091 +0,0 @@
-/******************************************************************************
- *
- * Name: skvpd.c
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.37 $
- * Date: $Date: 2003/01/13 10:42:45 $
- * Purpose: Shared software to read and write VPD data
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2003 SysKonnect GmbH.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
- Please refer skvpd.txt for information how to include this module
- */
-static const char SysKonnectFileId[] =
- "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
-
-#include "h/skdrv1st.h"
-#include "h/sktypes.h"
-#include "h/skdebug.h"
-#include "h/skdrv2nd.h"
-
-/*
- * Static functions
- */
-#ifndef SK_KR_PROTO
-static SK_VPD_PARA *vpd_find_para(
- SK_AC *pAC,
- const char *key,
- SK_VPD_PARA *p);
-#else /* SK_KR_PROTO */
-static SK_VPD_PARA *vpd_find_para();
-#endif /* SK_KR_PROTO */
-
-/*
- * waits for a completion of a VPD transfer
- * The VPD transfer must complete within SK_TICKS_PER_SEC/16
- *
- * returns 0: success, transfer completes
- * error exit(9) with a error message
- */
-static int VpdWait(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC, /* IO Context */
-int event) /* event to wait for (VPD_READ / VPD_write) completion*/
-{
- SK_U64 start_time;
- SK_U16 state;
-
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD wait for %s\n", event?"Write":"Read"));
- start_time = SkOsGetTime(pAC);
- do {
- if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
-
- /* Bug fix AF: Thu Mar 28 2002
- * Do not call: VPD_STOP(pAC, IoC);
- * A pending VPD read cycle can not be aborted by writing
- * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
- * Although the write threshold in the OUR-register protects
- * VPD read only space from being overwritten this does not
- * protect a VPD read from being `converted` into a VPD write
- * operation (on the fly). As a consequence the VPD_STOP would
- * delete VPD read only data. In case of any problems with the
- * I2C bus we exit the loop here. The I2C read operation can
- * not be aborted except by a reset (->LR).
- */
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
- ("ERROR:VPD wait timeout\n"));
- return(1);
- }
-
- VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("state = %x, event %x\n",state,event));
- } while((int)(state & PCI_VPD_FLAG) == event);
-
- return(0);
-}
-
-#ifdef SKDIAG
-
-/*
- * Read the dword at address 'addr' from the VPD EEPROM.
- *
- * Needed Time: MIN 1,3 ms MAX 2,6 ms
- *
- * Note: The DWord is returned in the endianess of the machine the routine
- * is running on.
- *
- * Returns the data read.
- */
-SK_U32 VpdReadDWord(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC, /* IO Context */
-int addr) /* VPD address */
-{
- SK_U32 Rtv;
-
- /* start VPD read */
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD read dword at 0x%x\n",addr));
- addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */
-
- VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
-
- /* ignore return code here */
- (void)VpdWait(pAC, IoC, VPD_READ);
-
- /* Don't swap here, it's a data stream of bytes */
- Rtv = 0;
-
- VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD read dword data = 0x%x\n",Rtv));
- return(Rtv);
-}
-
-#endif /* SKDIAG */
-
-/*
- * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
- * or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdWriteStream(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC, /* IO Context */
-char *buf, /* data buffer */
-int Addr, /* VPD start address */
-int Len) /* number of bytes to read / to write */
-{
- int i;
- int j;
- SK_U16 AdrReg;
- int Rtv;
- SK_U8 * pComp; /* Compare pointer */
- SK_U8 Data; /* Input Data for Compare */
-
- /* Init Compare Pointer */
- pComp = (SK_U8 *) buf;
-
- for (i = 0; i < Len; i++, buf++) {
- if ((i%sizeof(SK_U32)) == 0) {
- /*
- * At the begin of each cycle read the Data Reg
- * So it is initialized even if only a few bytes
- * are written.
- */
- AdrReg = (SK_U16) Addr;
- AdrReg &= ~VPD_WRITE; /* READ operation */
-
- VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
- /* Wait for termination */
- Rtv = VpdWait(pAC, IoC, VPD_READ);
- if (Rtv != 0) {
- return(i);
- }
- }
-
- /* Write current Byte */
- VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
- *(SK_U8*)buf);
-
- if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
- /* New Address needs to be written to VPD_ADDR reg */
- AdrReg = (SK_U16) Addr;
- Addr += sizeof(SK_U32);
- AdrReg |= VPD_WRITE; /* WRITE operation */
-
- VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
- /* Wait for termination */
- Rtv = VpdWait(pAC, IoC, VPD_WRITE);
- if (Rtv != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("Write Timed Out\n"));
- return(i - (i%sizeof(SK_U32)));
- }
-
- /*
- * Now re-read to verify
- */
- AdrReg &= ~VPD_WRITE; /* READ operation */
-
- VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
- /* Wait for termination */
- Rtv = VpdWait(pAC, IoC, VPD_READ);
- if (Rtv != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("Verify Timed Out\n"));
- return(i - (i%sizeof(SK_U32)));
- }
-
- for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
-
- VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
-
- if (Data != *pComp) {
- /* Verify Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("WriteStream Verify Error\n"));
- return(i - (i%sizeof(SK_U32)) + j);
- }
- }
- }
- }
-
- return(Len);
-}
-
-
-/*
- * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
- * or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdReadStream(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC, /* IO Context */
-char *buf, /* data buffer */
-int Addr, /* VPD start address */
-int Len) /* number of bytes to read / to write */
-{
- int i;
- SK_U16 AdrReg;
- int Rtv;
-
- for (i = 0; i < Len; i++, buf++) {
- if ((i%sizeof(SK_U32)) == 0) {
- /* New Address needs to be written to VPD_ADDR reg */
- AdrReg = (SK_U16) Addr;
- Addr += sizeof(SK_U32);
- AdrReg &= ~VPD_WRITE; /* READ operation */
-
- VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
-
- /* Wait for termination */
- Rtv = VpdWait(pAC, IoC, VPD_READ);
- if (Rtv != 0) {
- return(i);
- }
- }
- VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
- (SK_U8 *)buf);
- }
-
- return(Len);
-}
-
-/*
- * Read ore writes 'len' bytes of VPD data, starting at 'addr' from
- * or to the I2C EEPROM.
- *
- * Returns number of bytes read / written.
- */
-static int VpdTransferBlock(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC, /* IO Context */
-char *buf, /* data buffer */
-int addr, /* VPD start address */
-int len, /* number of bytes to read / to write */
-int dir) /* transfer direction may be VPD_READ or VPD_WRITE */
-{
- int Rtv; /* Return value */
- int vpd_rom_size;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD %s block, addr = 0x%x, len = %d\n",
- dir ? "write" : "read", addr, len));
-
- if (len == 0)
- return(0);
-
- vpd_rom_size = pAC->vpd.rom_size;
-
- if (addr > vpd_rom_size - 4) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Address error: 0x%x, exp. < 0x%x\n",
- addr, vpd_rom_size - 4));
- return(0);
- }
-
- if (addr + len > vpd_rom_size) {
- len = vpd_rom_size - addr;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("Warning: len was cut to %d\n", len));
- }
-
- if (dir == VPD_READ) {
- Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
- }
- else {
- Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
- }
-
- return(Rtv);
-}
-
-#ifdef SKDIAG
-
-/*
- * Read 'len' bytes of VPD data, starting at 'addr'.
- *
- * Returns number of bytes read.
- */
-int VpdReadBlock(
-SK_AC *pAC, /* pAC pointer */
-SK_IOC IoC, /* IO Context */
-char *buf, /* buffer were the data should be stored */
-int addr, /* start reading at the VPD address */
-int len) /* number of bytes to read */
-{
- return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
-}
-
-/*
- * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
- *
- * Returns number of bytes writes.
- */
-int VpdWriteBlock(
-SK_AC *pAC, /* pAC pointer */
-SK_IOC IoC, /* IO Context */
-char *buf, /* buffer, holds the data to write */
-int addr, /* start writing at the VPD address */
-int len) /* number of bytes to write */
-{
- return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
-}
-#endif /* SKDIAG */
-
-/*
- * (re)initialize the VPD buffer
- *
- * Reads the VPD data from the EEPROM into the VPD buffer.
- * Get the remaining read only and read / write space.
- *
- * return 0: success
- * 1: fatal VPD error
- */
-static int VpdInit(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC) /* IO Context */
-{
- SK_VPD_PARA *r, rp; /* RW or RV */
- int i;
- unsigned char x;
- int vpd_size;
- SK_U16 dev_id;
- SK_U32 our_reg2;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
-
- VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
-
- VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
-
- pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
-
- /*
- * this function might get used before the hardware is initialized
- * therefore we cannot always trust in GIChipId
- */
- if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
- dev_id != VPD_DEV_ID_GENESIS) ||
- ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
- !pAC->GIni.GIGenesis)) {
-
- /* for Yukon the VPD size is always 256 */
- vpd_size = VPD_SIZE_YUKON;
- }
- else {
- /* Genesis uses the maximum ROM size up to 512 for VPD */
- if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
- vpd_size = VPD_SIZE_GENESIS;
- }
- else {
- vpd_size = pAC->vpd.rom_size;
- }
- }
-
- /* read the VPD data into the VPD buffer */
- if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
- != vpd_size) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("Block Read Error\n"));
- return(1);
- }
-
- pAC->vpd.vpd_size = vpd_size;
-
- /* Asus K8V Se Deluxe bugfix. Correct VPD content */
- /* MBo April 2004 */
- if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
- ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
- ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
- printk("sk98lin: Asus mainboard with buggy VPD? "
- "Correcting data.\n");
- pAC->vpd.vpd_buf[0x40] = 0x38;
- }
-
-
- /* find the end tag of the RO area */
- if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: RV Tag not found\n"));
- return(1);
- }
-
- if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: Invalid VPD struct size\n"));
- return(1);
- }
- pAC->vpd.v.vpd_free_ro = r->p_len - 1;
-
- /* test the checksum */
- for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
- x += pAC->vpd.vpd_buf[i];
- }
-
- if (x != 0) {
- /* checksum error */
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("VPD Checksum Error\n"));
- return(1);
- }
-
- /* find and check the end tag of the RW area */
- if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: RV Tag not found\n"));
- return(1);
- }
-
- if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: Invalid VPD struct size\n"));
- return(1);
- }
- pAC->vpd.v.vpd_free_rw = r->p_len;
-
- /* everything seems to be ok */
- if (pAC->GIni.GIChipId != 0) {
- pAC->vpd.v.vpd_status |= VPD_VALID;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
- ("done. Free RO = %d, Free RW = %d\n",
- pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
-
- return(0);
-}
-
-/*
- * find the Keyword 'key' in the VPD buffer and fills the
- * parameter struct 'p' with it's values
- *
- * returns *p success
- * 0: parameter was not found or VPD encoding error
- */
-static SK_VPD_PARA *vpd_find_para(
-SK_AC *pAC, /* common data base */
-const char *key, /* keyword to find (e.g. "MN") */
-SK_VPD_PARA *p) /* parameter description struct */
-{
- char *v ; /* points to VPD buffer */
- int max; /* Maximum Number of Iterations */
-
- v = pAC->vpd.vpd_buf;
- max = 128;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD find para %s .. ",key));
-
- /* check mandatory resource type ID string (Product Name) */
- if (*v != (char)RES_ID) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Error: 0x%x missing\n", RES_ID));
- return NULL;
- }
-
- if (strcmp(key, VPD_NAME) == 0) {
- p->p_len = VPD_GET_RES_LEN(v);
- p->p_val = VPD_GET_VAL(v);
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("found, len = %d\n", p->p_len));
- return(p);
- }
-
- v += 3 + VPD_GET_RES_LEN(v) + 3;
- for (;; ) {
- if (SK_MEMCMP(key,v,2) == 0) {
- p->p_len = VPD_GET_VPD_LEN(v);
- p->p_val = VPD_GET_VAL(v);
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("found, len = %d\n",p->p_len));
- return(p);
- }
-
- /* exit when reaching the "RW" Tag or the maximum of itera. */
- max--;
- if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
- break;
- }
-
- if (SK_MEMCMP(VPD_RV,v,2) == 0) {
- v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
- }
- else {
- v += 3 + VPD_GET_VPD_LEN(v);
- }
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
- }
-
-#ifdef DEBUG
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
- if (max == 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Key/Len Encoding error\n"));
- }
-#endif /* DEBUG */
- return NULL;
-}
-
-/*
- * Move 'n' bytes. Begin with the last byte if 'n' is > 0,
- * Start with the last byte if n is < 0.
- *
- * returns nothing
- */
-static void vpd_move_para(
-char *start, /* start of memory block */
-char *end, /* end of memory block to move */
-int n) /* number of bytes the memory block has to be moved */
-{
- char *p;
- int i; /* number of byte copied */
-
- if (n == 0)
- return;
-
- i = (int) (end - start + 1);
- if (n < 0) {
- p = start + n;
- while (i != 0) {
- *p++ = *start++;
- i--;
- }
- }
- else {
- p = end + n;
- while (i != 0) {
- *p-- = *end--;
- i--;
- }
- }
-}
-
-/*
- * setup the VPD keyword 'key' at 'ip'.
- *
- * returns nothing
- */
-static void vpd_insert_key(
-const char *key, /* keyword to insert */
-const char *buf, /* buffer with the keyword value */
-int len, /* length of the value string */
-char *ip) /* inseration point */
-{
- SK_VPD_KEY *p;
-
- p = (SK_VPD_KEY *) ip;
- p->p_key[0] = key[0];
- p->p_key[1] = key[1];
- p->p_len = (unsigned char) len;
- SK_MEMCPY(&p->p_val,buf,len);
-}
-
-/*
- * Setup the VPD end tag "RV" / "RW".
- * Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
- *
- * returns 0: success
- * 1: encoding error
- */
-static int vpd_mod_endtag(
-SK_AC *pAC, /* common data base */
-char *etp) /* end pointer input position */
-{
- SK_VPD_KEY *p;
- unsigned char x;
- int i;
- int vpd_size;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
-
- vpd_size = pAC->vpd.vpd_size;
-
- p = (SK_VPD_KEY *) etp;
-
- if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
- /* something wrong here, encoding error */
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: invalid end tag\n"));
- return(1);
- }
- if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
- /* create "RW" tag */
- p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
- pAC->vpd.v.vpd_free_rw = (int) p->p_len;
- i = pAC->vpd.v.vpd_free_rw;
- etp += 3;
- }
- else {
- /* create "RV" tag */
- p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
- pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
-
- /* setup checksum */
- for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
- x += pAC->vpd.vpd_buf[i];
- }
- p->p_val = (char) 0 - x;
- i = pAC->vpd.v.vpd_free_ro;
- etp += 4;
- }
- while (i) {
- *etp++ = 0x00;
- i--;
- }
-
- return(0);
-}
-
-/*
- * Insert a VPD keyword into the VPD buffer.
- *
- * The keyword 'key' is inserted at the position 'ip' in the
- * VPD buffer.
- * The keywords behind the input position will
- * be moved. The VPD end tag "RV" or "RW" is generated again.
- *
- * returns 0: success
- * 2: value string was cut
- * 4: VPD full, keyword was not written
- * 6: fatal VPD error
- *
- */
-static int VpdSetupPara(
-SK_AC *pAC, /* common data base */
-const char *key, /* keyword to insert */
-const char *buf, /* buffer with the keyword value */
-int len, /* length of the keyword value */
-int type, /* VPD_RO_KEY or VPD_RW_KEY */
-int op) /* operation to do: ADD_KEY or OWR_KEY */
-{
- SK_VPD_PARA vp;
- char *etp; /* end tag position */
- int free; /* remaining space in selected area */
- char *ip; /* input position inside the VPD buffer */
- int rtv; /* return code */
- int head; /* additional haeder bytes to move */
- int found; /* additinoal bytes if the keyword was found */
- int vpd_size;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("VPD setup para key = %s, val = %s\n",key,buf));
-
- vpd_size = pAC->vpd.vpd_size;
-
- rtv = 0;
- ip = NULL;
- if (type == VPD_RW_KEY) {
- /* end tag is "RW" */
- free = pAC->vpd.v.vpd_free_rw;
- etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
- }
- else {
- /* end tag is "RV" */
- free = pAC->vpd.v.vpd_free_ro;
- etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
- }
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("Free RO = %d, Free RW = %d\n",
- pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
-
- head = 0;
- found = 0;
- if (op == OWR_KEY) {
- if (vpd_find_para(pAC, key, &vp)) {
- found = 3;
- ip = vp.p_val - 3;
- free += vp.p_len + 3;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("Overwrite Key\n"));
- }
- else {
- op = ADD_KEY;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
- ("Add Key\n"));
- }
- }
- if (op == ADD_KEY) {
- ip = etp;
- vp.p_len = 0;
- head = 3;
- }
-
- if (len + 3 > free) {
- if (free < 7) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD Buffer Overflow, keyword not written\n"));
- return(4);
- }
- /* cut it again */
- len = free - 3;
- rtv = 2;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD Buffer Full, Keyword was cut\n"));
- }
-
- vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
- vpd_insert_key(key, buf, len, ip);
- if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
- pAC->vpd.v.vpd_status &= ~VPD_VALID;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD Encoding Error\n"));
- return(6);
- }
-
- return(rtv);
-}
-
-
-/*
- * Read the contents of the VPD EEPROM and copy it to the
- * VPD buffer if not already done.
- *
- * return: A pointer to the vpd_status structure. The structure contains
- * this fields.
- */
-SK_VPD_STATUS *VpdStat(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC) /* IO Context */
-{
- if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
- (void)VpdInit(pAC, IoC);
- }
- return(&pAC->vpd.v);
-}
-
-
-/*
- * Read the contents of the VPD EEPROM and copy it to the VPD
- * buffer if not already done.
- * Scan the VPD buffer for VPD keywords and create the VPD
- * keyword list by copying the keywords to 'buf', all after
- * each other and terminated with a '\0'.
- *
- * Exceptions: o The Resource Type ID String (product name) is called "Name"
- * o The VPD end tags 'RV' and 'RW' are not listed
- *
- * The number of copied keywords is counted in 'elements'.
- *
- * returns 0: success
- * 2: buffer overfull, one or more keywords are missing
- * 6: fatal VPD error
- *
- * example values after returning:
- *
- * buf = "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
- * *len = 30
- * *elements = 9
- */
-int VpdKeys(
-SK_AC *pAC, /* common data base */
-SK_IOC IoC, /* IO Context */
-char *buf, /* buffer where to copy the keywords */
-int *len, /* buffer length */
-int *elements) /* number of keywords returned */
-{
- char *v;
- int n;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
- *elements = 0;
- if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
- if (VpdInit(pAC, IoC) != 0) {
- *len = 0;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD Init Error, terminated\n"));
- return(6);
- }
- }
-
- if ((signed)strlen(VPD_NAME) + 1 <= *len) {
- v = pAC->vpd.vpd_buf;
- strcpy(buf,VPD_NAME);
- n = strlen(VPD_NAME) + 1;
- buf += n;
- *elements = 1;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
- ("'%c%c' ",v[0],v[1]));
- }
- else {
- *len = 0;
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("buffer overflow\n"));
- return(2);
- }
-
- v += 3 + VPD_GET_RES_LEN(v) + 3;
- for (;; ) {
- /* exit when reaching the "RW" Tag */
- if (SK_MEMCMP(VPD_RW,v,2) == 0) {
- break;
- }
-
- if (SK_MEMCMP(VPD_RV,v,2) == 0) {
- v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
- continue;
- }
-
- if (n+3 <= *len) {
- SK_MEMCPY(buf,v,2);
- buf += 2;
- *buf++ = '\0';
- n += 3;
- v += 3 + VPD_GET_VPD_LEN(v);
- *elements += 1;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
- ("'%c%c' ",v[0],v[1]));
- }
- else {
- *len = n;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("buffer overflow\n"));
- return(2);
- }
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
- *len = n;
- return(0);
-}
-
-
-/*
- * Read the contents of the VPD EEPROM and copy it to the
- * VPD buffer if not already done. Search for the VPD keyword
- * 'key' and copy its value to 'buf'. Add a terminating '\0'.
- * If the value does not fit into the buffer cut it after
- * 'len' - 1 bytes.
- *
- * returns 0: success
- * 1: keyword not found
- * 2: value string was cut
- * 3: VPD transfer timeout
- * 6: fatal VPD error
- */
-int VpdRead(
-SK_AC *pAC, /* common data base */
-SK_IOC IoC, /* IO Context */
-const char *key, /* keyword to read (e.g. "MN") */
-char *buf, /* buffer where to copy the keyword value */
-int *len) /* buffer length */
-{
- SK_VPD_PARA *p, vp;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
- if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
- if (VpdInit(pAC, IoC) != 0) {
- *len = 0;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD init error\n"));
- return(6);
- }
- }
-
- if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
- if (p->p_len > (*(unsigned *)len)-1) {
- p->p_len = *len - 1;
- }
- SK_MEMCPY(buf, p->p_val, p->p_len);
- buf[p->p_len] = '\0';
- *len = p->p_len;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
- ("%c%c%c%c.., len = %d\n",
- buf[0],buf[1],buf[2],buf[3],*len));
- }
- else {
- *len = 0;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
- return(1);
- }
- return(0);
-}
-
-
-/*
- * Check whether a given key may be written
- *
- * returns
- * SK_TRUE Yes it may be written
- * SK_FALSE No it may be written
- */
-SK_BOOL VpdMayWrite(
-char *key) /* keyword to write (allowed values "Yx", "Vx") */
-{
- if ((*key != 'Y' && *key != 'V') ||
- key[1] < '0' || key[1] > 'Z' ||
- (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
-
- return(SK_FALSE);
- }
- return(SK_TRUE);
-}
-
-/*
- * Read the contents of the VPD EEPROM and copy it to the VPD
- * buffer if not already done. Insert/overwrite the keyword 'key'
- * in the VPD buffer. Cut the keyword value if it does not fit
- * into the VPD read / write area.
- *
- * returns 0: success
- * 2: value string was cut
- * 3: VPD transfer timeout
- * 4: VPD full, keyword was not written
- * 5: keyword cannot be written
- * 6: fatal VPD error
- */
-int VpdWrite(
-SK_AC *pAC, /* common data base */
-SK_IOC IoC, /* IO Context */
-const char *key, /* keyword to write (allowed values "Yx", "Vx") */
-const char *buf) /* buffer where the keyword value can be read from */
-{
- int len; /* length of the keyword to write */
- int rtv; /* return code */
- int rtv2;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
- ("VPD write %s = %s\n",key,buf));
-
- if ((*key != 'Y' && *key != 'V') ||
- key[1] < '0' || key[1] > 'Z' ||
- (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("illegal key tag, keyword not written\n"));
- return(5);
- }
-
- if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
- if (VpdInit(pAC, IoC) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD init error\n"));
- return(6);
- }
- }
-
- rtv = 0;
- len = strlen(buf);
- if (len > VPD_MAX_LEN) {
- /* cut it */
- len = VPD_MAX_LEN;
- rtv = 2;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
- }
- if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD write error\n"));
- return(rtv2);
- }
-
- return(rtv);
-}
-
-/*
- * Read the contents of the VPD EEPROM and copy it to the
- * VPD buffer if not already done. Remove the VPD keyword
- * 'key' from the VPD buffer.
- * Only the keywords in the read/write area can be deleted.
- * Keywords in the read only area cannot be deleted.
- *
- * returns 0: success, keyword was removed
- * 1: keyword not found
- * 5: keyword cannot be deleted
- * 6: fatal VPD error
- */
-int VpdDelete(
-SK_AC *pAC, /* common data base */
-SK_IOC IoC, /* IO Context */
-char *key) /* keyword to read (e.g. "MN") */
-{
- SK_VPD_PARA *p, vp;
- char *etp;
- int vpd_size;
-
- vpd_size = pAC->vpd.vpd_size;
-
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
- if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
- if (VpdInit(pAC, IoC) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD init error\n"));
- return(6);
- }
- }
-
- if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
- if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
- /* try to delete read only keyword */
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("cannot delete RO keyword\n"));
- return(5);
- }
-
- etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
-
- vpd_move_para(vp.p_val+vp.p_len, etp+2,
- - ((int)(vp.p_len + 3)));
- if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
- pAC->vpd.v.vpd_status &= ~VPD_VALID;
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("VPD encoding error\n"));
- return(6);
- }
- }
- else {
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("keyword not found\n"));
- return(1);
- }
-
- return(0);
-}
-
-/*
- * If the VPD buffer contains valid data write the VPD
- * read/write area back to the VPD EEPROM.
- *
- * returns 0: success
- * 3: VPD transfer timeout
- */
-int VpdUpdate(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC) /* IO Context */
-{
- int vpd_size;
-
- vpd_size = pAC->vpd.vpd_size;
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
- if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
- if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
- vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
- ("transfer timed out\n"));
- return(3);
- }
- }
- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
- return(0);
-}
-
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
deleted file mode 100644
index b4e75022a657..000000000000
--- a/drivers/net/sk98lin/skxmac2.c
+++ /dev/null
@@ -1,4160 +0,0 @@
-/******************************************************************************
- *
- * Name: skxmac2.c
- * Project: Gigabit Ethernet Adapters, Common Modules
- * Version: $Revision: 1.102 $
- * Date: $Date: 2003/10/02 16:53:58 $
- * Purpose: Contains functions to initialize the MACs and PHYs
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * (C)Copyright 1998-2002 SysKonnect.
- * (C)Copyright 2002-2003 Marvell.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-
-/* typedefs *******************************************************************/
-
-/* BCOM PHY magic pattern list */
-typedef struct s_PhyHack {
- int PhyReg; /* Phy register */
- SK_U16 PhyVal; /* Value to write */
-} BCOM_HACK;
-
-/* local variables ************************************************************/
-
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
- "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
-#endif
-
-#ifdef GENESIS
-static BCOM_HACK BcomRegA1Hack[] = {
- { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
- { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
- { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
- { 0, 0 }
-};
-static BCOM_HACK BcomRegC0Hack[] = {
- { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
- { 0x15, 0x0A04 }, { 0x18, 0x0420 },
- { 0, 0 }
-};
-#endif
-
-/* function prototypes ********************************************************/
-#ifdef GENESIS
-static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
-static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
-static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
-static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
-#endif /* GENESIS */
-#ifdef YUKON
-static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
-static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
-#endif /* YUKON */
-#ifdef OTHER_PHY
-static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
-static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
-static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
-static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
-#endif /* OTHER_PHY */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmPhyRead() - Read from XMAC PHY register
- *
- * Description: reads a 16-bit word from XMAC PHY or ext. PHY
- *
- * Returns:
- * nothing
- */
-void SkXmPhyRead(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Port, /* Port Index (MAC_1 + n) */
-int PhyReg, /* Register Address (Offset) */
-SK_U16 SK_FAR *pVal) /* Pointer to Value */
-{
- SK_U16 Mmu;
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* write the PHY register's address */
- XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-
- /* get the PHY register's value */
- XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
-
- if (pPrt->PhyType != SK_PHY_XMAC) {
- do {
- XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
- /* wait until 'Ready' is set */
- } while ((Mmu & XM_MMU_PHY_RDY) == 0);
-
- /* get the PHY register's value */
- XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
- }
-} /* SkXmPhyRead */
-
-
-/******************************************************************************
- *
- * SkXmPhyWrite() - Write to XMAC PHY register
- *
- * Description: writes a 16-bit word to XMAC PHY or ext. PHY
- *
- * Returns:
- * nothing
- */
-void SkXmPhyWrite(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Port, /* Port Index (MAC_1 + n) */
-int PhyReg, /* Register Address (Offset) */
-SK_U16 Val) /* Value */
-{
- SK_U16 Mmu;
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PhyType != SK_PHY_XMAC) {
- do {
- XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
- /* wait until 'Busy' is cleared */
- } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
- }
-
- /* write the PHY register's address */
- XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-
- /* write the PHY register's value */
- XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
-
- if (pPrt->PhyType != SK_PHY_XMAC) {
- do {
- XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
- /* wait until 'Busy' is cleared */
- } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
- }
-} /* SkXmPhyWrite */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmPhyRead() - Read from GPHY register
- *
- * Description: reads a 16-bit word from GPHY through MDIO
- *
- * Returns:
- * nothing
- */
-void SkGmPhyRead(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Port, /* Port Index (MAC_1 + n) */
-int PhyReg, /* Register Address (Offset) */
-SK_U16 SK_FAR *pVal) /* Pointer to Value */
-{
- SK_U16 Ctrl;
- SK_GEPORT *pPrt;
-#ifdef VCPU
- u_long SimCyle;
- u_long SimLowTime;
-
- VCPUgetTime(&SimCyle, &SimLowTime);
- VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
- PhyReg, SimCyle, SimLowTime);
-#endif /* VCPU */
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* set PHY-Register offset and 'Read' OpCode (= 1) */
- *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
- GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
-
- GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
-
- GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
- /* additional check for MDC/MDIO activity */
- if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
- *pVal = 0;
- return;
- }
-
- *pVal |= GM_SMI_CT_BUSY;
-
- do {
-#ifdef VCPU
- VCPUwaitTime(1000);
-#endif /* VCPU */
-
- GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
- /* wait until 'ReadValid' is set */
- } while (Ctrl == *pVal);
-
- /* get the PHY register's value */
- GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
-
-#ifdef VCPU
- VCPUgetTime(&SimCyle, &SimLowTime);
- VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
- SimCyle, SimLowTime);
-#endif /* VCPU */
-
-} /* SkGmPhyRead */
-
-
-/******************************************************************************
- *
- * SkGmPhyWrite() - Write to GPHY register
- *
- * Description: writes a 16-bit word to GPHY through MDIO
- *
- * Returns:
- * nothing
- */
-void SkGmPhyWrite(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Port, /* Port Index (MAC_1 + n) */
-int PhyReg, /* Register Address (Offset) */
-SK_U16 Val) /* Value */
-{
- SK_U16 Ctrl;
- SK_GEPORT *pPrt;
-#ifdef VCPU
- SK_U32 DWord;
- u_long SimCyle;
- u_long SimLowTime;
-
- VCPUgetTime(&SimCyle, &SimLowTime);
- VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
- PhyReg, Val, SimCyle, SimLowTime);
-#endif /* VCPU */
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* write the PHY register's value */
- GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
-
- /* set PHY-Register offset and 'Write' OpCode (= 0) */
- Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
-
- GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
-
- GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
- /* additional check for MDC/MDIO activity */
- if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
- return;
- }
-
- Val |= GM_SMI_CT_BUSY;
-
- do {
-#ifdef VCPU
- /* read Timer value */
- SK_IN32(IoC, B2_TI_VAL, &DWord);
-
- VCPUwaitTime(1000);
-#endif /* VCPU */
-
- GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-
- /* wait until 'Busy' is cleared */
- } while (Ctrl == Val);
-
-#ifdef VCPU
- VCPUgetTime(&SimCyle, &SimLowTime);
- VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
- SimCyle, SimLowTime);
-#endif /* VCPU */
-
-} /* SkGmPhyWrite */
-#endif /* YUKON */
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- * SkGePhyRead() - Read from PHY register
- *
- * Description: calls a read PHY routine dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkGePhyRead(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Port, /* Port Index (MAC_1 + n) */
-int PhyReg, /* Register Address (Offset) */
-SK_U16 *pVal) /* Pointer to Value */
-{
- void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
-
- if (pAC->GIni.GIGenesis) {
- r_func = SkXmPhyRead;
- }
- else {
- r_func = SkGmPhyRead;
- }
-
- r_func(pAC, IoC, Port, PhyReg, pVal);
-} /* SkGePhyRead */
-
-
-/******************************************************************************
- *
- * SkGePhyWrite() - Write to PHY register
- *
- * Description: calls a write PHY routine dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkGePhyWrite(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* I/O Context */
-int Port, /* Port Index (MAC_1 + n) */
-int PhyReg, /* Register Address (Offset) */
-SK_U16 Val) /* Value */
-{
- void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
-
- if (pAC->GIni.GIGenesis) {
- w_func = SkXmPhyWrite;
- }
- else {
- w_func = SkGmPhyWrite;
- }
-
- w_func(pAC, IoC, Port, PhyReg, Val);
-} /* SkGePhyWrite */
-#endif /* SK_DIAG */
-
-
-/******************************************************************************
- *
- * SkMacPromiscMode() - Enable / Disable Promiscuous Mode
- *
- * Description:
- * enables / disables promiscuous mode by setting Mode Register (XMAC) or
- * Receive Control Register (GMAC) dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacPromiscMode(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL Enable) /* Enable / Disable */
-{
-#ifdef YUKON
- SK_U16 RcReg;
-#endif
-#ifdef GENESIS
- SK_U32 MdReg;
-#endif
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- XM_IN32(IoC, Port, XM_MODE, &MdReg);
- /* enable or disable promiscuous mode */
- if (Enable) {
- MdReg |= XM_MD_ENA_PROM;
- }
- else {
- MdReg &= ~XM_MD_ENA_PROM;
- }
- /* setup Mode Register */
- XM_OUT32(IoC, Port, XM_MODE, MdReg);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-
- /* enable or disable unicast and multicast filtering */
- if (Enable) {
- RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
- }
- else {
- RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
- }
- /* setup Receive Control Register */
- GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
- }
-#endif /* YUKON */
-
-} /* SkMacPromiscMode*/
-
-
-/******************************************************************************
- *
- * SkMacHashing() - Enable / Disable Hashing
- *
- * Description:
- * enables / disables hashing by setting Mode Register (XMAC) or
- * Receive Control Register (GMAC) dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacHashing(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL Enable) /* Enable / Disable */
-{
-#ifdef YUKON
- SK_U16 RcReg;
-#endif
-#ifdef GENESIS
- SK_U32 MdReg;
-#endif
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- XM_IN32(IoC, Port, XM_MODE, &MdReg);
- /* enable or disable hashing */
- if (Enable) {
- MdReg |= XM_MD_ENA_HASH;
- }
- else {
- MdReg &= ~XM_MD_ENA_HASH;
- }
- /* setup Mode Register */
- XM_OUT32(IoC, Port, XM_MODE, MdReg);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-
- /* enable or disable multicast filtering */
- if (Enable) {
- RcReg |= GM_RXCR_MCF_ENA;
- }
- else {
- RcReg &= ~GM_RXCR_MCF_ENA;
- }
- /* setup Receive Control Register */
- GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
- }
-#endif /* YUKON */
-
-} /* SkMacHashing*/
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
- *
- * Description:
- * The features
- * - FCS stripping, SK_STRIP_FCS_ON/OFF
- * - pad byte stripping, SK_STRIP_PAD_ON/OFF
- * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF
- * for inrange length error frames
- * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF
- * for frames > 1514 bytes
- * - enable Rx of own packets SK_SELF_RX_ON/OFF
- *
- * for incoming packets may be enabled/disabled by this function.
- * Additional modes may be added later.
- * Multiple modes can be enabled/disabled at the same time.
- * The new configuration is written to the Rx Command register immediately.
- *
- * Returns:
- * nothing
- */
-static void SkXmSetRxCmd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
- SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
-{
- SK_U16 OldRxCmd;
- SK_U16 RxCmd;
-
- XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
-
- RxCmd = OldRxCmd;
-
- switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
- case SK_STRIP_FCS_ON:
- RxCmd |= XM_RX_STRIP_FCS;
- break;
- case SK_STRIP_FCS_OFF:
- RxCmd &= ~XM_RX_STRIP_FCS;
- break;
- }
-
- switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
- case SK_STRIP_PAD_ON:
- RxCmd |= XM_RX_STRIP_PAD;
- break;
- case SK_STRIP_PAD_OFF:
- RxCmd &= ~XM_RX_STRIP_PAD;
- break;
- }
-
- switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
- case SK_LENERR_OK_ON:
- RxCmd |= XM_RX_LENERR_OK;
- break;
- case SK_LENERR_OK_OFF:
- RxCmd &= ~XM_RX_LENERR_OK;
- break;
- }
-
- switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
- case SK_BIG_PK_OK_ON:
- RxCmd |= XM_RX_BIG_PK_OK;
- break;
- case SK_BIG_PK_OK_OFF:
- RxCmd &= ~XM_RX_BIG_PK_OK;
- break;
- }
-
- switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
- case SK_SELF_RX_ON:
- RxCmd |= XM_RX_SELF_RX;
- break;
- case SK_SELF_RX_OFF:
- RxCmd &= ~XM_RX_SELF_RX;
- break;
- }
-
- /* Write the new mode to the Rx command register if required */
- if (OldRxCmd != RxCmd) {
- XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
- }
-} /* SkXmSetRxCmd */
-
-
-/******************************************************************************
- *
- * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
- *
- * Description:
- * The features
- * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF
- * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF
- * for frames > 1514 bytes
- * - enable Rx of own packets SK_SELF_RX_ON/OFF
- *
- * for incoming packets may be enabled/disabled by this function.
- * Additional modes may be added later.
- * Multiple modes can be enabled/disabled at the same time.
- * The new configuration is written to the Rx Command register immediately.
- *
- * Returns:
- * nothing
- */
-static void SkGmSetRxCmd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
- SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
-{
- SK_U16 OldRxCmd;
- SK_U16 RxCmd;
-
- if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
-
- GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
-
- RxCmd = OldRxCmd;
-
- if ((Mode & SK_STRIP_FCS_ON) != 0) {
- RxCmd |= GM_RXCR_CRC_DIS;
- }
- else {
- RxCmd &= ~GM_RXCR_CRC_DIS;
- }
- /* Write the new mode to the Rx control register if required */
- if (OldRxCmd != RxCmd) {
- GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
- }
- }
-
- if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
-
- GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
-
- RxCmd = OldRxCmd;
-
- if ((Mode & SK_BIG_PK_OK_ON) != 0) {
- RxCmd |= GM_SMOD_JUMBO_ENA;
- }
- else {
- RxCmd &= ~GM_SMOD_JUMBO_ENA;
- }
- /* Write the new mode to the Rx control register if required */
- if (OldRxCmd != RxCmd) {
- GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
- }
- }
-} /* SkGmSetRxCmd */
-
-
-/******************************************************************************
- *
- * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
- *
- * Description: modifies the MAC's Rx Control reg. dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacSetRxCmd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-int Mode) /* Rx Mode */
-{
- if (pAC->GIni.GIGenesis) {
-
- SkXmSetRxCmd(pAC, IoC, Port, Mode);
- }
- else {
-
- SkGmSetRxCmd(pAC, IoC, Port, Mode);
- }
-
-} /* SkMacSetRxCmd */
-
-
-/******************************************************************************
- *
- * SkMacCrcGener() - Enable / Disable CRC Generation
- *
- * Description: enables / disables CRC generation dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacCrcGener(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL Enable) /* Enable / Disable */
-{
- SK_U16 Word;
-
- if (pAC->GIni.GIGenesis) {
-
- XM_IN16(IoC, Port, XM_TX_CMD, &Word);
-
- if (Enable) {
- Word &= ~XM_TX_NO_CRC;
- }
- else {
- Word |= XM_TX_NO_CRC;
- }
- /* setup Tx Command Register */
- XM_OUT16(IoC, Port, XM_TX_CMD, Word);
- }
- else {
-
- GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
-
- if (Enable) {
- Word &= ~GM_TXCR_CRC_DIS;
- }
- else {
- Word |= GM_TXCR_CRC_DIS;
- }
- /* setup Tx Control Register */
- GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
- }
-
-} /* SkMacCrcGener*/
-
-#endif /* SK_DIAG */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmClrExactAddr() - Clear Exact Match Address Registers
- *
- * Description:
- * All Exact Match Address registers of the XMAC 'Port' will be
- * cleared starting with 'StartNum' up to (and including) the
- * Exact Match address number of 'StopNum'.
- *
- * Returns:
- * nothing
- */
-void SkXmClrExactAddr(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-int StartNum, /* Begin with this Address Register Index (0..15) */
-int StopNum) /* Stop after finished with this Register Idx (0..15) */
-{
- int i;
- SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
-
- if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
- StartNum > StopNum) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
- return;
- }
-
- for (i = StartNum; i <= StopNum; i++) {
- XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
- }
-} /* SkXmClrExactAddr */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
- *
- * Description:
- * Flush the transmit FIFO of the MAC specified by the index 'Port'
- *
- * Returns:
- * nothing
- */
-void SkMacFlushTxFifo(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
-#ifdef GENESIS
- SK_U32 MdReg;
-
- if (pAC->GIni.GIGenesis) {
-
- XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
- XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* no way to flush the FIFO we have to issue a reset */
- /* TBD */
- }
-#endif /* YUKON */
-
-} /* SkMacFlushTxFifo */
-
-
-/******************************************************************************
- *
- * SkMacFlushRxFifo() - Flush the MAC's receive FIFO
- *
- * Description:
- * Flush the receive FIFO of the MAC specified by the index 'Port'
- *
- * Returns:
- * nothing
- */
-static void SkMacFlushRxFifo(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
-#ifdef GENESIS
- SK_U32 MdReg;
-
- if (pAC->GIni.GIGenesis) {
-
- XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
- XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* no way to flush the FIFO we have to issue a reset */
- /* TBD */
- }
-#endif /* YUKON */
-
-} /* SkMacFlushRxFifo */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmSoftRst() - Do a XMAC software reset
- *
- * Description:
- * The PHY registers should not be destroyed during this
- * kind of software reset. Therefore the XMAC Software Reset
- * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
- *
- * The software reset is done by
- * - disabling the Rx and Tx state machine,
- * - resetting the statistics module,
- * - clear all other significant XMAC Mode,
- * Command, and Control Registers
- * - clearing the Hash Register and the
- * Exact Match Address registers, and
- * - flushing the XMAC's Rx and Tx FIFOs.
- *
- * Note:
- * Another requirement when stopping the XMAC is to
- * avoid sending corrupted frames on the network.
- * Disabling the Tx state machine will NOT interrupt
- * the currently transmitted frame. But we must take care
- * that the Tx FIFO is cleared AFTER the current frame
- * is complete sent to the network.
- *
- * It takes about 12ns to send a frame with 1538 bytes.
- * One PCI clock goes at least 15ns (66MHz). Therefore
- * after reading XM_GP_PORT back, we are sure that the
- * transmitter is disabled AND idle. And this means
- * we may flush the transmit FIFO now.
- *
- * Returns:
- * nothing
- */
-static void SkXmSoftRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
-
- /* reset the statistics module */
- XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
-
- /* disable all XMAC IRQs */
- XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
-
- XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */
-
- XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */
- XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */
-
- /* disable all PHY IRQs */
- switch (pAC->GIni.GP[Port].PhyType) {
- case SK_PHY_BCOM:
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
- break;
- case SK_PHY_NAT:
- /* todo: National
- SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
- break;
-#endif /* OTHER_PHY */
- }
-
- /* clear the Hash Register */
- XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
-
- /* clear the Exact Match Address registers */
- SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
-
- /* clear the Source Check Address registers */
- XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
-
-} /* SkXmSoftRst */
-
-
-/******************************************************************************
- *
- * SkXmHardRst() - Do a XMAC hardware reset
- *
- * Description:
- * The XMAC of the specified 'Port' and all connected devices
- * (PHY and SERDES) will receive a reset signal on its *Reset pins.
- * External PHYs must be reset by clearing a bit in the GPIO register
- * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
- *
- * ATTENTION:
- * It is absolutely necessary to reset the SW_RST Bit first
- * before calling this function.
- *
- * Returns:
- * nothing
- */
-static void SkXmHardRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U32 Reg;
- int i;
- int TOut;
- SK_U16 Word;
-
- for (i = 0; i < 4; i++) {
- /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
-
- TOut = 0;
- do {
- if (TOut++ > 10000) {
- /*
- * Adapter seems to be in RESET state.
- * Registers cannot be written.
- */
- return;
- }
-
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
-
- SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
-
- } while ((Word & MFF_SET_MAC_RST) == 0);
- }
-
- /* For external PHYs there must be special handling */
- if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-
- SK_IN32(IoC, B2_GP_IO, &Reg);
-
- if (Port == 0) {
- Reg |= GP_DIR_0; /* set to output */
- Reg &= ~GP_IO_0; /* set PHY reset (active low) */
- }
- else {
- Reg |= GP_DIR_2; /* set to output */
- Reg &= ~GP_IO_2; /* set PHY reset (active low) */
- }
- /* reset external PHY */
- SK_OUT32(IoC, B2_GP_IO, Reg);
-
- /* short delay */
- SK_IN32(IoC, B2_GP_IO, &Reg);
- }
-} /* SkXmHardRst */
-
-
-/******************************************************************************
- *
- * SkXmClearRst() - Release the PHY & XMAC reset
- *
- * Description:
- *
- * Returns:
- * nothing
- */
-static void SkXmClearRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U32 DWord;
-
- /* clear HW reset */
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
-
- if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-
- SK_IN32(IoC, B2_GP_IO, &DWord);
-
- if (Port == 0) {
- DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
- }
- else {
- DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
- }
- /* Clear PHY reset */
- SK_OUT32(IoC, B2_GP_IO, DWord);
-
- /* Enable GMII interface */
- XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
- }
-} /* SkXmClearRst */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmSoftRst() - Do a GMAC software reset
- *
- * Description:
- * The GPHY registers should not be destroyed during this
- * kind of software reset.
- *
- * Returns:
- * nothing
- */
-static void SkGmSoftRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
- SK_U16 RxCtrl;
-
- /* reset the statistics module */
-
- /* disable all GMAC IRQs */
- SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-
- /* disable all PHY IRQs */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-
- /* clear the Hash Register */
- GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
-
- /* Enable Unicast and Multicast filtering */
- GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
-
- GM_OUT16(IoC, Port, GM_RX_CTRL,
- (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
-
-} /* SkGmSoftRst */
-
-
-/******************************************************************************
- *
- * SkGmHardRst() - Do a GMAC hardware reset
- *
- * Description:
- *
- * Returns:
- * nothing
- */
-static void SkGmHardRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U32 DWord;
-
- /* WA code for COMA mode */
- if (pAC->GIni.GIYukonLite &&
- pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
-
- SK_IN32(IoC, B2_GP_IO, &DWord);
-
- DWord |= (GP_DIR_9 | GP_IO_9);
-
- /* set PHY reset */
- SK_OUT32(IoC, B2_GP_IO, DWord);
- }
-
- /* set GPHY Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
-
- /* set GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-} /* SkGmHardRst */
-
-
-/******************************************************************************
- *
- * SkGmClearRst() - Release the GPHY & GMAC reset
- *
- * Description:
- *
- * Returns:
- * nothing
- */
-static void SkGmClearRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U32 DWord;
-
-#ifdef XXX
- /* clear GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
-
- /* set GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-#endif /* XXX */
-
- /* WA code for COMA mode */
- if (pAC->GIni.GIYukonLite &&
- pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
-
- SK_IN32(IoC, B2_GP_IO, &DWord);
-
- DWord |= GP_DIR_9; /* set to output */
- DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
-
- /* clear PHY reset */
- SK_OUT32(IoC, B2_GP_IO, DWord);
- }
-
- /* set HWCFG_MODE */
- DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
- GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
- (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
- GPC_HWCFG_GMII_FIB);
-
- /* set GPHY Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
-
- /* release GPHY Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
-
-#ifdef VCPU
- VCpuWait(9000);
-#endif /* VCPU */
-
- /* clear GMAC Control reset */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
-
-#ifdef VCPU
- VCpuWait(2000);
-
- SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
-
- SK_IN32(IoC, B0_ISRC, &DWord);
-#endif /* VCPU */
-
-} /* SkGmClearRst */
-#endif /* YUKON */
-
-
-/******************************************************************************
- *
- * SkMacSoftRst() - Do a MAC software reset
- *
- * Description: calls a MAC software reset routine dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacSoftRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* disable receiver and transmitter */
- SkMacRxTxDisable(pAC, IoC, Port);
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- SkXmSoftRst(pAC, IoC, Port);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- SkGmSoftRst(pAC, IoC, Port);
- }
-#endif /* YUKON */
-
- /* flush the MAC's Rx and Tx FIFOs */
- SkMacFlushTxFifo(pAC, IoC, Port);
-
- SkMacFlushRxFifo(pAC, IoC, Port);
-
- pPrt->PState = SK_PRT_STOP;
-
-} /* SkMacSoftRst */
-
-
-/******************************************************************************
- *
- * SkMacHardRst() - Do a MAC hardware reset
- *
- * Description: calls a MAC hardware reset routine dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacHardRst(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- SkXmHardRst(pAC, IoC, Port);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- SkGmHardRst(pAC, IoC, Port);
- }
-#endif /* YUKON */
-
- pAC->GIni.GP[Port].PState = SK_PRT_RESET;
-
-} /* SkMacHardRst */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmInitMac() - Initialize the XMAC II
- *
- * Description:
- * Initialize the XMAC of the specified port.
- * The XMAC must be reset or stopped before calling this function.
- *
- * Note:
- * The XMAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- * nothing
- */
-void SkXmInitMac(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- int i;
- SK_U16 SWord;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PState == SK_PRT_STOP) {
- /* Port State: SK_PRT_STOP */
- /* Verify that the reset bit is cleared */
- SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
-
- if ((SWord & MFF_SET_MAC_RST) != 0) {
- /* PState does not match HW state */
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
- /* Correct it */
- pPrt->PState = SK_PRT_RESET;
- }
- }
-
- if (pPrt->PState == SK_PRT_RESET) {
-
- SkXmClearRst(pAC, IoC, Port);
-
- if (pPrt->PhyType != SK_PHY_XMAC) {
- /* read Id from external PHY (all have the same address) */
- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
-
- /*
- * Optimize MDIO transfer by suppressing preamble.
- * Must be done AFTER first access to BCOM chip.
- */
- XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
-
- XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
-
- if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
- /*
- * Workaround BCOM Errata for the C0 type.
- * Write magic patterns to reserved registers.
- */
- i = 0;
- while (BcomRegC0Hack[i].PhyReg != 0) {
- SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
- BcomRegC0Hack[i].PhyVal);
- i++;
- }
- }
- else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
- /*
- * Workaround BCOM Errata for the A1 type.
- * Write magic patterns to reserved registers.
- */
- i = 0;
- while (BcomRegA1Hack[i].PhyReg != 0) {
- SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
- BcomRegA1Hack[i].PhyVal);
- i++;
- }
- }
-
- /*
- * Workaround BCOM Errata (#10523) for all BCom PHYs.
- * Disable Power Management after reset.
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
-
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
- (SK_U16)(SWord | PHY_B_AC_DIS_PM));
-
- /* PHY LED initialization is done in SkGeXmitLED() */
- }
-
- /* Dummy read the Interrupt source register */
- XM_IN16(IoC, Port, XM_ISRC, &SWord);
-
- /*
- * The auto-negotiation process starts immediately after
- * clearing the reset. The auto-negotiation process should be
- * started by the SIRQ, therefore stop it here immediately.
- */
- SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
-
-#ifdef TEST_ONLY
- /* temp. code: enable signal detect */
- /* WARNING: do not override GMII setting above */
- XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG);
-#endif
- }
-
- /*
- * configure the XMACs Station Address
- * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
- * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
- */
- for (i = 0; i < 3; i++) {
- /*
- * The following 2 statements are together endianess
- * independent. Remember this when changing.
- */
- SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-
- XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
- }
-
- /* Tx Inter Packet Gap (XM_TX_IPG): use default */
- /* Tx High Water Mark (XM_TX_HI_WM): use default */
- /* Tx Low Water Mark (XM_TX_LO_WM): use default */
- /* Host Request Threshold (XM_HT_THR): use default */
- /* Rx Request Threshold (XM_RX_THR): use default */
- /* Rx Low Water Mark (XM_RX_LO_WM): use default */
-
- /* configure Rx High Water Mark (XM_RX_HI_WM) */
- XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
-
- /* Configure Tx Request Threshold */
- SWord = SK_XM_THR_SL; /* for single port */
-
- if (pAC->GIni.GIMacsFound > 1) {
- switch (pAC->GIni.GIPortUsage) {
- case SK_RED_LINK:
- SWord = SK_XM_THR_REDL; /* redundant link */
- break;
- case SK_MUL_LINK:
- SWord = SK_XM_THR_MULL; /* load balancing */
- break;
- case SK_JUMBO_LINK:
- SWord = SK_XM_THR_JUMBO; /* jumbo frames */
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
- break;
- }
- }
- XM_OUT16(IoC, Port, XM_TX_THR, SWord);
-
- /* setup register defaults for the Tx Command Register */
- XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
-
- /* setup register defaults for the Rx Command Register */
- SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
-
- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
- SWord |= XM_RX_BIG_PK_OK;
- }
-
- if (pPrt->PLinkMode == SK_LMODE_HALF) {
- /*
- * If in manual half duplex mode the other side might be in
- * full duplex mode, so ignore if a carrier extension is not seen
- * on frames received
- */
- SWord |= XM_RX_DIS_CEXT;
- }
-
- XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
-
- /*
- * setup register defaults for the Mode Register
- * - Don't strip error frames to avoid Store & Forward
- * on the Rx side.
- * - Enable 'Check Station Address' bit
- * - Enable 'Check Address Array' bit
- */
- XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
-
- /*
- * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
- * - Enable all bits excepting 'Octets Rx OK Low CntOv'
- * and 'Octets Rx OK Hi Cnt Ov'.
- */
- XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
-
- /*
- * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
- * - Enable all bits excepting 'Octets Tx OK Low CntOv'
- * and 'Octets Tx OK Hi Cnt Ov'.
- */
- XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
-
- /*
- * Do NOT init XMAC interrupt mask here.
- * All interrupts remain disable until link comes up!
- */
-
- /*
- * Any additional configuration changes may be done now.
- * The last action is to enable the Rx and Tx state machine.
- * This should be done after the auto-negotiation process
- * has been completed successfully.
- */
-} /* SkXmInitMac */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmInitMac() - Initialize the GMAC
- *
- * Description:
- * Initialize the GMAC of the specified port.
- * The GMAC must be reset or stopped before calling this function.
- *
- * Note:
- * The GMAC's Rx and Tx state machine is still disabled when returning.
- *
- * Returns:
- * nothing
- */
-void SkGmInitMac(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- int i;
- SK_U16 SWord;
- SK_U32 DWord;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PState == SK_PRT_STOP) {
- /* Port State: SK_PRT_STOP */
- /* Verify that the reset bit is cleared */
- SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
-
- if ((DWord & GMC_RST_SET) != 0) {
- /* PState does not match HW state */
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
- /* Correct it */
- pPrt->PState = SK_PRT_RESET;
- }
- }
-
- if (pPrt->PState == SK_PRT_RESET) {
-
- SkGmHardRst(pAC, IoC, Port);
-
- SkGmClearRst(pAC, IoC, Port);
-
- /* Auto-negotiation ? */
- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
- /* Auto-negotiation disabled */
-
- /* get General Purpose Control */
- GM_IN16(IoC, Port, GM_GP_CTRL, &SWord);
-
- /* disable auto-update for speed, duplex and flow-control */
- SWord |= GM_GPCR_AU_ALL_DIS;
-
- /* setup General Purpose Control Register */
- GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
-
- SWord = GM_GPCR_AU_ALL_DIS;
- }
- else {
- SWord = 0;
- }
-
- /* speed settings */
- switch (pPrt->PLinkSpeed) {
- case SK_LSPEED_AUTO:
- case SK_LSPEED_1000MBPS:
- SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
- break;
- case SK_LSPEED_100MBPS:
- SWord |= GM_GPCR_SPEED_100;
- break;
- case SK_LSPEED_10MBPS:
- break;
- }
-
- /* duplex settings */
- if (pPrt->PLinkMode != SK_LMODE_HALF) {
- /* set full duplex */
- SWord |= GM_GPCR_DUP_FULL;
- }
-
- /* flow-control settings */
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- /* set Pause Off */
- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
- /* disable Tx & Rx flow-control */
- SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
- break;
- case SK_FLOW_MODE_LOC_SEND:
- /* disable Rx flow-control */
- SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- case SK_FLOW_MODE_SYM_OR_REM:
- /* enable Tx & Rx flow-control */
- break;
- }
-
- /* setup General Purpose Control Register */
- GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
-
- /* dummy read the Interrupt Source Register */
- SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
-
-#ifndef VCPU
- /* read Id from PHY */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
-
- SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
-#endif /* VCPU */
- }
-
- (void)SkGmResetCounter(pAC, IoC, Port);
-
- /* setup Transmit Control Register */
- GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
-
- /* setup Receive Control Register */
- GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
- GM_RXCR_CRC_DIS);
-
- /* setup Transmit Flow Control Register */
- GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
-
- /* setup Transmit Parameter Register */
-#ifdef VCPU
- GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
-#endif /* VCPU */
-
- SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
- TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
- TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
-
- GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
-
- /* configure the Serial Mode Register */
-#ifdef VCPU
- GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
-#endif /* VCPU */
-
- SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
-
- if (pPrt->PMacLimit4) {
- /* reset of collision counter after 4 consecutive collisions */
- SWord |= GM_SMOD_LIMIT_4;
- }
-
- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
- /* enable jumbo mode (Max. Frame Length = 9018) */
- SWord |= GM_SMOD_JUMBO_ENA;
- }
-
- GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
-
- /*
- * configure the GMACs Station Addresses
- * in PROM you can find our addresses at:
- * B2_MAC_1 = xx xx xx xx xx x0 virtual address
- * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
- * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
- */
-
- for (i = 0; i < 3; i++) {
- /*
- * The following 2 statements are together endianess
- * independent. Remember this when changing.
- */
- /* physical address: will be used for pause frames */
- SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-
-#ifdef WA_DEV_16
- /* WA for deviation #16 */
- if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {
- /* swap the address bytes */
- SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
-
- /* write to register in reversed order */
- GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
- }
- else {
- GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
- }
-#else
- GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
-#endif /* WA_DEV_16 */
-
- /* virtual address: will be used for data */
- SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
-
- GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
-
- /* reset Multicast filtering Hash registers 1-3 */
- GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
- }
-
- /* reset Multicast filtering Hash register 4 */
- GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
-
- /* enable interrupt mask for counter overflows */
- GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
- GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
- GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
-
-#if defined(SK_DIAG) || defined(DEBUG)
- /* read General Purpose Status */
- GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("MAC Stat Reg.=0x%04X\n", SWord));
-#endif /* SK_DIAG || DEBUG */
-
-#ifdef SK_DIAG
- c_print("MAC Stat Reg=0x%04X\n", SWord);
-#endif /* SK_DIAG */
-
-} /* SkGmInitMac */
-#endif /* YUKON */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmInitDupMd() - Initialize the XMACs Duplex Mode
- *
- * Description:
- * This function initializes the XMACs Duplex Mode.
- * It should be called after successfully finishing
- * the Auto-negotiation Process
- *
- * Returns:
- * nothing
- */
-static void SkXmInitDupMd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- switch (pAC->GIni.GP[Port].PLinkModeStatus) {
- case SK_LMODE_STAT_AUTOHALF:
- case SK_LMODE_STAT_HALF:
- /* Configuration Actions for Half Duplex Mode */
- /*
- * XM_BURST = default value. We are probable not quick
- * enough at the 'XMAC' bus to burst 8kB.
- * The XMAC stops bursting if no transmit frames
- * are available or the burst limit is exceeded.
- */
- /* XM_TX_RT_LIM = default value (15) */
- /* XM_TX_STIME = default value (0xff = 4096 bit times) */
- break;
- case SK_LMODE_STAT_AUTOFULL:
- case SK_LMODE_STAT_FULL:
- /* Configuration Actions for Full Duplex Mode */
- /*
- * The duplex mode is configured by the PHY,
- * therefore it seems to be that there is nothing
- * to do here.
- */
- break;
- case SK_LMODE_STAT_UNKNOWN:
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
- break;
- }
-} /* SkXmInitDupMd */
-
-
-/******************************************************************************
- *
- * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
- *
- * Description:
- * This function initializes the Pause Mode which should
- * be used for this port.
- * It should be called after successfully finishing
- * the Auto-negotiation Process
- *
- * Returns:
- * nothing
- */
-static void SkXmInitPauseMd(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U32 DWord;
- SK_U16 Word;
-
- pPrt = &pAC->GIni.GP[Port];
-
- XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-
- if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
- pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
-
- /* Disable Pause Frame Reception */
- Word |= XM_MMU_IGN_PF;
- }
- else {
- /*
- * enabling pause frame reception is required for 1000BT
- * because the XMAC is not reset if the link is going down
- */
- /* Enable Pause Frame Reception */
- Word &= ~XM_MMU_IGN_PF;
- }
-
- XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
-
- XM_IN32(IoC, Port, XM_MODE, &DWord);
-
- if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
- pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
-
- /*
- * Configure Pause Frame Generation
- * Use internal and external Pause Frame Generation.
- * Sending pause frames is edge triggered.
- * Send a Pause frame with the maximum pause time if
- * internal oder external FIFO full condition occurs.
- * Send a zero pause time frame to re-start transmission.
- */
-
- /* XM_PAUSE_DA = '010000C28001' (default) */
-
- /* XM_MAC_PTIME = 0xffff (maximum) */
- /* remember this value is defined in big endian (!) */
- XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
-
- /* Set Pause Mode in Mode Register */
- DWord |= XM_PAUSE_MODE;
-
- /* Set Pause Mode in MAC Rx FIFO */
- SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
- }
- else {
- /*
- * disable pause frame generation is required for 1000BT
- * because the XMAC is not reset if the link is going down
- */
- /* Disable Pause Mode in Mode Register */
- DWord &= ~XM_PAUSE_MODE;
-
- /* Disable Pause Mode in MAC Rx FIFO */
- SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
- }
-
- XM_OUT32(IoC, Port, XM_MODE, DWord);
-} /* SkXmInitPauseMd*/
-
-
-/******************************************************************************
- *
- * SkXmInitPhyXmac() - Initialize the XMAC Phy registers
- *
- * Description: initializes all the XMACs Phy registers
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-static void SkXmInitPhyXmac(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
-{
- SK_GEPORT *pPrt;
- SK_U16 Ctrl;
-
- pPrt = &pAC->GIni.GP[Port];
- Ctrl = 0;
-
- /* Auto-negotiation ? */
- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
- /* Set DuplexMode in Config register */
- if (pPrt->PLinkMode == SK_LMODE_FULL) {
- Ctrl |= PHY_CT_DUP_MD;
- }
-
- /*
- * Do NOT enable Auto-negotiation here. This would hold
- * the link down because no IDLEs are transmitted
- */
- }
- else {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
- /* Set Auto-negotiation advertisement */
-
- /* Set Full/half duplex capabilities */
- switch (pPrt->PLinkMode) {
- case SK_LMODE_AUTOHALF:
- Ctrl |= PHY_X_AN_HD;
- break;
- case SK_LMODE_AUTOFULL:
- Ctrl |= PHY_X_AN_FD;
- break;
- case SK_LMODE_AUTOBOTH:
- Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
- SKERR_HWI_E015MSG);
- }
-
- /* Set Flow-control capabilities */
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- Ctrl |= PHY_X_P_NO_PAUSE;
- break;
- case SK_FLOW_MODE_LOC_SEND:
- Ctrl |= PHY_X_P_ASYM_MD;
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- Ctrl |= PHY_X_P_SYM_MD;
- break;
- case SK_FLOW_MODE_SYM_OR_REM:
- Ctrl |= PHY_X_P_BOTH_MD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
- SKERR_HWI_E016MSG);
- }
-
- /* Write AutoNeg Advertisement Register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
-
- /* Restart Auto-negotiation */
- Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
- }
-
- if (DoLoop) {
- /* Set the Phy Loopback bit, too */
- Ctrl |= PHY_CT_LOOP;
- }
-
- /* Write to the Phy control register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
-} /* SkXmInitPhyXmac */
-
-
-/******************************************************************************
- *
- * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
- *
- * Description: initializes all the Broadcom Phy registers
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-static void SkXmInitPhyBcom(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
-{
- SK_GEPORT *pPrt;
- SK_U16 Ctrl1;
- SK_U16 Ctrl2;
- SK_U16 Ctrl3;
- SK_U16 Ctrl4;
- SK_U16 Ctrl5;
-
- Ctrl1 = PHY_CT_SP1000;
- Ctrl2 = 0;
- Ctrl3 = PHY_SEL_TYPE;
- Ctrl4 = PHY_B_PEC_EN_LTR;
- Ctrl5 = PHY_B_AC_TX_TST;
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* manually Master/Slave ? */
- if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
- Ctrl2 |= PHY_B_1000C_MSE;
-
- if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
- Ctrl2 |= PHY_B_1000C_MSC;
- }
- }
- /* Auto-negotiation ? */
- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
- /* Set DuplexMode in Config register */
- if (pPrt->PLinkMode == SK_LMODE_FULL) {
- Ctrl1 |= PHY_CT_DUP_MD;
- }
-
- /* Determine Master/Slave manually if not already done */
- if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
- Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
- }
-
- /*
- * Do NOT enable Auto-negotiation here. This would hold
- * the link down because no IDLES are transmitted
- */
- }
- else {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
- /* Set Auto-negotiation advertisement */
-
- /*
- * Workaround BCOM Errata #1 for the C5 type.
- * 1000Base-T Link Acquisition Failure in Slave Mode
- * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
- */
- Ctrl2 |= PHY_B_1000C_RD;
-
- /* Set Full/half duplex capabilities */
- switch (pPrt->PLinkMode) {
- case SK_LMODE_AUTOHALF:
- Ctrl2 |= PHY_B_1000C_AHD;
- break;
- case SK_LMODE_AUTOFULL:
- Ctrl2 |= PHY_B_1000C_AFD;
- break;
- case SK_LMODE_AUTOBOTH:
- Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
- SKERR_HWI_E015MSG);
- }
-
- /* Set Flow-control capabilities */
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- Ctrl3 |= PHY_B_P_NO_PAUSE;
- break;
- case SK_FLOW_MODE_LOC_SEND:
- Ctrl3 |= PHY_B_P_ASYM_MD;
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- Ctrl3 |= PHY_B_P_SYM_MD;
- break;
- case SK_FLOW_MODE_SYM_OR_REM:
- Ctrl3 |= PHY_B_P_BOTH_MD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
- SKERR_HWI_E016MSG);
- }
-
- /* Restart Auto-negotiation */
- Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
- }
-
- /* Initialize LED register here? */
- /* No. Please do it in SkDgXmitLed() (if required) and swap
- init order of LEDs and XMAC. (MAl) */
-
- /* Write 1000Base-T Control Register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-
- /* Write AutoNeg Advertisement Register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
-
- if (DoLoop) {
- /* Set the Phy Loopback bit, too */
- Ctrl1 |= PHY_CT_LOOP;
- }
-
- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
- /* configure FIFO to high latency for transmission of ext. packets */
- Ctrl4 |= PHY_B_PEC_HIGH_LA;
-
- /* configure reception of extended packets */
- Ctrl5 |= PHY_B_AC_LONG_PACK;
-
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
- }
-
- /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
-
- /* Write to the Phy control register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Control Reg=0x%04X\n", Ctrl1));
-} /* SkXmInitPhyBcom */
-#endif /* GENESIS */
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmInitPhyMarv() - Initialize the Marvell Phy registers
- *
- * Description: initializes all the Marvell Phy registers
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-static void SkGmInitPhyMarv(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
-{
- SK_GEPORT *pPrt;
- SK_U16 PhyCtrl;
- SK_U16 C1000BaseT;
- SK_U16 AutoNegAdv;
- SK_U16 ExtPhyCtrl;
- SK_U16 LedCtrl;
- SK_BOOL AutoNeg;
-#if defined(SK_DIAG) || defined(DEBUG)
- SK_U16 PhyStat;
- SK_U16 PhyStat1;
- SK_U16 PhySpecStat;
-#endif /* SK_DIAG || DEBUG */
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* Auto-negotiation ? */
- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
- AutoNeg = SK_FALSE;
- }
- else {
- AutoNeg = SK_TRUE;
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyMarv: Port %d, auto-negotiation %s\n",
- Port, AutoNeg ? "ON" : "OFF"));
-
-#ifdef VCPU
- VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
- Port, DoLoop);
-#else /* VCPU */
- if (DoLoop) {
- /* Set 'MAC Power up'-bit, set Manual MDI configuration */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
- PHY_M_PC_MAC_POW_UP);
- }
- else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
- /* Read Ext. PHY Specific Control */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-
- ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
- PHY_M_EC_MAC_S_MSK);
-
- ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
- PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
-
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
- }
-
- /* Read PHY Control */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
-
- if (!AutoNeg) {
- /* Disable Auto-negotiation */
- PhyCtrl &= ~PHY_CT_ANE;
- }
-
- PhyCtrl |= PHY_CT_RESET;
- /* Assert software reset */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-#endif /* VCPU */
-
- PhyCtrl = 0 /* PHY_CT_COL_TST */;
- C1000BaseT = 0;
- AutoNegAdv = PHY_SEL_TYPE;
-
- /* manually Master/Slave ? */
- if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
- /* enable Manual Master/Slave */
- C1000BaseT |= PHY_M_1000C_MSE;
-
- if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
- C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */
- }
- }
-
- /* Auto-negotiation ? */
- if (!AutoNeg) {
-
- if (pPrt->PLinkMode == SK_LMODE_FULL) {
- /* Set Full Duplex Mode */
- PhyCtrl |= PHY_CT_DUP_MD;
- }
-
- /* Set Master/Slave manually if not already done */
- if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
- C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */
- }
-
- /* Set Speed */
- switch (pPrt->PLinkSpeed) {
- case SK_LSPEED_AUTO:
- case SK_LSPEED_1000MBPS:
- PhyCtrl |= PHY_CT_SP1000;
- break;
- case SK_LSPEED_100MBPS:
- PhyCtrl |= PHY_CT_SP100;
- break;
- case SK_LSPEED_10MBPS:
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
- SKERR_HWI_E019MSG);
- }
-
- if (!DoLoop) {
- PhyCtrl |= PHY_CT_RESET;
- }
- }
- else {
- /* Set Auto-negotiation advertisement */
-
- if (pAC->GIni.GICopperType) {
- /* Set Speed capabilities */
- switch (pPrt->PLinkSpeed) {
- case SK_LSPEED_AUTO:
- C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
- AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
- PHY_M_AN_10_FD | PHY_M_AN_10_HD;
- break;
- case SK_LSPEED_1000MBPS:
- C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
- break;
- case SK_LSPEED_100MBPS:
- AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
- /* advertise 10Base-T also */
- PHY_M_AN_10_FD | PHY_M_AN_10_HD;
- break;
- case SK_LSPEED_10MBPS:
- AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
- SKERR_HWI_E019MSG);
- }
-
- /* Set Full/half duplex capabilities */
- switch (pPrt->PLinkMode) {
- case SK_LMODE_AUTOHALF:
- C1000BaseT &= ~PHY_M_1000C_AFD;
- AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
- break;
- case SK_LMODE_AUTOFULL:
- C1000BaseT &= ~PHY_M_1000C_AHD;
- AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
- break;
- case SK_LMODE_AUTOBOTH:
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
- SKERR_HWI_E015MSG);
- }
-
- /* Set Flow-control capabilities */
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- AutoNegAdv |= PHY_B_P_NO_PAUSE;
- break;
- case SK_FLOW_MODE_LOC_SEND:
- AutoNegAdv |= PHY_B_P_ASYM_MD;
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- AutoNegAdv |= PHY_B_P_SYM_MD;
- break;
- case SK_FLOW_MODE_SYM_OR_REM:
- AutoNegAdv |= PHY_B_P_BOTH_MD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
- SKERR_HWI_E016MSG);
- }
- }
- else { /* special defines for FIBER (88E1011S only) */
-
- /* Set Full/half duplex capabilities */
- switch (pPrt->PLinkMode) {
- case SK_LMODE_AUTOHALF:
- AutoNegAdv |= PHY_M_AN_1000X_AHD;
- break;
- case SK_LMODE_AUTOFULL:
- AutoNegAdv |= PHY_M_AN_1000X_AFD;
- break;
- case SK_LMODE_AUTOBOTH:
- AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
- SKERR_HWI_E015MSG);
- }
-
- /* Set Flow-control capabilities */
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
- break;
- case SK_FLOW_MODE_LOC_SEND:
- AutoNegAdv |= PHY_M_P_ASYM_MD_X;
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- AutoNegAdv |= PHY_M_P_SYM_MD_X;
- break;
- case SK_FLOW_MODE_SYM_OR_REM:
- AutoNegAdv |= PHY_M_P_BOTH_MD_X;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
- SKERR_HWI_E016MSG);
- }
- }
-
- if (!DoLoop) {
- /* Restart Auto-negotiation */
- PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
- }
- }
-
-#ifdef VCPU
- /*
- * E-mail from Gu Lin (08-03-2002):
- */
-
- /* Program PHY register 30 as 16'h0708 for simulation speed up */
- SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
-
- VCpuWait(2000);
-
-#else /* VCPU */
-
- /* Write 1000Base-T Control Register */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
-
- /* Write AutoNeg Advertisement Register */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
-#endif /* VCPU */
-
- if (DoLoop) {
- /* Set the PHY Loopback bit */
- PhyCtrl |= PHY_CT_LOOP;
-
-#ifdef XXX
- /* Program PHY register 16 as 16'h0400 to force link good */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
-#endif /* XXX */
-
-#ifndef VCPU
- if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
- /* Write Ext. PHY Specific Control */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
- (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
- }
-#endif /* VCPU */
- }
-#ifdef TEST_ONLY
- else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
- /* Write PHY Specific Control */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
- PHY_M_PC_EN_DET_MSK);
- }
-#endif
-
- /* Write to the PHY Control register */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
-
-#ifdef VCPU
- VCpuWait(2000);
-#else
-
- LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
-
- if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
- LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
- }
-
- if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
- LedCtrl |= PHY_M_LEDC_DP_CTRL;
- }
-
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
-
- if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
- /* only in forced 100 Mbps mode */
- if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
-
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
- PHY_M_LED_MO_100(MO_LED_ON));
- }
- }
-
-#ifdef SK_DIAG
- c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
- c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
- c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
- c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
-#endif /* SK_DIAG */
-
-#if defined(SK_DIAG) || defined(DEBUG)
- /* Read PHY Control */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
-
- /* Read 1000Base-T Control Register */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
-
- /* Read AutoNeg Advertisement Register */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
-
- /* Read Ext. PHY Specific Control */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
-
- /* Read PHY Status */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Stat Reg.=0x%04X\n", PhyStat));
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Stat Reg.=0x%04X\n", PhyStat1));
-
- /* Read PHY Specific Status */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Spec Stat=0x%04X\n", PhySpecStat));
-#endif /* SK_DIAG || DEBUG */
-
-#ifdef SK_DIAG
- c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
- c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
- c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
- c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
- c_print("PHY Stat Reg=0x%04X\n", PhyStat);
- c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
- c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
-#endif /* SK_DIAG */
-
-#endif /* VCPU */
-
-} /* SkGmInitPhyMarv */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- * SkXmInitPhyLone() - Initialize the Level One Phy registers
- *
- * Description: initializes all the Level One Phy registers
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-static void SkXmInitPhyLone(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
-{
- SK_GEPORT *pPrt;
- SK_U16 Ctrl1;
- SK_U16 Ctrl2;
- SK_U16 Ctrl3;
-
- Ctrl1 = PHY_CT_SP1000;
- Ctrl2 = 0;
- Ctrl3 = PHY_SEL_TYPE;
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* manually Master/Slave ? */
- if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
- Ctrl2 |= PHY_L_1000C_MSE;
-
- if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
- Ctrl2 |= PHY_L_1000C_MSC;
- }
- }
- /* Auto-negotiation ? */
- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
- /*
- * level one spec say: "1000 Mbps: manual mode not allowed"
- * but lets see what happens...
- */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyLone: no auto-negotiation Port %d\n", Port));
- /* Set DuplexMode in Config register */
- if (pPrt->PLinkMode == SK_LMODE_FULL) {
- Ctrl1 |= PHY_CT_DUP_MD;
- }
-
- /* Determine Master/Slave manually if not already done */
- if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
- Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */
- }
-
- /*
- * Do NOT enable Auto-negotiation here. This would hold
- * the link down because no IDLES are transmitted
- */
- }
- else {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("InitPhyLone: with auto-negotiation Port %d\n", Port));
- /* Set Auto-negotiation advertisement */
-
- /* Set Full/half duplex capabilities */
- switch (pPrt->PLinkMode) {
- case SK_LMODE_AUTOHALF:
- Ctrl2 |= PHY_L_1000C_AHD;
- break;
- case SK_LMODE_AUTOFULL:
- Ctrl2 |= PHY_L_1000C_AFD;
- break;
- case SK_LMODE_AUTOBOTH:
- Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
- SKERR_HWI_E015MSG);
- }
-
- /* Set Flow-control capabilities */
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- Ctrl3 |= PHY_L_P_NO_PAUSE;
- break;
- case SK_FLOW_MODE_LOC_SEND:
- Ctrl3 |= PHY_L_P_ASYM_MD;
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- Ctrl3 |= PHY_L_P_SYM_MD;
- break;
- case SK_FLOW_MODE_SYM_OR_REM:
- Ctrl3 |= PHY_L_P_BOTH_MD;
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
- SKERR_HWI_E016MSG);
- }
-
- /* Restart Auto-negotiation */
- Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
- }
-
- /* Write 1000Base-T Control Register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-
- /* Write AutoNeg Advertisement Register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
-
- if (DoLoop) {
- /* Set the Phy Loopback bit, too */
- Ctrl1 |= PHY_CT_LOOP;
- }
-
- /* Write to the Phy control register */
- SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Control Reg=0x%04X\n", Ctrl1));
-} /* SkXmInitPhyLone */
-
-
-/******************************************************************************
- *
- * SkXmInitPhyNat() - Initialize the National Phy registers
- *
- * Description: initializes all the National Phy registers
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-static void SkXmInitPhyNat(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
-{
-/* todo: National */
-} /* SkXmInitPhyNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- * SkMacInitPhy() - Initialize the PHY registers
- *
- * Description: calls the Init PHY routines dep. on board type
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-void SkMacInitPhy(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
-{
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- switch (pPrt->PhyType) {
- case SK_PHY_XMAC:
- SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
- break;
- case SK_PHY_BCOM:
- SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
- break;
- case SK_PHY_NAT:
- SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
- break;
-#endif /* OTHER_PHY */
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
- }
-#endif /* YUKON */
-
-} /* SkMacInitPhy */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmAutoNegDoneXmac() - Auto-negotiation handling
- *
- * Description:
- * This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- * SK_AND_OK o.k.
- * SK_AND_DUP_CAP Duplex capability error happened
- * SK_AND_OTHER Other error happened
- */
-static int SkXmAutoNegDoneXmac(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U16 ResAb; /* Resolved Ability */
- SK_U16 LPAb; /* Link Partner Ability */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegDoneXmac, Port %d\n", Port));
-
- pPrt = &pAC->GIni.GP[Port];
-
- /* Get PHY parameters */
- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
-
- if ((LPAb & PHY_X_AN_RFB) != 0) {
- /* At least one of the remote fault bit is set */
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Remote fault bit set Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- return(SK_AND_OTHER);
- }
-
- /* Check Duplex mismatch */
- if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
- }
- else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
- }
- else {
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- return(SK_AND_DUP_CAP);
- }
-
- /* Check PAUSE mismatch */
- /* We are NOT using chapter 4.23 of the Xaqti manual */
- /* We are using IEEE 802.3z/D5.0 Table 37-4 */
- if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
- pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
- (LPAb & PHY_X_P_SYM_MD) != 0) {
- /* Symmetric PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
- }
- else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
- (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
- /* Enable PAUSE receive, disable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
- }
- else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
- (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
- /* Disable PAUSE receive, enable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
- }
- else {
- /* PAUSE mismatch -> no PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
- }
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-
- return(SK_AND_OK);
-} /* SkXmAutoNegDoneXmac */
-
-
-/******************************************************************************
- *
- * SkXmAutoNegDoneBcom() - Auto-negotiation handling
- *
- * Description:
- * This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- * SK_AND_OK o.k.
- * SK_AND_DUP_CAP Duplex capability error happened
- * SK_AND_OTHER Other error happened
- */
-static int SkXmAutoNegDoneBcom(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U16 LPAb; /* Link Partner Ability */
- SK_U16 AuxStat; /* Auxiliary Status */
-
-#ifdef TEST_ONLY
-01-Sep-2000 RA;:;:
- SK_U16 ResAb; /* Resolved Ability */
-#endif /* 0 */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegDoneBcom, Port %d\n", Port));
- pPrt = &pAC->GIni.GP[Port];
-
- /* Get PHY parameters */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
-#ifdef TEST_ONLY
-01-Sep-2000 RA;:;:
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-#endif /* 0 */
-
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
-
- if ((LPAb & PHY_B_AN_RF) != 0) {
- /* Remote fault bit is set: Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Remote fault bit set Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- return(SK_AND_OTHER);
- }
-
- /* Check Duplex mismatch */
- if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
- }
- else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
- }
- else {
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- return(SK_AND_DUP_CAP);
- }
-
-#ifdef TEST_ONLY
-01-Sep-2000 RA;:;:
- /* Check Master/Slave resolution */
- if ((ResAb & PHY_B_1000S_MSF) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Master/Slave Fault Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PMSStatus = SK_MS_STAT_FAULT;
- return(SK_AND_OTHER);
- }
-
- pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
- SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-#endif /* 0 */
-
- /* Check PAUSE mismatch ??? */
- /* We are using IEEE 802.3z/D5.0 Table 37-4 */
- if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
- /* Symmetric PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
- }
- else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
- /* Enable PAUSE receive, disable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
- }
- else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
- /* Disable PAUSE receive, enable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
- }
- else {
- /* PAUSE mismatch -> no PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
- }
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-
- return(SK_AND_OK);
-} /* SkXmAutoNegDoneBcom */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmAutoNegDoneMarv() - Auto-negotiation handling
- *
- * Description:
- * This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- * SK_AND_OK o.k.
- * SK_AND_DUP_CAP Duplex capability error happened
- * SK_AND_OTHER Other error happened
- */
-static int SkGmAutoNegDoneMarv(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U16 LPAb; /* Link Partner Ability */
- SK_U16 ResAb; /* Resolved Ability */
- SK_U16 AuxStat; /* Auxiliary Status */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegDoneMarv, Port %d\n", Port));
- pPrt = &pAC->GIni.GP[Port];
-
- /* Get PHY parameters */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Link P.Abil.=0x%04X\n", LPAb));
-
- if ((LPAb & PHY_M_AN_RF) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Remote fault bit set Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- return(SK_AND_OTHER);
- }
-
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-
- /* Check Master/Slave resolution */
- if ((ResAb & PHY_B_1000S_MSF) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Master/Slave Fault Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PMSStatus = SK_MS_STAT_FAULT;
- return(SK_AND_OTHER);
- }
-
- pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
- (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
-
- /* Read PHY Specific Status */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
-
- /* Check Speed & Duplex resolved */
- if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
- return(SK_AND_DUP_CAP);
- }
-
- if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
- }
- else {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
- }
-
- /* Check PAUSE mismatch ??? */
- /* We are using IEEE 802.3z/D5.0 Table 37-4 */
- if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
- /* Symmetric PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
- }
- else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
- /* Enable PAUSE receive, disable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
- }
- else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
- /* Disable PAUSE receive, enable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
- }
- else {
- /* PAUSE mismatch -> no PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
- }
-
- /* set used link speed */
- switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
- case (unsigned)PHY_M_PS_SPEED_1000:
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
- break;
- case PHY_M_PS_SPEED_100:
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
- break;
- default:
- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
- }
-
- return(SK_AND_OK);
-} /* SkGmAutoNegDoneMarv */
-#endif /* YUKON */
-
-
-#ifdef OTHER_PHY
-/******************************************************************************
- *
- * SkXmAutoNegDoneLone() - Auto-negotiation handling
- *
- * Description:
- * This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- * SK_AND_OK o.k.
- * SK_AND_DUP_CAP Duplex capability error happened
- * SK_AND_OTHER Other error happened
- */
-static int SkXmAutoNegDoneLone(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U16 ResAb; /* Resolved Ability */
- SK_U16 LPAb; /* Link Partner Ability */
- SK_U16 QuickStat; /* Auxiliary Status */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegDoneLone, Port %d\n", Port));
- pPrt = &pAC->GIni.GP[Port];
-
- /* Get PHY parameters */
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
-
- if ((LPAb & PHY_L_AN_RF) != 0) {
- /* Remote fault bit is set */
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegFail: Remote fault bit set Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- return(SK_AND_OTHER);
- }
-
- /* Check Duplex mismatch */
- if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
- }
- else {
- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
- }
-
- /* Check Master/Slave resolution */
- if ((ResAb & PHY_L_1000S_MSF) != 0) {
- /* Error */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("Master/Slave Fault Port %d\n", Port));
- pPrt->PAutoNegFail = SK_TRUE;
- pPrt->PMSStatus = SK_MS_STAT_FAULT;
- return(SK_AND_OTHER);
- }
- else if (ResAb & PHY_L_1000S_MSR) {
- pPrt->PMSStatus = SK_MS_STAT_MASTER;
- }
- else {
- pPrt->PMSStatus = SK_MS_STAT_SLAVE;
- }
-
- /* Check PAUSE mismatch */
- /* We are using IEEE 802.3z/D5.0 Table 37-4 */
- /* we must manually resolve the abilities here */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-
- switch (pPrt->PFlowCtrlMode) {
- case SK_FLOW_MODE_NONE:
- /* default */
- break;
- case SK_FLOW_MODE_LOC_SEND:
- if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
- (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
- /* Disable PAUSE receive, enable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
- }
- break;
- case SK_FLOW_MODE_SYMMETRIC:
- if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
- /* Symmetric PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
- }
- break;
- case SK_FLOW_MODE_SYM_OR_REM:
- if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
- PHY_L_QS_AS_PAUSE) {
- /* Enable PAUSE receive, disable PAUSE transmit */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
- }
- else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
- /* Symmetric PAUSE */
- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
- }
- break;
- default:
- SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
- SKERR_HWI_E016MSG);
- }
-
- return(SK_AND_OK);
-} /* SkXmAutoNegDoneLone */
-
-
-/******************************************************************************
- *
- * SkXmAutoNegDoneNat() - Auto-negotiation handling
- *
- * Description:
- * This function handles the auto-negotiation if the Done bit is set.
- *
- * Returns:
- * SK_AND_OK o.k.
- * SK_AND_DUP_CAP Duplex capability error happened
- * SK_AND_OTHER Other error happened
- */
-static int SkXmAutoNegDoneNat(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
-/* todo: National */
- return(SK_AND_OK);
-} /* SkXmAutoNegDoneNat */
-#endif /* OTHER_PHY */
-
-
-/******************************************************************************
- *
- * SkMacAutoNegDone() - Auto-negotiation handling
- *
- * Description: calls the auto-negotiation done routines dep. on board type
- *
- * Returns:
- * SK_AND_OK o.k.
- * SK_AND_DUP_CAP Duplex capability error happened
- * SK_AND_OTHER Other error happened
- */
-int SkMacAutoNegDone(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- int Rtv;
-
- Rtv = SK_AND_OK;
-
- pPrt = &pAC->GIni.GP[Port];
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- switch (pPrt->PhyType) {
-
- case SK_PHY_XMAC:
- Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
- break;
- case SK_PHY_BCOM:
- Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
- break;
- case SK_PHY_NAT:
- Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
- break;
-#endif /* OTHER_PHY */
- default:
- return(SK_AND_OTHER);
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
- }
-#endif /* YUKON */
-
- if (Rtv != SK_AND_OK) {
- return(Rtv);
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNeg done Port %d\n", Port));
-
- /* We checked everything and may now enable the link */
- pPrt->PAutoNegFail = SK_FALSE;
-
- SkMacRxTxEnable(pAC, IoC, Port);
-
- return(SK_AND_OK);
-} /* SkMacAutoNegDone */
-
-
-/******************************************************************************
- *
- * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
- *
- * Description: enables Rx/Tx dep. on board type
- *
- * Returns:
- * 0 o.k.
- * != 0 Error happened
- */
-int SkMacRxTxEnable(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U16 Reg; /* 16-bit register value */
- SK_U16 IntMask; /* MAC interrupt mask */
-#ifdef GENESIS
- SK_U16 SWord;
-#endif
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (!pPrt->PHWLinkUp) {
- /* The Hardware link is NOT up */
- return(0);
- }
-
- if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
- pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
- pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
- pPrt->PAutoNegFail) {
- /* Auto-negotiation is not done or failed */
- return(0);
- }
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* set Duplex Mode and Pause Mode */
- SkXmInitDupMd(pAC, IoC, Port);
-
- SkXmInitPauseMd(pAC, IoC, Port);
-
- /*
- * Initialize the Interrupt Mask Register. Default IRQs are...
- * - Link Asynchronous Event
- * - Link Partner requests config
- * - Auto Negotiation Done
- * - Rx Counter Event Overflow
- * - Tx Counter Event Overflow
- * - Transmit FIFO Underrun
- */
- IntMask = XM_DEF_MSK;
-
-#ifdef DEBUG
- /* add IRQ for Receive FIFO Overflow */
- IntMask &= ~XM_IS_RXF_OV;
-#endif /* DEBUG */
-
- if (pPrt->PhyType != SK_PHY_XMAC) {
- /* disable GP0 interrupt bit */
- IntMask |= XM_IS_INP_ASS;
- }
- XM_OUT16(IoC, Port, XM_IMSK, IntMask);
-
- /* get MMU Command Reg. */
- XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
-
- if (pPrt->PhyType != SK_PHY_XMAC &&
- (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
- pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
- /* set to Full Duplex */
- Reg |= XM_MMU_GMII_FD;
- }
-
- switch (pPrt->PhyType) {
- case SK_PHY_BCOM:
- /*
- * Workaround BCOM Errata (#10523) for all BCom Phys
- * Enable Power Management after link up
- */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
- (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
- (SK_U16)PHY_B_DEF_MSK);
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
- break;
- case SK_PHY_NAT:
- /* todo National:
- SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
- /* no interrupts possible from National ??? */
- break;
-#endif /* OTHER_PHY */
- }
-
- /* enable Rx/Tx */
- XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /*
- * Initialize the Interrupt Mask Register. Default IRQs are...
- * - Rx Counter Event Overflow
- * - Tx Counter Event Overflow
- * - Transmit FIFO Underrun
- */
- IntMask = GMAC_DEF_MSK;
-
-#ifdef DEBUG
- /* add IRQ for Receive FIFO Overrun */
- IntMask |= GM_IS_RX_FF_OR;
-#endif /* DEBUG */
-
- SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
-
- /* get General Purpose Control */
- GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
-
- if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
- pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
- /* set to Full Duplex */
- Reg |= GM_GPCR_DUP_FULL;
- }
-
- /* enable Rx/Tx */
- GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
- GM_GPCR_TX_ENA));
-
-#ifndef VCPU
- /* Enable all PHY interrupts */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
- (SK_U16)PHY_M_DEF_MSK);
-#endif /* VCPU */
- }
-#endif /* YUKON */
-
- return(0);
-
-} /* SkMacRxTxEnable */
-
-
-/******************************************************************************
- *
- * SkMacRxTxDisable() - Disable Receiver and Transmitter
- *
- * Description: disables Rx/Tx dep. on board type
- *
- * Returns: N/A
- */
-void SkMacRxTxDisable(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U16 Word;
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-
- XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
-
- /* dummy read to ensure writing */
- XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
-
- GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
-
- GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
- GM_GPCR_TX_ENA)));
-
- /* dummy read to ensure writing */
- GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
- }
-#endif /* YUKON */
-
-} /* SkMacRxTxDisable */
-
-
-/******************************************************************************
- *
- * SkMacIrqDisable() - Disable IRQ from MAC
- *
- * Description: sets the IRQ-mask to disable IRQ dep. on board type
- *
- * Returns: N/A
- */
-void SkMacIrqDisable(
-SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
-#ifdef GENESIS
- SK_U16 Word;
-#endif
-
- pPrt = &pAC->GIni.GP[Port];
-
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
-
- /* disable all XMAC IRQs */
- XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
-
- /* Disable all PHY interrupts */
- switch (pPrt->PhyType) {
- case SK_PHY_BCOM:
- /* Make sure that PHY is initialized */
- if (pPrt->PState != SK_PRT_RESET) {
- /* NOT allowed if BCOM is in RESET state */
- /* Workaround BCOM Errata (#10523) all BCom */
- /* Disable Power Management if link is down */
- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
- (SK_U16)(Word | PHY_B_AC_DIS_PM));
- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
- }
- break;
-#ifdef OTHER_PHY
- case SK_PHY_LONE:
- SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
- break;
- case SK_PHY_NAT:
- /* todo: National
- SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
- break;
-#endif /* OTHER_PHY */
- }
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* disable all GMAC IRQs */
- SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-
-#ifndef VCPU
- /* Disable all PHY interrupts */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-#endif /* VCPU */
- }
-#endif /* YUKON */
-
-} /* SkMacIrqDisable */
-
-
-#ifdef SK_DIAG
-/******************************************************************************
- *
- * SkXmSendCont() - Enable / Disable Send Continuous Mode
- *
- * Description: enable / disable Send Continuous Mode on XMAC
- *
- * Returns:
- * nothing
- */
-void SkXmSendCont(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL Enable) /* Enable / Disable */
-{
- SK_U32 MdReg;
-
- XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
- if (Enable) {
- MdReg |= XM_MD_TX_CONT;
- }
- else {
- MdReg &= ~XM_MD_TX_CONT;
- }
- /* setup Mode Register */
- XM_OUT32(IoC, Port, XM_MODE, MdReg);
-
-} /* SkXmSendCont */
-
-
-/******************************************************************************
- *
- * SkMacTimeStamp() - Enable / Disable Time Stamp
- *
- * Description: enable / disable Time Stamp generation for Rx packets
- *
- * Returns:
- * nothing
- */
-void SkMacTimeStamp(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL Enable) /* Enable / Disable */
-{
- SK_U32 MdReg;
- SK_U8 TimeCtrl;
-
- if (pAC->GIni.GIGenesis) {
-
- XM_IN32(IoC, Port, XM_MODE, &MdReg);
-
- if (Enable) {
- MdReg |= XM_MD_ATS;
- }
- else {
- MdReg &= ~XM_MD_ATS;
- }
- /* setup Mode Register */
- XM_OUT32(IoC, Port, XM_MODE, MdReg);
- }
- else {
- if (Enable) {
- TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
- }
- else {
- TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
- }
- /* Start/Stop Time Stamp Timer */
- SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl);
- }
-
-} /* SkMacTimeStamp*/
-
-#else /* !SK_DIAG */
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
- *
- * This function analyses the Interrupt status word. If any of the
- * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
- * is set true.
- */
-void SkXmAutoNegLipaXmac(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_U16 IStatus) /* Interrupt Status word to analyse */
-{
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
- (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
- Port, IStatus));
- pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
- }
-} /* SkXmAutoNegLipaXmac */
-#endif /* GENESIS */
-
-
-/******************************************************************************
- *
- * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
- *
- * This function analyses the PHY status word.
- * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
- * is set true.
- */
-void SkMacAutoNegLipaPhy(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_U16 PhyStat) /* PHY Status word to analyse */
-{
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
- (PhyStat & PHY_ST_AN_OVER) != 0) {
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
- Port, PhyStat));
- pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
- }
-} /* SkMacAutoNegLipaPhy */
-
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmIrq() - Interrupt Service Routine
- *
- * Description: services an Interrupt Request of the XMAC
- *
- * Note:
- * With an external PHY, some interrupt bits are not meaningfull any more:
- * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE
- * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC
- * - Page Received (bit #9) XM_IS_RX_PAGE
- * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE
- * - AutoNegDone (bit #7) XM_IS_AND
- * Also probably not valid any more is the GP0 input bit:
- * - GPRegisterBit0set XM_IS_INP_ASS
- *
- * Returns:
- * nothing
- */
-static void SkXmIrq(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_EVPARA Para;
- SK_U16 IStatus; /* Interrupt status read from the XMAC */
- SK_U16 IStatus2;
-#ifdef SK_SLIM
- SK_U64 OverflowStatus;
-#endif
-
- pPrt = &pAC->GIni.GP[Port];
-
- XM_IN16(IoC, Port, XM_ISRC, &IStatus);
-
- /* LinkPartner Auto-negable? */
- if (pPrt->PhyType == SK_PHY_XMAC) {
- SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
- }
- else {
- /* mask bits that are not used with ext. PHY */
- IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
- XM_IS_RX_PAGE | XM_IS_TX_PAGE |
- XM_IS_AND | XM_IS_INP_ASS);
- }
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
-
- if (!pPrt->PHWLinkUp) {
- /* Spurious XMAC interrupt */
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("SkXmIrq: spurious interrupt on Port %d\n", Port));
- return;
- }
-
- if ((IStatus & XM_IS_INP_ASS) != 0) {
- /* Reread ISR Register if link is not in sync */
- XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n",
- Port, IStatus, IStatus2));
- IStatus &= ~XM_IS_INP_ASS;
- IStatus |= IStatus2;
- }
-
- if ((IStatus & XM_IS_LNK_AE) != 0) {
- /* not used, GP0 is used instead */
- }
-
- if ((IStatus & XM_IS_TX_ABORT) != 0) {
- /* not used */
- }
-
- if ((IStatus & XM_IS_FRC_INT) != 0) {
- /* not used, use ASIC IRQ instead if needed */
- }
-
- if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
- SkHWLinkDown(pAC, IoC, Port);
-
- /* Signal to RLMT */
- Para.Para32[0] = (SK_U32)Port;
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
-
- /* Start workaround Errata #2 timer */
- SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
- SKGE_HWAC, SK_HWEV_WATIM, Para);
- }
-
- if ((IStatus & XM_IS_RX_PAGE) != 0) {
- /* not used */
- }
-
- if ((IStatus & XM_IS_TX_PAGE) != 0) {
- /* not used */
- }
-
- if ((IStatus & XM_IS_AND) != 0) {
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("SkXmIrq: AND on link that is up Port %d\n", Port));
- }
-
- if ((IStatus & XM_IS_TSC_OV) != 0) {
- /* not used */
- }
-
- /* Combined Tx & Rx Counter Overflow SIRQ Event */
- if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
-#ifdef SK_SLIM
- SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
-#else
- Para.Para32[0] = (SK_U32)Port;
- Para.Para32[1] = (SK_U32)IStatus;
- SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-#endif /* SK_SLIM */
- }
-
- if ((IStatus & XM_IS_RXF_OV) != 0) {
- /* normal situation -> no effect */
-#ifdef DEBUG
- pPrt->PRxOverCnt++;
-#endif /* DEBUG */
- }
-
- if ((IStatus & XM_IS_TXF_UR) != 0) {
- /* may NOT happen -> error log */
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
- }
-
- if ((IStatus & XM_IS_TX_COMP) != 0) {
- /* not served here */
- }
-
- if ((IStatus & XM_IS_RX_COMP) != 0) {
- /* not served here */
- }
-} /* SkXmIrq */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmIrq() - Interrupt Service Routine
- *
- * Description: services an Interrupt Request of the GMAC
- *
- * Note:
- *
- * Returns:
- * nothing
- */
-static void SkGmIrq(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U8 IStatus; /* Interrupt status */
-#ifdef SK_SLIM
- SK_U64 OverflowStatus;
-#else
- SK_EVPARA Para;
-#endif
-
- pPrt = &pAC->GIni.GP[Port];
-
- SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
-
-#ifdef XXX
- /* LinkPartner Auto-negable? */
- SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
-#endif /* XXX */
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
- ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
-
- /* Combined Tx & Rx Counter Overflow SIRQ Event */
- if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
- /* these IRQs will be cleared by reading GMACs register */
-#ifdef SK_SLIM
- SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
-#else
- Para.Para32[0] = (SK_U32)Port;
- Para.Para32[1] = (SK_U32)IStatus;
- SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-#endif
- }
-
- if (IStatus & GM_IS_RX_FF_OR) {
- /* clear GMAC Rx FIFO Overrun IRQ */
- SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
-#ifdef DEBUG
- pPrt->PRxOverCnt++;
-#endif /* DEBUG */
- }
-
- if (IStatus & GM_IS_TX_FF_UR) {
- /* clear GMAC Tx FIFO Underrun IRQ */
- SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
- /* may NOT happen -> error log */
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
- }
-
- if (IStatus & GM_IS_TX_COMPL) {
- /* not served here */
- }
-
- if (IStatus & GM_IS_RX_COMPL) {
- /* not served here */
- }
-} /* SkGmIrq */
-#endif /* YUKON */
-
-
-/******************************************************************************
- *
- * SkMacIrq() - Interrupt Service Routine for MAC
- *
- * Description: calls the Interrupt Service Routine dep. on board type
- *
- * Returns:
- * nothing
- */
-void SkMacIrq(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port) /* Port Index (MAC_1 + n) */
-{
-#ifdef GENESIS
- if (pAC->GIni.GIGenesis) {
- /* IRQ from XMAC */
- SkXmIrq(pAC, IoC, Port);
- }
-#endif /* GENESIS */
-
-#ifdef YUKON
- if (pAC->GIni.GIYukon) {
- /* IRQ from GMAC */
- SkGmIrq(pAC, IoC, Port);
- }
-#endif /* YUKON */
-
-} /* SkMacIrq */
-
-#endif /* !SK_DIAG */
-
-#ifdef GENESIS
-/******************************************************************************
- *
- * SkXmUpdateStats() - Force the XMAC to output the current statistic
- *
- * Description:
- * The XMAC holds its statistic internally. To obtain the current
- * values a command must be sent so that the statistic data will
- * be written to a predefined memory area on the adapter.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkXmUpdateStats(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port) /* Port Index (MAC_1 + n) */
-{
- SK_GEPORT *pPrt;
- SK_U16 StatReg;
- int WaitIndex;
-
- pPrt = &pAC->GIni.GP[Port];
- WaitIndex = 0;
-
- /* Send an update command to XMAC specified */
- XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
-
- /*
- * It is an auto-clearing register. If the command bits
- * went to zero again, the statistics are transferred.
- * Normally the command should be executed immediately.
- * But just to be sure we execute a loop.
- */
- do {
-
- XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
-
- if (++WaitIndex > 10) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
-
- return(1);
- }
- } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
-
- return(0);
-} /* SkXmUpdateStats */
-
-
-/******************************************************************************
- *
- * SkXmMacStatistic() - Get XMAC counter value
- *
- * Description:
- * Gets the 32bit counter value. Except for the octet counters
- * the lower 32bit are counted in hardware and the upper 32bit
- * must be counted in software by monitoring counter overflow interrupts.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkXmMacStatistic(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port, /* Port Index (MAC_1 + n) */
-SK_U16 StatAddr, /* MIB counter base address */
-SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
-{
- if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-
- return(1);
- }
-
- XM_IN32(IoC, Port, StatAddr, pVal);
-
- return(0);
-} /* SkXmMacStatistic */
-
-
-/******************************************************************************
- *
- * SkXmResetCounter() - Clear MAC statistic counter
- *
- * Description:
- * Force the XMAC to clear its statistic counter.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkXmResetCounter(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port) /* Port Index (MAC_1 + n) */
-{
- XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
- /* Clear two times according to Errata #3 */
- XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-
- return(0);
-} /* SkXmResetCounter */
-
-
-/******************************************************************************
- *
- * SkXmOverflowStatus() - Gets the status of counter overflow interrupt
- *
- * Description:
- * Checks the source causing an counter overflow interrupt. On success the
- * resulting counter overflow status is written to <pStatus>, whereas the
- * upper dword stores the XMAC ReceiveCounterEvent register and the lower
- * dword the XMAC TransmitCounterEvent register.
- *
- * Note:
- * For XMAC the interrupt source is a self-clearing register, so the source
- * must be checked only once. SIRQ module does another check to be sure
- * that no interrupt get lost during process time.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkXmOverflowStatus(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port, /* Port Index (MAC_1 + n) */
-SK_U16 IStatus, /* Interupt Status from MAC */
-SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
-{
- SK_U64 Status; /* Overflow status */
- SK_U32 RegVal;
-
- Status = 0;
-
- if ((IStatus & XM_IS_RXC_OV) != 0) {
-
- XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
- Status |= (SK_U64)RegVal << 32;
- }
-
- if ((IStatus & XM_IS_TXC_OV) != 0) {
-
- XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
- Status |= (SK_U64)RegVal;
- }
-
- *pStatus = Status;
-
- return(0);
-} /* SkXmOverflowStatus */
-#endif /* GENESIS */
-
-
-#ifdef YUKON
-/******************************************************************************
- *
- * SkGmUpdateStats() - Force the GMAC to output the current statistic
- *
- * Description:
- * Empty function for GMAC. Statistic data is accessible in direct way.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkGmUpdateStats(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port) /* Port Index (MAC_1 + n) */
-{
- return(0);
-}
-
-
-/******************************************************************************
- *
- * SkGmMacStatistic() - Get GMAC counter value
- *
- * Description:
- * Gets the 32bit counter value. Except for the octet counters
- * the lower 32bit are counted in hardware and the upper 32bit
- * must be counted in software by monitoring counter overflow interrupts.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkGmMacStatistic(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port, /* Port Index (MAC_1 + n) */
-SK_U16 StatAddr, /* MIB counter base address */
-SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
-{
-
- if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
-
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
- return(1);
- }
-
- GM_IN32(IoC, Port, StatAddr, pVal);
-
- return(0);
-} /* SkGmMacStatistic */
-
-
-/******************************************************************************
- *
- * SkGmResetCounter() - Clear MAC statistic counter
- *
- * Description:
- * Force GMAC to clear its statistic counter.
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkGmResetCounter(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port) /* Port Index (MAC_1 + n) */
-{
- SK_U16 Reg; /* Phy Address Register */
- SK_U16 Word;
- int i;
-
- GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
-
- /* set MIB Clear Counter Mode */
- GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
-
- /* read all MIB Counters with Clear Mode set */
- for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
- /* the reset is performed only when the lower 16 bits are read */
- GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
- }
-
- /* clear MIB Clear Counter Mode */
- GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
-
- return(0);
-} /* SkGmResetCounter */
-
-
-/******************************************************************************
- *
- * SkGmOverflowStatus() - Gets the status of counter overflow interrupt
- *
- * Description:
- * Checks the source causing an counter overflow interrupt. On success the
- * resulting counter overflow status is written to <pStatus>, whereas the
- * the following bit coding is used:
- * 63:56 - unused
- * 55:48 - TxRx interrupt register bit7:0
- * 32:47 - Rx interrupt register
- * 31:24 - unused
- * 23:16 - TxRx interrupt register bit15:8
- * 15:0 - Tx interrupt register
- *
- * Returns:
- * 0: success
- * 1: something went wrong
- */
-int SkGmOverflowStatus(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-unsigned int Port, /* Port Index (MAC_1 + n) */
-SK_U16 IStatus, /* Interupt Status from MAC */
-SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
-{
- SK_U64 Status; /* Overflow status */
- SK_U16 RegVal;
-
- Status = 0;
-
- if ((IStatus & GM_IS_RX_CO_OV) != 0) {
- /* this register is self-clearing after read */
- GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
- Status |= (SK_U64)RegVal << 32;
- }
-
- if ((IStatus & GM_IS_TX_CO_OV) != 0) {
- /* this register is self-clearing after read */
- GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
- Status |= (SK_U64)RegVal;
- }
-
- /* this register is self-clearing after read */
- GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
- /* Rx overflow interrupt register bits (LoByte)*/
- Status |= (SK_U64)((SK_U8)RegVal) << 48;
- /* Tx overflow interrupt register bits (HiByte)*/
- Status |= (SK_U64)(RegVal >> 8) << 16;
-
- *pStatus = Status;
-
- return(0);
-} /* SkGmOverflowStatus */
-
-
-#ifndef SK_SLIM
-/******************************************************************************
- *
- * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
- *
- * Description:
- * starts the cable diagnostic test if 'StartTest' is true
- * gets the results if 'StartTest' is true
- *
- * NOTE: this test is meaningful only when link is down
- *
- * Returns:
- * 0: success
- * 1: no YUKON copper
- * 2: test in progress
- */
-int SkGmCableDiagStatus(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
-SK_BOOL StartTest) /* flag for start / get result */
-{
- int i;
- SK_U16 RegVal;
- SK_GEPORT *pPrt;
-
- pPrt = &pAC->GIni.GP[Port];
-
- if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-
- return(1);
- }
-
- if (StartTest) {
- /* only start the cable test */
- if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
- /* apply TDR workaround from Marvell */
- SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
-
- SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
- }
-
- /* set address to 0 for MDI[0] */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
-
- /* Read Cable Diagnostic Reg */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
- /* start Cable Diagnostic Test */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
- (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
-
- return(0);
- }
-
- /* Read Cable Diagnostic Reg */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
- ("PHY Cable Diag.=0x%04X\n", RegVal));
-
- if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
- /* test is running */
- return(2);
- }
-
- /* get the test results */
- for (i = 0; i < 4; i++) {
- /* set address to i for MDI[i] */
- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
-
- /* get Cable Diagnostic values */
- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
-
- pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
-
- pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
- }
-
- return(0);
-} /* SkGmCableDiagStatus */
-#endif /* !SK_SLIM */
-#endif /* YUKON */
-
-/* End of file */
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index b51d73c8f817..a2f32151559e 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -39,6 +39,7 @@
#include <linux/workqueue.h>
#include <linux/if_vlan.h>
#include <linux/prefetch.h>
+#include <linux/debugfs.h>
#include <linux/mii.h>
#include <asm/irq.h>
@@ -50,7 +51,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.15"
+#define DRV_VERSION "1.16"
#define PFX DRV_NAME " "
/*
@@ -64,7 +65,6 @@
#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2)
#define RX_DEF_PENDING RX_MAX_PENDING
#define RX_SKB_ALIGN 8
-#define RX_BUF_WRITE 16
#define TX_RING_SIZE 512
#define TX_DEF_PENDING (TX_RING_SIZE - 1)
@@ -77,6 +77,9 @@
#define NAPI_WEIGHT 64
#define PHY_RETRIES 1000
+#define SKY2_EEPROM_MAGIC 0x9955aabb
+
+
#define RING_NEXT(x,s) (((x)+1) & ((s)-1))
static const u32 default_msg =
@@ -96,7 +99,7 @@ static int disable_msi = 0;
module_param(disable_msi, int, 0);
MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
-static int idle_timeout = 0;
+static int idle_timeout = 100;
module_param(idle_timeout, int, 0);
MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
@@ -890,24 +893,18 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
return le;
}
-/* Return high part of DMA address (could be 32 or 64 bit) */
-static inline u32 high32(dma_addr_t a)
-{
- return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
-}
-
/* Build description to hardware for one receive segment */
static void sky2_rx_add(struct sky2_port *sky2, u8 op,
dma_addr_t map, unsigned len)
{
struct sky2_rx_le *le;
- u32 hi = high32(map);
+ u32 hi = upper_32_bits(map);
if (sky2->rx_addr64 != hi) {
le = sky2_next_rx(sky2);
le->addr = cpu_to_le32(hi);
le->opcode = OP_ADDR64 | HW_OWNER;
- sky2->rx_addr64 = high32(map + len);
+ sky2->rx_addr64 = upper_32_bits(map + len);
}
le = sky2_next_rx(sky2);
@@ -1137,6 +1134,11 @@ nomem:
return NULL;
}
+static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
+{
+ sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
+}
+
/*
* Allocate and setup receiver buffer pool.
* Normal case this ends up creating one list element for skb
@@ -1172,8 +1174,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
rx_set_checksum(sky2);
/* Space needed for frame data + headers rounded up */
- size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
- + 8;
+ size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
/* Stopping point for hardware truncation */
thresh = (size - 8) / sizeof(u32);
@@ -1228,7 +1229,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
}
/* Tell chip about available buffers */
- sky2_put_idx(hw, rxq, sky2->rx_put);
+ sky2_rx_update(sky2, rxq);
return 0;
nomem:
sky2_rx_clean(sky2);
@@ -1265,6 +1266,8 @@ static int sky2_up(struct net_device *dev)
if (netif_msg_ifup(sky2))
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+ netif_carrier_off(dev);
+
/* must be power of 2 */
sky2->tx_le = pci_alloc_consistent(hw->pdev,
TX_RING_SIZE *
@@ -1415,14 +1418,15 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
len = skb_headlen(skb);
mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
- addr64 = high32(mapping);
+ addr64 = upper_32_bits(mapping);
/* Send high bits if changed or crosses boundary */
- if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+ if (addr64 != sky2->tx_addr64 ||
+ upper_32_bits(mapping + len) != sky2->tx_addr64) {
le = get_tx_le(sky2);
le->addr = cpu_to_le32(addr64);
le->opcode = OP_ADDR64 | HW_OWNER;
- sky2->tx_addr64 = high32(mapping + len);
+ sky2->tx_addr64 = upper_32_bits(mapping + len);
}
/* Check for TCP Segmentation Offload */
@@ -1502,7 +1506,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
- addr64 = high32(mapping);
+ addr64 = upper_32_bits(mapping);
if (addr64 != sky2->tx_addr64) {
le = get_tx_le(sky2);
le->addr = cpu_to_le32(addr64);
@@ -1572,13 +1576,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
if (unlikely(netif_msg_tx_done(sky2)))
printk(KERN_DEBUG "%s: tx done %u\n",
dev->name, idx);
+
sky2->net_stats.tx_packets++;
sky2->net_stats.tx_bytes += re->skb->len;
dev_kfree_skb_any(re->skb);
+ sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE);
}
-
- le->opcode = 0; /* paranoia */
}
sky2->tx_cons = idx;
@@ -1616,7 +1620,6 @@ static int sky2_down(struct net_device *dev)
/* Stop more packets from being queued */
netif_stop_queue(dev);
- netif_carrier_off(dev);
/* Disable port IRQ */
imask = sky2_read32(hw, B0_IMSK);
@@ -1668,6 +1671,8 @@ static int sky2_down(struct net_device *dev)
sky2_phy_power(hw, port, 0);
+ netif_carrier_off(dev);
+
/* turn off LED's */
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
@@ -1732,7 +1737,6 @@ static void sky2_link_up(struct sky2_port *sky2)
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
netif_carrier_on(sky2->netdev);
- netif_wake_queue(sky2->netdev);
/* Turn on link LED */
sky2_write8(hw, SK_REG(port, LNK_LED_REG),
@@ -1784,7 +1788,6 @@ static void sky2_link_down(struct sky2_port *sky2)
gma_write16(hw, port, GM_GP_CTRL, reg);
netif_carrier_off(sky2->netdev);
- netif_stop_queue(sky2->netdev);
/* Turn on link LED */
sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
@@ -2055,8 +2058,6 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
struct sk_buff *skb, *nskb;
unsigned hdr_space = sky2->rx_data_size;
- pr_debug(PFX "receive new length=%d\n", length);
-
/* Don't be tricky about reusing pages (yet) */
nskb = sky2_rx_alloc(sky2);
if (unlikely(!nskb))
@@ -2100,6 +2101,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
if (!(status & GMR_FS_RX_OK))
goto resubmit;
+ if (status >> 16 != length)
+ goto len_mismatch;
+
if (length < copybreak)
skb = receive_copy(sky2, re, length);
else
@@ -2109,6 +2113,11 @@ resubmit:
return skb;
+len_mismatch:
+ /* Truncation of overlength packets
+ causes PHY length to not match MAC length */
+ ++sky2->net_stats.rx_length_errors;
+
error:
++sky2->net_stats.rx_errors;
if (status & GMR_FS_RX_FF_OV) {
@@ -2145,14 +2154,14 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
/* Process status response ring */
static int sky2_status_intr(struct sky2_hw *hw, int to_do)
{
- struct sky2_port *sky2;
int work_done = 0;
- unsigned buf_write[2] = { 0, 0 };
+ unsigned rx[2] = { 0, 0 };
u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
rmb();
while (hw->st_idx != hwidx) {
+ struct sky2_port *sky2;
struct sky2_status_le *le = hw->st_le + hw->st_idx;
unsigned port = le->css & CSS_LINK_BIT;
struct net_device *dev;
@@ -2169,10 +2178,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
switch (le->opcode & ~HW_OWNER) {
case OP_RXSTAT:
+ ++rx[port];
skb = sky2_receive(dev, length, status);
if (unlikely(!skb)) {
sky2->net_stats.rx_dropped++;
- goto force_update;
+ break;
}
/* This chip reports checksum status differently */
@@ -2199,13 +2209,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
#endif
netif_receive_skb(skb);
- /* Update receiver after 16 frames */
- if (++buf_write[port] == RX_BUF_WRITE) {
-force_update:
- sky2_put_idx(hw, rxqaddr[port], sky2->rx_put);
- buf_write[port] = 0;
- }
-
/* Stop after net poll weight */
if (++work_done >= to_do)
goto exit_loop;
@@ -2261,24 +2264,18 @@ force_update:
if (net_ratelimit())
printk(KERN_WARNING PFX
"unknown status opcode 0x%x\n", le->opcode);
- goto exit_loop;
}
}
/* Fully processed status ring so clear irq */
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
- mmiowb();
exit_loop:
- if (buf_write[0]) {
- sky2 = netdev_priv(hw->dev[0]);
- sky2_put_idx(hw, Q_R1, sky2->rx_put);
- }
+ if (rx[0])
+ sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1);
- if (buf_write[1]) {
- sky2 = netdev_priv(hw->dev[1]);
- sky2_put_idx(hw, Q_R2, sky2->rx_put);
- }
+ if (rx[1])
+ sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2);
return work_done;
}
@@ -2475,8 +2472,7 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
static int sky2_poll(struct net_device *dev0, int *budget)
{
struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
- int work_limit = min(dev0->quota, *budget);
- int work_done = 0;
+ int work_done;
u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
if (unlikely(status & Y2_IS_ERROR))
@@ -2488,18 +2484,25 @@ static int sky2_poll(struct net_device *dev0, int *budget)
if (status & Y2_IS_IRQ_PHY2)
sky2_phy_intr(hw, 1);
- work_done = sky2_status_intr(hw, work_limit);
- if (work_done < work_limit) {
- netif_rx_complete(dev0);
+ work_done = sky2_status_intr(hw, min(dev0->quota, *budget));
+ *budget -= work_done;
+ dev0->quota -= work_done;
- /* end of interrupt, re-enables also acts as I/O synchronization */
- sky2_read32(hw, B0_Y2_SP_LISR);
- return 0;
- } else {
- *budget -= work_done;
- dev0->quota -= work_done;
+ /* More work? */
+ if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX))
return 1;
+
+ /* Bug/Errata workaround?
+ * Need to kick the TX irq moderation timer.
+ */
+ if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
+ sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+ sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
}
+ netif_rx_complete(dev0);
+
+ sky2_read32(hw, B0_Y2_SP_LISR);
+ return 0;
}
static irqreturn_t sky2_intr(int irq, void *dev_id)
@@ -2723,8 +2726,6 @@ static void sky2_restart(struct work_struct *work)
struct net_device *dev;
int i, err;
- dev_dbg(&hw->pdev->dev, "restarting\n");
-
del_timer_sync(&hw->idle_timer);
rtnl_lock();
@@ -3429,39 +3430,315 @@ static int sky2_set_tso(struct net_device *dev, u32 data)
return ethtool_op_set_tso(dev, data);
}
+static int sky2_get_eeprom_len(struct net_device *dev)
+{
+ struct sky2_port *sky2 = netdev_priv(dev);
+ u16 reg2;
+
+ reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2);
+ return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+}
+
+static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset)
+{
+ sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+
+ while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F))
+ cpu_relax();
+ return sky2_pci_read32(hw, cap + PCI_VPD_DATA);
+}
+
+static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val)
+{
+ sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
+ sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
+ do {
+ cpu_relax();
+ } while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F);
+}
+
+static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+ u8 *data)
+{
+ struct sky2_port *sky2 = netdev_priv(dev);
+ int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+ int length = eeprom->len;
+ u16 offset = eeprom->offset;
+
+ if (!cap)
+ return -EINVAL;
+
+ eeprom->magic = SKY2_EEPROM_MAGIC;
+
+ while (length > 0) {
+ u32 val = sky2_vpd_read(sky2->hw, cap, offset);
+ int n = min_t(int, length, sizeof(val));
+
+ memcpy(data, &val, n);
+ length -= n;
+ data += n;
+ offset += n;
+ }
+ return 0;
+}
+
+static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+ u8 *data)
+{
+ struct sky2_port *sky2 = netdev_priv(dev);
+ int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+ int length = eeprom->len;
+ u16 offset = eeprom->offset;
+
+ if (!cap)
+ return -EINVAL;
+
+ if (eeprom->magic != SKY2_EEPROM_MAGIC)
+ return -EINVAL;
+
+ while (length > 0) {
+ u32 val;
+ int n = min_t(int, length, sizeof(val));
+
+ if (n < sizeof(val))
+ val = sky2_vpd_read(sky2->hw, cap, offset);
+ memcpy(&val, data, n);
+
+ sky2_vpd_write(sky2->hw, cap, offset, val);
+
+ length -= n;
+ data += n;
+ offset += n;
+ }
+ return 0;
+}
+
+
static const struct ethtool_ops sky2_ethtool_ops = {
- .get_settings = sky2_get_settings,
- .set_settings = sky2_set_settings,
- .get_drvinfo = sky2_get_drvinfo,
- .get_wol = sky2_get_wol,
- .set_wol = sky2_set_wol,
- .get_msglevel = sky2_get_msglevel,
- .set_msglevel = sky2_set_msglevel,
- .nway_reset = sky2_nway_reset,
- .get_regs_len = sky2_get_regs_len,
- .get_regs = sky2_get_regs,
- .get_link = ethtool_op_get_link,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = sky2_set_tx_csum,
- .get_tso = ethtool_op_get_tso,
- .set_tso = sky2_set_tso,
- .get_rx_csum = sky2_get_rx_csum,
- .set_rx_csum = sky2_set_rx_csum,
- .get_strings = sky2_get_strings,
- .get_coalesce = sky2_get_coalesce,
- .set_coalesce = sky2_set_coalesce,
- .get_ringparam = sky2_get_ringparam,
- .set_ringparam = sky2_set_ringparam,
+ .get_settings = sky2_get_settings,
+ .set_settings = sky2_set_settings,
+ .get_drvinfo = sky2_get_drvinfo,
+ .get_wol = sky2_get_wol,
+ .set_wol = sky2_set_wol,
+ .get_msglevel = sky2_get_msglevel,
+ .set_msglevel = sky2_set_msglevel,
+ .nway_reset = sky2_nway_reset,
+ .get_regs_len = sky2_get_regs_len,
+ .get_regs = sky2_get_regs,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = sky2_get_eeprom_len,
+ .get_eeprom = sky2_get_eeprom,
+ .set_eeprom = sky2_set_eeprom,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = sky2_set_tx_csum,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = sky2_set_tso,
+ .get_rx_csum = sky2_get_rx_csum,
+ .set_rx_csum = sky2_set_rx_csum,
+ .get_strings = sky2_get_strings,
+ .get_coalesce = sky2_get_coalesce,
+ .set_coalesce = sky2_set_coalesce,
+ .get_ringparam = sky2_get_ringparam,
+ .set_ringparam = sky2_set_ringparam,
.get_pauseparam = sky2_get_pauseparam,
.set_pauseparam = sky2_set_pauseparam,
- .phys_id = sky2_phys_id,
+ .phys_id = sky2_phys_id,
.get_stats_count = sky2_get_stats_count,
.get_ethtool_stats = sky2_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
+#ifdef CONFIG_SKY2_DEBUG
+
+static struct dentry *sky2_debug;
+
+static int sky2_debug_show(struct seq_file *seq, void *v)
+{
+ struct net_device *dev = seq->private;
+ const struct sky2_port *sky2 = netdev_priv(dev);
+ const struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
+ unsigned idx, last;
+ int sop;
+
+ if (!netif_running(dev))
+ return -ENETDOWN;
+
+ seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+ sky2_read32(hw, B0_ISRC),
+ sky2_read32(hw, B0_IMSK),
+ sky2_read32(hw, B0_Y2_SP_ICR));
+
+ netif_poll_disable(hw->dev[0]);
+ last = sky2_read16(hw, STAT_PUT_IDX);
+
+ if (hw->st_idx == last)
+ seq_puts(seq, "Status ring (empty)\n");
+ else {
+ seq_puts(seq, "Status ring\n");
+ for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE;
+ idx = RING_NEXT(idx, STATUS_RING_SIZE)) {
+ const struct sky2_status_le *le = hw->st_le + idx;
+ seq_printf(seq, "[%d] %#x %d %#x\n",
+ idx, le->opcode, le->length, le->status);
+ }
+ seq_puts(seq, "\n");
+ }
+
+ seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n",
+ sky2->tx_cons, sky2->tx_prod,
+ sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
+ sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE)));
+
+ /* Dump contents of tx ring */
+ sop = 1;
+ for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE;
+ idx = RING_NEXT(idx, TX_RING_SIZE)) {
+ const struct sky2_tx_le *le = sky2->tx_le + idx;
+ u32 a = le32_to_cpu(le->addr);
+
+ if (sop)
+ seq_printf(seq, "%u:", idx);
+ sop = 0;
+
+ switch(le->opcode & ~HW_OWNER) {
+ case OP_ADDR64:
+ seq_printf(seq, " %#x:", a);
+ break;
+ case OP_LRGLEN:
+ seq_printf(seq, " mtu=%d", a);
+ break;
+ case OP_VLAN:
+ seq_printf(seq, " vlan=%d", be16_to_cpu(le->length));
+ break;
+ case OP_TCPLISW:
+ seq_printf(seq, " csum=%#x", a);
+ break;
+ case OP_LARGESEND:
+ seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length));
+ break;
+ case OP_PACKET:
+ seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length));
+ break;
+ case OP_BUFFER:
+ seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length));
+ break;
+ default:
+ seq_printf(seq, " op=%#x,%#x(%d)", le->opcode,
+ a, le16_to_cpu(le->length));
+ }
+
+ if (le->ctrl & EOP) {
+ seq_putc(seq, '\n');
+ sop = 1;
+ }
+ }
+
+ seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
+ sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
+ last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
+ sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
+
+ netif_poll_enable(hw->dev[0]);
+ return 0;
+}
+
+static int sky2_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sky2_debug_show, inode->i_private);
+}
+
+static const struct file_operations sky2_debug_fops = {
+ .owner = THIS_MODULE,
+ .open = sky2_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/*
+ * Use network device events to create/remove/rename
+ * debugfs file entries
+ */
+static int sky2_device_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = ptr;
+
+ if (dev->open == sky2_up) {
+ struct sky2_port *sky2 = netdev_priv(dev);
+
+ switch(event) {
+ case NETDEV_CHANGENAME:
+ if (!netif_running(dev))
+ break;
+ /* fallthrough */
+ case NETDEV_DOWN:
+ case NETDEV_GOING_DOWN:
+ if (sky2->debugfs) {
+ printk(KERN_DEBUG PFX "%s: remove debugfs\n",
+ dev->name);
+ debugfs_remove(sky2->debugfs);
+ sky2->debugfs = NULL;
+ }
+
+ if (event != NETDEV_CHANGENAME)
+ break;
+ /* fallthrough for changename */
+ case NETDEV_UP:
+ if (sky2_debug) {
+ struct dentry *d;
+ d = debugfs_create_file(dev->name, S_IRUGO,
+ sky2_debug, dev,
+ &sky2_debug_fops);
+ if (d == NULL || IS_ERR(d))
+ printk(KERN_INFO PFX
+ "%s: debugfs create failed\n",
+ dev->name);
+ else
+ sky2->debugfs = d;
+ }
+ break;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block sky2_notifier = {
+ .notifier_call = sky2_device_event,
+};
+
+
+static __init void sky2_debug_init(void)
+{
+ struct dentry *ent;
+
+ ent = debugfs_create_dir("sky2", NULL);
+ if (!ent || IS_ERR(ent))
+ return;
+
+ sky2_debug = ent;
+ register_netdevice_notifier(&sky2_notifier);
+}
+
+static __exit void sky2_debug_cleanup(void)
+{
+ if (sky2_debug) {
+ unregister_netdevice_notifier(&sky2_notifier);
+ debugfs_remove(sky2_debug);
+ sky2_debug = NULL;
+ }
+}
+
+#else
+#define sky2_debug_init()
+#define sky2_debug_cleanup()
+#endif
+
+
/* Initialize network device */
static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
unsigned port,
@@ -3536,10 +3813,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- /* device is off until link detection */
- netif_carrier_off(dev);
- netif_stop_queue(dev);
-
return dev;
}
@@ -3956,12 +4229,14 @@ static struct pci_driver sky2_driver = {
static int __init sky2_init_module(void)
{
+ sky2_debug_init();
return pci_register_driver(&sky2_driver);
}
static void __exit sky2_cleanup_module(void)
{
pci_unregister_driver(&sky2_driver);
+ sky2_debug_cleanup();
}
module_init(sky2_init_module);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 8df4643493d1..dce4d276d443 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1998,6 +1998,7 @@ struct sky2_port {
struct sky2_tx_le *tx_le;
u16 tx_cons; /* next le to check */
u16 tx_prod; /* next le to use */
+ u16 tx_next; /* debug only */
u32 tx_addr64;
u16 tx_pending;
u16 tx_last_mss;
@@ -2028,6 +2029,9 @@ struct sky2_port {
enum flow_control flow_mode;
enum flow_control flow_status;
+#ifdef CONFIG_SKY2_DEBUG
+ struct dentry *debugfs;
+#endif
struct net_device_stats net_stats;
};
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index f5abb5279d4d..590b12c7246c 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1441,11 +1441,17 @@ static void
spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
{
u32 error_reg1, error_reg2;
+ u32 mask_reg1, mask_reg2;
u32 i;
int show_error = 1;
error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
+ mask_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1MSK);
+ mask_reg2 = spider_net_read_reg(card,SPIDER_NET_GHIINT2MSK);
+
+ error_reg1 &= mask_reg1;
+ error_reg2 &= mask_reg2;
/* check GHIINT0STS ************************************/
if (status_reg)
@@ -1673,9 +1679,11 @@ spider_net_interrupt(int irq, void *ptr)
{
struct net_device *netdev = ptr;
struct spider_net_card *card = netdev_priv(netdev);
- u32 status_reg;
+ u32 status_reg, mask_reg;
status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
+ mask_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
+ status_reg &= mask_reg;
if (!status_reg)
return IRQ_NONE;
@@ -1717,6 +1725,38 @@ spider_net_poll_controller(struct net_device *netdev)
#endif /* CONFIG_NET_POLL_CONTROLLER */
/**
+ * spider_net_enable_interrupts - enable interrupts
+ * @card: card structure
+ *
+ * spider_net_enable_interrupt enables several interrupts
+ */
+static void
+spider_net_enable_interrupts(struct spider_net_card *card)
+{
+ spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
+ SPIDER_NET_INT0_MASK_VALUE);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
+ SPIDER_NET_INT1_MASK_VALUE);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
+ SPIDER_NET_INT2_MASK_VALUE);
+}
+
+/**
+ * spider_net_disable_interrupts - disable interrupts
+ * @card: card structure
+ *
+ * spider_net_disable_interrupts disables all the interrupts
+ */
+static void
+spider_net_disable_interrupts(struct spider_net_card *card)
+{
+ spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+ spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+}
+
+/**
* spider_net_init_card - initializes the card
* @card: card structure
*
@@ -1736,6 +1776,7 @@ spider_net_init_card(struct spider_net_card *card)
spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
+ spider_net_disable_interrupts(card);
}
/**
@@ -1823,14 +1864,6 @@ spider_net_enable_card(struct spider_net_card *card)
spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
SPIDER_NET_OPMODE_VALUE);
- /* set interrupt mask registers */
- spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
- SPIDER_NET_INT0_MASK_VALUE);
- spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
- SPIDER_NET_INT1_MASK_VALUE);
- spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
- SPIDER_NET_INT2_MASK_VALUE);
-
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_GDTBSTA);
}
@@ -2007,6 +2040,8 @@ spider_net_open(struct net_device *netdev)
netif_carrier_on(netdev);
netif_poll_enable(netdev);
+ spider_net_enable_interrupts(card);
+
return 0;
register_int_failed:
@@ -2179,11 +2214,7 @@ spider_net_stop(struct net_device *netdev)
del_timer_sync(&card->tx_timer);
del_timer_sync(&card->aneg_timer);
- /* disable/mask all interrupts */
- spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
- spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
- spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+ spider_net_disable_interrupts(card);
free_irq(netdev->irq, netdev);
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 51c3fe2108a3..15146a119230 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2625,7 +2625,7 @@ static void quattro_sbus_free_irqs(void)
#endif /* CONFIG_SBUS */
#ifdef CONFIG_PCI
-static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
+static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
{
struct pci_dev *bdev = pdev->bus->self;
struct quattro *qp;
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 463d600ed83d..75655add3f34 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -23,9 +23,9 @@
*/
#ifdef TC35815_NAPI
-#define DRV_VERSION "1.35-NAPI"
+#define DRV_VERSION "1.36-NAPI"
#else
-#define DRV_VERSION "1.35"
+#define DRV_VERSION "1.36"
#endif
static const char *version = "tc35815.c:v" DRV_VERSION "\n";
#define MODNAME "tc35815"
@@ -49,6 +49,7 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n";
#include <linux/pci.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -597,13 +598,46 @@ static int tc_mdio_read(struct net_device *dev, int phy_id, int location);
static void tc_mdio_write(struct net_device *dev, int phy_id, int location,
int val);
-static void __devinit tc35815_init_dev_addr (struct net_device *dev)
+#ifdef CONFIG_CPU_TX49XX
+/*
+ * Find a platform_device providing a MAC address. The platform code
+ * should provide a "tc35815-mac" device with a MAC address in its
+ * platform_data.
+ */
+static int __devinit tc35815_mac_match(struct device *dev, void *data)
+{
+ struct platform_device *plat_dev = to_platform_device(dev);
+ struct pci_dev *pci_dev = data;
+ unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn;
+ return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id;
+}
+
+static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
+{
+ struct tc35815_local *lp = dev->priv;
+ struct device *pd = bus_find_device(&platform_bus_type, NULL,
+ lp->pci_dev, tc35815_mac_match);
+ if (pd) {
+ if (pd->platform_data)
+ memcpy(dev->dev_addr, pd->platform_data, ETH_ALEN);
+ put_device(pd);
+ return is_valid_ether_addr(dev->dev_addr) ? 0 : -ENODEV;
+ }
+ return -ENODEV;
+}
+#else
+static int __devinit tc35815_read_plat_dev_addr(struct device *dev)
+{
+ return -ENODEV;
+}
+#endif
+
+static int __devinit tc35815_init_dev_addr (struct net_device *dev)
{
struct tc35815_regs __iomem *tr =
(struct tc35815_regs __iomem *)dev->base_addr;
int i;
- /* dev_addr will be overwritten on NETDEV_REGISTER event */
while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
;
for (i = 0; i < 6; i += 2) {
@@ -615,6 +649,9 @@ static void __devinit tc35815_init_dev_addr (struct net_device *dev)
dev->dev_addr[i] = data & 0xff;
dev->dev_addr[i+1] = data >> 8;
}
+ if (!is_valid_ether_addr(dev->dev_addr))
+ return tc35815_read_plat_dev_addr(dev);
+ return 0;
}
static int __devinit tc35815_init_one (struct pci_dev *pdev,
@@ -724,7 +761,10 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev,
tc35815_chip_reset(dev);
/* Retrieve the ethernet address. */
- tc35815_init_dev_addr(dev);
+ if (tc35815_init_dev_addr(dev)) {
+ dev_warn(&pdev->dev, "not valid ether addr\n");
+ random_ether_addr(dev->dev_addr);
+ }
rc = register_netdev (dev);
if (rc)
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index e22a3f5333ef..9f1b6ab9c228 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -363,7 +363,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
}
-static int __init xl_init(struct net_device *dev)
+static int __devinit xl_init(struct net_device *dev)
{
struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 18b731bb4da1..e4736a3b1b7a 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2276,7 +2276,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
phy_stop(phydev);
/* Mask all interrupts */
- out_be32(ugeth->uccf->p_ucce, 0x00000000);
+ out_be32(ugeth->uccf->p_uccm, 0x00000000);
/* Clear all interrupts */
out_be32(ugeth->uccf->p_ucce, 0xffffffff);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 86b690843362..37bf4f2c0a44 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1213,7 +1213,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
status = 0;
}
- if (status == 0 && dev->status)
+ if (status >= 0 && dev->status)
status = init_status (dev, udev);
if (status < 0)
goto out3;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
new file mode 100644
index 000000000000..ab9c3e5a7c1d
--- /dev/null
+++ b/drivers/power/Kconfig
@@ -0,0 +1,51 @@
+menuconfig POWER_SUPPLY
+ tristate "Power supply class support"
+ help
+ Say Y here to enable power supply class support. This allows
+ power supply (batteries, AC, USB) monitoring by userspace
+ via sysfs and uevent (if available) and/or APM kernel interface
+ (if selected below).
+
+if POWER_SUPPLY
+
+config POWER_SUPPLY_DEBUG
+ bool "Power supply debug"
+ help
+ Say Y here to enable debugging messages for power supply class
+ and drivers.
+
+config PDA_POWER
+ tristate "Generic PDA/phone power driver"
+ help
+ Say Y here to enable generic power driver for PDAs and phones with
+ one or two external power supplies (AC/USB) connected to main and
+ backup batteries, and optional builtin charger.
+
+config APM_POWER
+ tristate "APM emulation for class batteries"
+ depends on APM_EMULATION
+ help
+ Say Y here to enable support APM status emulation using
+ battery class devices.
+
+config BATTERY_DS2760
+ tristate "DS2760 battery driver (HP iPAQ & others)"
+ select W1
+ select W1_SLAVE_DS2760
+ help
+ Say Y here to enable support for batteries with ds2760 chip.
+
+config BATTERY_PMU
+ tristate "Apple PMU battery"
+ depends on ADB_PMU
+ help
+ Say Y here to expose battery information on Apple machines
+ through the generic battery class.
+
+config BATTERY_OLPC
+ tristate "One Laptop Per Child battery"
+ depends on X86_32 && OLPC
+ help
+ Say Y to enable support for the battery on the OLPC laptop.
+
+endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
new file mode 100644
index 000000000000..6413ded5fe5f
--- /dev/null
+++ b/drivers/power/Makefile
@@ -0,0 +1,22 @@
+power_supply-objs := power_supply_core.o
+
+ifeq ($(CONFIG_SYSFS),y)
+power_supply-objs += power_supply_sysfs.o
+endif
+
+ifeq ($(CONFIG_LEDS_TRIGGERS),y)
+power_supply-objs += power_supply_leds.o
+endif
+
+ifeq ($(CONFIG_POWER_SUPPLY_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
+
+obj-$(CONFIG_PDA_POWER) += pda_power.o
+obj-$(CONFIG_APM_POWER) += apm_power.o
+
+obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
+obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
+obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
new file mode 100644
index 000000000000..042bd950d036
--- /dev/null
+++ b/drivers/power/apm_power.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
+ * Copyright © 2007 Eugeny Boger <eugenyboger@dgap.mipt.ru>
+ *
+ * Author: Eugeny Boger <eugenyboger@dgap.mipt.ru>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ */
+
+#include <linux/module.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
+
+#define PSY_PROP(psy, prop, val) psy->get_property(psy, \
+ POWER_SUPPLY_PROP_##prop, val)
+
+#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \
+ prop, val)
+
+#define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val)
+
+static struct power_supply *main_battery;
+
+static void find_main_battery(void)
+{
+ struct device *dev;
+ struct power_supply *bat, *batm;
+ union power_supply_propval full;
+ int max_charge = 0;
+
+ main_battery = NULL;
+ batm = NULL;
+ list_for_each_entry(dev, &power_supply_class->devices, node) {
+ bat = dev_get_drvdata(dev);
+ /* If none of battery devices cantains 'use_for_apm' flag,
+ choice one with maximum design charge */
+ if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) {
+ if (full.intval > max_charge) {
+ batm = bat;
+ max_charge = full.intval;
+ }
+ }
+
+ if (bat->use_for_apm)
+ main_battery = bat;
+ }
+ if (!main_battery)
+ main_battery = batm;
+
+ return;
+}
+
+static int calculate_time(int status)
+{
+ union power_supply_propval charge_full, charge_empty;
+ union power_supply_propval charge, I;
+
+ if (MPSY_PROP(CHARGE_FULL, &charge_full)) {
+ /* if battery can't report this property, use design value */
+ if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full))
+ return -1;
+ }
+
+ if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) {
+ /* if battery can't report this property, use design value */
+ if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty))
+ charge_empty.intval = 0;
+ }
+
+ if (MPSY_PROP(CHARGE_AVG, &charge)) {
+ /* if battery can't report average value, use momentary */
+ if (MPSY_PROP(CHARGE_NOW, &charge))
+ return -1;
+ }
+
+ if (MPSY_PROP(CURRENT_AVG, &I)) {
+ /* if battery can't report average value, use momentary */
+ if (MPSY_PROP(CURRENT_NOW, &I))
+ return -1;
+ }
+
+ if (status == POWER_SUPPLY_STATUS_CHARGING)
+ return ((charge.intval - charge_full.intval) * 60L) /
+ I.intval;
+ else
+ return -((charge.intval - charge_empty.intval) * 60L) /
+ I.intval;
+}
+
+static int calculate_capacity(int using_charge)
+{
+ enum power_supply_property full_prop, empty_prop;
+ enum power_supply_property full_design_prop, empty_design_prop;
+ enum power_supply_property now_prop, avg_prop;
+ union power_supply_propval empty, full, cur;
+ int ret;
+
+ if (using_charge) {
+ full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+ empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
+ now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+ avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+ } else {
+ full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+ empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+ full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+ empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
+ now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
+ avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+ }
+
+ if (_MPSY_PROP(full_prop, &full)) {
+ /* if battery can't report this property, use design value */
+ if (_MPSY_PROP(full_design_prop, &full))
+ return -1;
+ }
+
+ if (_MPSY_PROP(avg_prop, &cur)) {
+ /* if battery can't report average value, use momentary */
+ if (_MPSY_PROP(now_prop, &cur))
+ return -1;
+ }
+
+ if (_MPSY_PROP(empty_prop, &empty)) {
+ /* if battery can't report this property, use design value */
+ if (_MPSY_PROP(empty_design_prop, &empty))
+ empty.intval = 0;
+ }
+
+ if (full.intval - empty.intval)
+ ret = ((cur.intval - empty.intval) * 100L) /
+ (full.intval - empty.intval);
+ else
+ return -1;
+
+ if (ret > 100)
+ return 100;
+ else if (ret < 0)
+ return 0;
+
+ return ret;
+}
+
+static void apm_battery_apm_get_power_status(struct apm_power_info *info)
+{
+ union power_supply_propval status;
+ union power_supply_propval capacity, time_to_full, time_to_empty;
+
+ down(&power_supply_class->sem);
+ find_main_battery();
+ if (!main_battery) {
+ up(&power_supply_class->sem);
+ return;
+ }
+
+ /* status */
+
+ if (MPSY_PROP(STATUS, &status))
+ status.intval = POWER_SUPPLY_STATUS_UNKNOWN;
+
+ /* ac line status */
+
+ if ((status.intval == POWER_SUPPLY_STATUS_CHARGING) ||
+ (status.intval == POWER_SUPPLY_STATUS_NOT_CHARGING) ||
+ (status.intval == POWER_SUPPLY_STATUS_FULL))
+ info->ac_line_status = APM_AC_ONLINE;
+ else
+ info->ac_line_status = APM_AC_OFFLINE;
+
+ /* battery life (i.e. capacity, in percents) */
+
+ if (MPSY_PROP(CAPACITY, &capacity) == 0) {
+ info->battery_life = capacity.intval;
+ } else {
+ /* try calculate using energy */
+ info->battery_life = calculate_capacity(0);
+ /* if failed try calculate using charge instead */
+ if (info->battery_life == -1)
+ info->battery_life = calculate_capacity(1);
+ }
+
+ /* charging status */
+
+ if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ } else {
+ if (info->battery_life > 50)
+ info->battery_status = APM_BATTERY_STATUS_HIGH;
+ else if (info->battery_life > 5)
+ info->battery_status = APM_BATTERY_STATUS_LOW;
+ else
+ info->battery_status = APM_BATTERY_STATUS_CRITICAL;
+ }
+ info->battery_flag = info->battery_status;
+
+ /* time */
+
+ info->units = APM_UNITS_MINS;
+
+ if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
+ if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) {
+ if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full))
+ info->time = calculate_time(status.intval);
+ else
+ info->time = time_to_full.intval / 60;
+ }
+ } else {
+ if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) {
+ if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty))
+ info->time = calculate_time(status.intval);
+ else
+ info->time = time_to_empty.intval / 60;
+ }
+ }
+
+ up(&power_supply_class->sem);
+ return;
+}
+
+static int __init apm_battery_init(void)
+{
+ printk(KERN_INFO "APM Battery Driver\n");
+
+ apm_get_power_status = apm_battery_apm_get_power_status;
+ return 0;
+}
+
+static void __exit apm_battery_exit(void)
+{
+ apm_get_power_status = NULL;
+ return;
+}
+
+module_init(apm_battery_init);
+module_exit(apm_battery_exit);
+
+MODULE_AUTHOR("Eugeny Boger <eugenyboger@dgap.mipt.ru>");
+MODULE_DESCRIPTION("APM emulation driver for battery monitoring class");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
new file mode 100644
index 000000000000..00e1ea6f1de2
--- /dev/null
+++ b/drivers/power/ds2760_battery.c
@@ -0,0 +1,470 @@
+/*
+ * Driver for batteries with DS2760 chips inside.
+ *
+ * Copyright © 2007 Anton Vorontsov
+ * 2004-2007 Matt Reimer
+ * 2004 Szabolcs Gyurko
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ * Author: Anton Vorontsov <cbou@mail.ru>
+ * February 2007
+ *
+ * Matt Reimer <mreimer@vpop.net>
+ * April 2004, 2005, 2007
+ *
+ * Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ * September 2004
+ */
+
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+#include "../w1/w1.h"
+#include "../w1/slaves/w1_ds2760.h"
+
+struct ds2760_device_info {
+ struct device *dev;
+
+ /* DS2760 data, valid after calling ds2760_battery_read_status() */
+ unsigned long update_time; /* jiffies when data read */
+ char raw[DS2760_DATA_SIZE]; /* raw DS2760 data */
+ int voltage_raw; /* units of 4.88 mV */
+ int voltage_uV; /* units of µV */
+ int current_raw; /* units of 0.625 mA */
+ int current_uA; /* units of µA */
+ int accum_current_raw; /* units of 0.25 mAh */
+ int accum_current_uAh; /* units of µAh */
+ int temp_raw; /* units of 0.125 °C */
+ int temp_C; /* units of 0.1 °C */
+ int rated_capacity; /* units of µAh */
+ int rem_capacity; /* percentage */
+ int full_active_uAh; /* units of µAh */
+ int empty_uAh; /* units of µAh */
+ int life_sec; /* units of seconds */
+ int charge_status; /* POWER_SUPPLY_STATUS_* */
+
+ int full_counter;
+ struct power_supply bat;
+ struct device *w1_dev;
+ struct workqueue_struct *monitor_wqueue;
+ struct delayed_work monitor_work;
+};
+
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+
+/* Some batteries have their rated capacity stored a N * 10 mAh, while
+ * others use an index into this table. */
+static int rated_capacities[] = {
+ 0,
+ 920, /* Samsung */
+ 920, /* BYD */
+ 920, /* Lishen */
+ 920, /* NEC */
+ 1440, /* Samsung */
+ 1440, /* BYD */
+ 1440, /* Lishen */
+ 1440, /* NEC */
+ 2880, /* Samsung */
+ 2880, /* BYD */
+ 2880, /* Lishen */
+ 2880 /* NEC */
+};
+
+/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C
+ * temp is in Celsius */
+static int battery_interpolate(int array[], int temp)
+{
+ int index, dt;
+
+ if (temp <= 0)
+ return array[0];
+ if (temp >= 40)
+ return array[4];
+
+ index = temp / 10;
+ dt = temp % 10;
+
+ return array[index] + (((array[index + 1] - array[index]) * dt) / 10);
+}
+
+static int ds2760_battery_read_status(struct ds2760_device_info *di)
+{
+ int ret, i, start, count, scale[5];
+
+ if (di->update_time && time_before(jiffies, di->update_time +
+ msecs_to_jiffies(cache_time)))
+ return 0;
+
+ /* The first time we read the entire contents of SRAM/EEPROM,
+ * but after that we just read the interesting bits that change. */
+ if (di->update_time == 0) {
+ start = 0;
+ count = DS2760_DATA_SIZE;
+ } else {
+ start = DS2760_VOLTAGE_MSB;
+ count = DS2760_TEMP_LSB - start + 1;
+ }
+
+ ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count);
+ if (ret != count) {
+ dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n",
+ di->w1_dev);
+ return 1;
+ }
+
+ di->update_time = jiffies;
+
+ /* DS2760 reports voltage in units of 4.88mV, but the battery class
+ * reports in units of uV, so convert by multiplying by 4880. */
+ di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) |
+ (di->raw[DS2760_VOLTAGE_LSB] >> 5);
+ di->voltage_uV = di->voltage_raw * 4880;
+
+ /* DS2760 reports current in signed units of 0.625mA, but the battery
+ * class reports in units of µA, so convert by multiplying by 625. */
+ di->current_raw =
+ (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) |
+ (di->raw[DS2760_CURRENT_LSB] >> 3);
+ di->current_uA = di->current_raw * 625;
+
+ /* DS2760 reports accumulated current in signed units of 0.25mAh. */
+ di->accum_current_raw =
+ (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) |
+ di->raw[DS2760_CURRENT_ACCUM_LSB];
+ di->accum_current_uAh = di->accum_current_raw * 250;
+
+ /* DS2760 reports temperature in signed units of 0.125°C, but the
+ * battery class reports in units of 1/10 °C, so we convert by
+ * multiplying by .125 * 10 = 1.25. */
+ di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) |
+ (di->raw[DS2760_TEMP_LSB] >> 5);
+ di->temp_C = di->temp_raw + (di->temp_raw / 4);
+
+ /* At least some battery monitors (e.g. HP iPAQ) store the battery's
+ * maximum rated capacity. */
+ if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities))
+ di->rated_capacity = rated_capacities[
+ (unsigned int)di->raw[DS2760_RATED_CAPACITY]];
+ else
+ di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10;
+
+ di->rated_capacity *= 1000; /* convert to µAh */
+
+ /* Calculate the full level at the present temperature. */
+ di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 |
+ di->raw[DS2760_ACTIVE_FULL + 1];
+
+ scale[0] = di->raw[DS2760_ACTIVE_FULL] << 8 |
+ di->raw[DS2760_ACTIVE_FULL + 1];
+ for (i = 1; i < 5; i++)
+ scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i];
+
+ di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10);
+ di->full_active_uAh *= 1000; /* convert to µAh */
+
+ /* Calculate the empty level at the present temperature. */
+ scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4];
+ for (i = 3; i >= 0; i--)
+ scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i];
+
+ di->empty_uAh = battery_interpolate(scale, di->temp_C / 10);
+ di->empty_uAh *= 1000; /* convert to µAh */
+
+ /* From Maxim Application Note 131: remaining capacity =
+ * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */
+ di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) /
+ (di->full_active_uAh - di->empty_uAh);
+
+ if (di->rem_capacity < 0)
+ di->rem_capacity = 0;
+ if (di->rem_capacity > 100)
+ di->rem_capacity = 100;
+
+ if (di->current_uA)
+ di->life_sec = -((di->accum_current_uAh - di->empty_uAh) *
+ 3600L) / di->current_uA;
+ else
+ di->life_sec = 0;
+
+ return 0;
+}
+
+static void ds2760_battery_update_status(struct ds2760_device_info *di)
+{
+ int old_charge_status = di->charge_status;
+
+ ds2760_battery_read_status(di);
+
+ if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN)
+ di->full_counter = 0;
+
+ if (power_supply_am_i_supplied(&di->bat)) {
+ if (di->current_uA > 10000) {
+ di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
+ di->full_counter = 0;
+ } else if (di->current_uA < -5000) {
+ if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING)
+ dev_notice(di->dev, "not enough power to "
+ "charge\n");
+ di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ di->full_counter = 0;
+ } else if (di->current_uA < 10000 &&
+ di->charge_status != POWER_SUPPLY_STATUS_FULL) {
+
+ /* Don't consider the battery to be full unless
+ * we've seen the current < 10 mA at least two
+ * consecutive times. */
+
+ di->full_counter++;
+
+ if (di->full_counter < 2) {
+ di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else {
+ unsigned char acr[2];
+ int acr_val;
+
+ /* acr is in units of 0.25 mAh */
+ acr_val = di->full_active_uAh * 4L / 1000;
+
+ acr[0] = acr_val >> 8;
+ acr[1] = acr_val & 0xff;
+
+ if (w1_ds2760_write(di->w1_dev, acr,
+ DS2760_CURRENT_ACCUM_MSB, 2) < 2)
+ dev_warn(di->dev,
+ "ACR reset failed\n");
+
+ di->charge_status = POWER_SUPPLY_STATUS_FULL;
+ }
+ }
+ } else {
+ di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
+ di->full_counter = 0;
+ }
+
+ if (di->charge_status != old_charge_status)
+ power_supply_changed(&di->bat);
+
+ return;
+}
+
+static void ds2760_battery_work(struct work_struct *work)
+{
+ struct ds2760_device_info *di = container_of(work,
+ struct ds2760_device_info, monitor_work.work);
+ const int interval = HZ * 60;
+
+ dev_dbg(di->dev, "%s\n", __FUNCTION__);
+
+ ds2760_battery_update_status(di);
+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval);
+
+ return;
+}
+
+#define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \
+ bat);
+
+static void ds2760_battery_external_power_changed(struct power_supply *psy)
+{
+ struct ds2760_device_info *di = to_ds2760_device_info(psy);
+
+ dev_dbg(di->dev, "%s\n", __FUNCTION__);
+
+ cancel_delayed_work(&di->monitor_work);
+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10);
+
+ return;
+}
+
+static int ds2760_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct ds2760_device_info *di = to_ds2760_device_info(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = di->charge_status;
+ return 0;
+ default:
+ break;
+ }
+
+ ds2760_battery_read_status(di);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = di->voltage_uV;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = di->current_uA;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ val->intval = di->rated_capacity;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ val->intval = di->full_active_uAh;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_EMPTY:
+ val->intval = di->empty_uAh;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ val->intval = di->accum_current_uAh;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = di->temp_C;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static enum power_supply_property ds2760_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_EMPTY,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static int ds2760_battery_probe(struct platform_device *pdev)
+{
+ int retval = 0;
+ struct ds2760_device_info *di;
+ struct ds2760_platform_data *pdata;
+
+ di = kzalloc(sizeof(*di), GFP_KERNEL);
+ if (!di) {
+ retval = -ENOMEM;
+ goto di_alloc_failed;
+ }
+
+ platform_set_drvdata(pdev, di);
+
+ pdata = pdev->dev.platform_data;
+ di->dev = &pdev->dev;
+ di->w1_dev = pdev->dev.parent;
+ di->bat.name = pdev->dev.bus_id;
+ di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ di->bat.properties = ds2760_battery_props;
+ di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props);
+ di->bat.get_property = ds2760_battery_get_property;
+ di->bat.external_power_changed =
+ ds2760_battery_external_power_changed;
+
+ di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+ retval = power_supply_register(&pdev->dev, &di->bat);
+ if (retval) {
+ dev_err(di->dev, "failed to register battery");
+ goto batt_failed;
+ }
+
+ INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
+ di->monitor_wqueue = create_singlethread_workqueue(pdev->dev.bus_id);
+ if (!di->monitor_wqueue) {
+ retval = -ESRCH;
+ goto workqueue_failed;
+ }
+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1);
+
+ goto success;
+
+workqueue_failed:
+ power_supply_unregister(&di->bat);
+batt_failed:
+ kfree(di);
+di_alloc_failed:
+success:
+ return retval;
+}
+
+static int ds2760_battery_remove(struct platform_device *pdev)
+{
+ struct ds2760_device_info *di = platform_get_drvdata(pdev);
+
+ cancel_rearming_delayed_workqueue(di->monitor_wqueue,
+ &di->monitor_work);
+ destroy_workqueue(di->monitor_wqueue);
+ power_supply_unregister(&di->bat);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int ds2760_battery_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ds2760_device_info *di = platform_get_drvdata(pdev);
+
+ di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+ return 0;
+}
+
+static int ds2760_battery_resume(struct platform_device *pdev)
+{
+ struct ds2760_device_info *di = platform_get_drvdata(pdev);
+
+ di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+ power_supply_changed(&di->bat);
+
+ cancel_delayed_work(&di->monitor_work);
+ queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ);
+
+ return 0;
+}
+
+#else
+
+#define ds2760_battery_suspend NULL
+#define ds2760_battery_resume NULL
+
+#endif /* CONFIG_PM */
+
+static struct platform_driver ds2760_battery_driver = {
+ .driver = {
+ .name = "ds2760-battery",
+ },
+ .probe = ds2760_battery_probe,
+ .remove = ds2760_battery_remove,
+ .suspend = ds2760_battery_suspend,
+ .resume = ds2760_battery_resume,
+};
+
+static int __init ds2760_battery_init(void)
+{
+ return platform_driver_register(&ds2760_battery_driver);
+}
+
+static void __exit ds2760_battery_exit(void)
+{
+ platform_driver_unregister(&ds2760_battery_driver);
+ return;
+}
+
+module_init(ds2760_battery_init);
+module_exit(ds2760_battery_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
+ "Matt Reimer <mreimer@vpop.net>, "
+ "Anton Vorontsov <cbou@mail.ru>");
+MODULE_DESCRIPTION("ds2760 battery driver");
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
new file mode 100644
index 000000000000..878684df7667
--- /dev/null
+++ b/drivers/power/olpc_battery.c
@@ -0,0 +1,352 @@
+/*
+ * Battery driver for One Laptop Per Child board.
+ *
+ * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <asm/olpc.h>
+
+
+#define EC_BAT_VOLTAGE 0x10 /* uint16_t, *9.76/32, mV */
+#define EC_BAT_CURRENT 0x11 /* int16_t, *15.625/120, mA */
+#define EC_BAT_ACR 0x12
+#define EC_BAT_TEMP 0x13 /* uint16_t, *100/256, °C */
+#define EC_AMB_TEMP 0x14 /* uint16_t, *100/256, °C */
+#define EC_BAT_STATUS 0x15 /* uint8_t, bitmask */
+#define EC_BAT_SOC 0x16 /* uint8_t, percentage */
+#define EC_BAT_SERIAL 0x17 /* uint8_t[6] */
+#define EC_BAT_EEPROM 0x18 /* uint8_t adr as input, uint8_t output */
+#define EC_BAT_ERRCODE 0x1f /* uint8_t, bitmask */
+
+#define BAT_STAT_PRESENT 0x01
+#define BAT_STAT_FULL 0x02
+#define BAT_STAT_LOW 0x04
+#define BAT_STAT_DESTROY 0x08
+#define BAT_STAT_AC 0x10
+#define BAT_STAT_CHARGING 0x20
+#define BAT_STAT_DISCHARGING 0x40
+
+#define BAT_ERR_INFOFAIL 0x02
+#define BAT_ERR_OVERVOLTAGE 0x04
+#define BAT_ERR_OVERTEMP 0x05
+#define BAT_ERR_GAUGESTOP 0x06
+#define BAT_ERR_OUT_OF_CONTROL 0x07
+#define BAT_ERR_ID_FAIL 0x09
+#define BAT_ERR_ACR_FAIL 0x10
+
+#define BAT_ADDR_MFR_TYPE 0x5F
+
+/*********************************************************************
+ * Power
+ *********************************************************************/
+
+static int olpc_ac_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret = 0;
+ uint8_t status;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
+ if (ret)
+ return ret;
+
+ val->intval = !!(status & BAT_STAT_AC);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static enum power_supply_property olpc_ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static struct power_supply olpc_ac = {
+ .name = "olpc-ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .properties = olpc_ac_props,
+ .num_properties = ARRAY_SIZE(olpc_ac_props),
+ .get_property = olpc_ac_get_prop,
+};
+
+/*********************************************************************
+ * Battery properties
+ *********************************************************************/
+static int olpc_bat_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret = 0;
+ int16_t ec_word;
+ uint8_t ec_byte;
+
+ ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
+ if (ret)
+ return ret;
+
+ /* Theoretically there's a race here -- the battery could be
+ removed immediately after we check whether it's present, and
+ then we query for some other property of the now-absent battery.
+ It doesn't matter though -- the EC will return the last-known
+ information, and it's as if we just ran that _little_ bit faster
+ and managed to read it out before the battery went away. */
+ if (!(ec_byte & BAT_STAT_PRESENT) && psp != POWER_SUPPLY_PROP_PRESENT)
+ return -ENODEV;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (olpc_platform_info.ecver > 0x44) {
+ if (ec_byte & BAT_STAT_CHARGING)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else if (ec_byte & BAT_STAT_DISCHARGING)
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else if (ec_byte & BAT_STAT_FULL)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ else /* er,... */
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ /* Older EC didn't report charge/discharge bits */
+ if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else if (ec_byte & BAT_STAT_FULL)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ else /* Not _necessarily_ true but EC doesn't tell all yet */
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ }
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = !!(ec_byte & BAT_STAT_PRESENT);
+ break;
+
+ case POWER_SUPPLY_PROP_HEALTH:
+ if (ec_byte & BAT_STAT_DESTROY)
+ val->intval = POWER_SUPPLY_HEALTH_DEAD;
+ else {
+ ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
+ if (ret)
+ return ret;
+
+ switch (ec_byte) {
+ case 0:
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+
+ case BAT_ERR_OVERTEMP:
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ break;
+
+ case BAT_ERR_OVERVOLTAGE:
+ val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ break;
+
+ case BAT_ERR_INFOFAIL:
+ case BAT_ERR_OUT_OF_CONTROL:
+ case BAT_ERR_ID_FAIL:
+ case BAT_ERR_ACR_FAIL:
+ val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ break;
+
+ default:
+ /* Eep. We don't know this failure code */
+ return -EIO;
+ }
+ }
+ break;
+
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ ec_byte = BAT_ADDR_MFR_TYPE;
+ ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
+ if (ret)
+ return ret;
+
+ switch (ec_byte >> 4) {
+ case 1:
+ val->strval = "Gold Peak";
+ break;
+ case 2:
+ val->strval = "BYD";
+ break;
+ default:
+ val->strval = "Unknown";
+ break;
+ }
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ ec_byte = BAT_ADDR_MFR_TYPE;
+ ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
+ if (ret)
+ return ret;
+
+ switch (ec_byte & 0xf) {
+ case 1:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
+ break;
+ case 2:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
+ break;
+ default:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+ break;
+ }
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+ ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);
+ if (ret)
+ return ret;
+
+ ec_word = be16_to_cpu(ec_word);
+ val->intval = ec_word * 9760L / 32;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
+ ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
+ if (ret)
+ return ret;
+
+ ec_word = be16_to_cpu(ec_word);
+ val->intval = ec_word * 15625L / 120;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
+ if (ret)
+ return ret;
+ val->intval = ec_byte;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
+ if (ec_byte & BAT_STAT_FULL)
+ val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
+ else if (ec_byte & BAT_STAT_LOW)
+ val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
+ else
+ val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
+ if (ret)
+ return ret;
+ ec_word = be16_to_cpu(ec_word);
+ val->intval = ec_word * 100 / 256;
+ break;
+ case POWER_SUPPLY_PROP_TEMP_AMBIENT:
+ ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
+ if (ret)
+ return ret;
+
+ ec_word = be16_to_cpu(ec_word);
+ val->intval = ec_word * 100 / 256;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static enum power_supply_property olpc_bat_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TEMP_AMBIENT,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+/*********************************************************************
+ * Initialisation
+ *********************************************************************/
+
+static struct platform_device *bat_pdev;
+
+static struct power_supply olpc_bat = {
+ .properties = olpc_bat_props,
+ .num_properties = ARRAY_SIZE(olpc_bat_props),
+ .get_property = olpc_bat_get_property,
+ .use_for_apm = 1,
+};
+
+void olpc_battery_trigger_uevent(unsigned long cause)
+{
+ if (cause & EC_SCI_SRC_ACPWR)
+ kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE);
+ if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY))
+ kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE);
+}
+
+static int __init olpc_bat_init(void)
+{
+ int ret = 0;
+ uint8_t status;
+
+ if (!olpc_platform_info.ecver)
+ return -ENXIO;
+ if (olpc_platform_info.ecver < 0x43) {
+ printk(KERN_NOTICE "OLPC EC version 0x%02x too old for battery driver.\n", olpc_platform_info.ecver);
+ return -ENXIO;
+ }
+
+ ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
+ if (ret)
+ return ret;
+
+ /* Ignore the status. It doesn't actually matter */
+
+ bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0);
+ if (IS_ERR(bat_pdev))
+ return PTR_ERR(bat_pdev);
+
+ ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
+ if (ret)
+ goto ac_failed;
+
+ olpc_bat.name = bat_pdev->name;
+
+ ret = power_supply_register(&bat_pdev->dev, &olpc_bat);
+ if (ret)
+ goto battery_failed;
+
+ olpc_register_battery_callback(&olpc_battery_trigger_uevent);
+ goto success;
+
+battery_failed:
+ power_supply_unregister(&olpc_ac);
+ac_failed:
+ platform_device_unregister(bat_pdev);
+success:
+ return ret;
+}
+
+static void __exit olpc_bat_exit(void)
+{
+ olpc_deregister_battery_callback();
+ power_supply_unregister(&olpc_bat);
+ power_supply_unregister(&olpc_ac);
+ platform_device_unregister(bat_pdev);
+ return;
+}
+
+module_init(olpc_bat_init);
+module_exit(olpc_bat_exit);
+
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Battery driver for One Laptop Per Child 'XO' machine");
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
new file mode 100644
index 000000000000..4e1eb040e148
--- /dev/null
+++ b/drivers/power/pda_power.c
@@ -0,0 +1,261 @@
+/*
+ * Common power driver for PDAs and phones with one or two external
+ * power supplies (AC/USB) connected to main and backup batteries,
+ * and optional builtin charger.
+ *
+ * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/power_supply.h>
+#include <linux/pda_power.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+
+static inline unsigned int get_irq_flags(struct resource *res)
+{
+ unsigned int flags = IRQF_DISABLED | IRQF_SHARED;
+
+ flags |= res->flags & IRQF_TRIGGER_MASK;
+
+ return flags;
+}
+
+static struct device *dev;
+static struct pda_power_pdata *pdata;
+static struct resource *ac_irq, *usb_irq;
+static struct timer_list charger_timer;
+static struct timer_list supply_timer;
+
+static int pda_power_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ if (psy->type == POWER_SUPPLY_TYPE_MAINS)
+ val->intval = pdata->is_ac_online ?
+ pdata->is_ac_online() : 0;
+ else
+ val->intval = pdata->is_usb_online ?
+ pdata->is_usb_online() : 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property pda_power_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static char *pda_power_supplied_to[] = {
+ "main-battery",
+ "backup-battery",
+};
+
+static struct power_supply pda_power_supplies[] = {
+ {
+ .name = "ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .supplied_to = pda_power_supplied_to,
+ .num_supplicants = ARRAY_SIZE(pda_power_supplied_to),
+ .properties = pda_power_props,
+ .num_properties = ARRAY_SIZE(pda_power_props),
+ .get_property = pda_power_get_property,
+ },
+ {
+ .name = "usb",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .supplied_to = pda_power_supplied_to,
+ .num_supplicants = ARRAY_SIZE(pda_power_supplied_to),
+ .properties = pda_power_props,
+ .num_properties = ARRAY_SIZE(pda_power_props),
+ .get_property = pda_power_get_property,
+ },
+};
+
+static void update_charger(void)
+{
+ if (!pdata->set_charge)
+ return;
+
+ if (pdata->is_ac_online && pdata->is_ac_online()) {
+ dev_dbg(dev, "charger on (AC)\n");
+ pdata->set_charge(PDA_POWER_CHARGE_AC);
+ } else if (pdata->is_usb_online && pdata->is_usb_online()) {
+ dev_dbg(dev, "charger on (USB)\n");
+ pdata->set_charge(PDA_POWER_CHARGE_USB);
+ } else {
+ dev_dbg(dev, "charger off\n");
+ pdata->set_charge(0);
+ }
+
+ return;
+}
+
+static void supply_timer_func(unsigned long irq)
+{
+ if (ac_irq && irq == ac_irq->start)
+ power_supply_changed(&pda_power_supplies[0]);
+ else if (usb_irq && irq == usb_irq->start)
+ power_supply_changed(&pda_power_supplies[1]);
+ return;
+}
+
+static void charger_timer_func(unsigned long irq)
+{
+ update_charger();
+
+ /* Okay, charger set. Now wait a bit before notifying supplicants,
+ * charge power should stabilize. */
+ supply_timer.data = irq;
+ mod_timer(&supply_timer,
+ jiffies + msecs_to_jiffies(pdata->wait_for_charger));
+ return;
+}
+
+static irqreturn_t power_changed_isr(int irq, void *unused)
+{
+ /* Wait a bit before reading ac/usb line status and setting charger,
+ * because ac/usb status readings may lag from irq. */
+ charger_timer.data = irq;
+ mod_timer(&charger_timer,
+ jiffies + msecs_to_jiffies(pdata->wait_for_status));
+ return IRQ_HANDLED;
+}
+
+static int pda_power_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ dev = &pdev->dev;
+
+ if (pdev->id != -1) {
+ dev_err(dev, "it's meaningless to register several "
+ "pda_powers; use id = -1\n");
+ ret = -EINVAL;
+ goto wrongid;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ update_charger();
+
+ if (!pdata->wait_for_status)
+ pdata->wait_for_status = 500;
+
+ if (!pdata->wait_for_charger)
+ pdata->wait_for_charger = 500;
+
+ setup_timer(&charger_timer, charger_timer_func, 0);
+ setup_timer(&supply_timer, supply_timer_func, 0);
+
+ ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
+ usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
+ if (!ac_irq && !usb_irq) {
+ dev_err(dev, "no ac/usb irq specified\n");
+ ret = -ENODEV;
+ goto noirqs;
+ }
+
+ if (pdata->supplied_to) {
+ pda_power_supplies[0].supplied_to = pdata->supplied_to;
+ pda_power_supplies[1].supplied_to = pdata->supplied_to;
+ pda_power_supplies[0].num_supplicants = pdata->num_supplicants;
+ pda_power_supplies[1].num_supplicants = pdata->num_supplicants;
+ }
+
+ ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
+ if (ret) {
+ dev_err(dev, "failed to register %s power supply\n",
+ pda_power_supplies[0].name);
+ goto supply0_failed;
+ }
+
+ ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
+ if (ret) {
+ dev_err(dev, "failed to register %s power supply\n",
+ pda_power_supplies[1].name);
+ goto supply1_failed;
+ }
+
+ if (ac_irq) {
+ ret = request_irq(ac_irq->start, power_changed_isr,
+ get_irq_flags(ac_irq), ac_irq->name,
+ &pda_power_supplies[0]);
+ if (ret) {
+ dev_err(dev, "request ac irq failed\n");
+ goto ac_irq_failed;
+ }
+ }
+
+ if (usb_irq) {
+ ret = request_irq(usb_irq->start, power_changed_isr,
+ get_irq_flags(usb_irq), usb_irq->name,
+ &pda_power_supplies[1]);
+ if (ret) {
+ dev_err(dev, "request usb irq failed\n");
+ goto usb_irq_failed;
+ }
+ }
+
+ goto success;
+
+usb_irq_failed:
+ if (ac_irq)
+ free_irq(ac_irq->start, &pda_power_supplies[0]);
+ac_irq_failed:
+ power_supply_unregister(&pda_power_supplies[1]);
+supply1_failed:
+ power_supply_unregister(&pda_power_supplies[0]);
+supply0_failed:
+noirqs:
+wrongid:
+success:
+ return ret;
+}
+
+static int pda_power_remove(struct platform_device *pdev)
+{
+ if (usb_irq)
+ free_irq(usb_irq->start, &pda_power_supplies[1]);
+ if (ac_irq)
+ free_irq(ac_irq->start, &pda_power_supplies[0]);
+ del_timer_sync(&charger_timer);
+ del_timer_sync(&supply_timer);
+ power_supply_unregister(&pda_power_supplies[1]);
+ power_supply_unregister(&pda_power_supplies[0]);
+ return 0;
+}
+
+static struct platform_driver pda_power_pdrv = {
+ .driver = {
+ .name = "pda-power",
+ },
+ .probe = pda_power_probe,
+ .remove = pda_power_remove,
+};
+
+static int __init pda_power_init(void)
+{
+ return platform_driver_register(&pda_power_pdrv);
+}
+
+static void __exit pda_power_exit(void)
+{
+ platform_driver_unregister(&pda_power_pdrv);
+ return;
+}
+
+module_init(pda_power_init);
+module_exit(pda_power_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c
new file mode 100644
index 000000000000..2fea4af0e40a
--- /dev/null
+++ b/drivers/power/pmu_battery.c
@@ -0,0 +1,215 @@
+/*
+ * Battery class driver for Apple PMU
+ *
+ * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+static struct pmu_battery_dev {
+ struct power_supply bat;
+ struct pmu_battery_info *pbi;
+ char name[16];
+ int propval;
+} *pbats[PMU_MAX_BATTERIES];
+
+#define to_pmu_battery_dev(x) container_of(x, struct pmu_battery_dev, bat)
+
+/*********************************************************************
+ * Power
+ *********************************************************************/
+
+static int pmu_get_ac_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = (!!(pmu_power_flags & PMU_PWR_AC_PRESENT)) ||
+ (pmu_battery_count == 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static enum power_supply_property pmu_ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static struct power_supply pmu_ac = {
+ .name = "pmu-ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .properties = pmu_ac_props,
+ .num_properties = ARRAY_SIZE(pmu_ac_props),
+ .get_property = pmu_get_ac_prop,
+};
+
+/*********************************************************************
+ * Battery properties
+ *********************************************************************/
+
+static char *pmu_batt_types[] = {
+ "Smart", "Comet", "Hooper", "Unknown"
+};
+
+static char *pmu_bat_get_model_name(struct pmu_battery_info *pbi)
+{
+ switch (pbi->flags & PMU_BATT_TYPE_MASK) {
+ case PMU_BATT_TYPE_SMART:
+ return pmu_batt_types[0];
+ case PMU_BATT_TYPE_COMET:
+ return pmu_batt_types[1];
+ case PMU_BATT_TYPE_HOOPER:
+ return pmu_batt_types[2];
+ default: break;
+ }
+ return pmu_batt_types[3];
+}
+
+static int pmu_bat_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pmu_battery_dev *pbat = to_pmu_battery_dev(psy);
+ struct pmu_battery_info *pbi = pbat->pbi;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (pbi->flags & PMU_BATT_CHARGING)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = !!(pbi->flags & PMU_BATT_PRESENT);
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = pmu_bat_get_model_name(pbi);
+ break;
+ case POWER_SUPPLY_PROP_ENERGY_AVG:
+ val->intval = pbi->charge * 1000; /* mWh -> µWh */
+ break;
+ case POWER_SUPPLY_PROP_ENERGY_FULL:
+ val->intval = pbi->max_charge * 1000; /* mWh -> µWh */
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
+ val->intval = pbi->amperage * 1000; /* mA -> µA */
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+ val->intval = pbi->voltage * 1000; /* mV -> µV */
+ break;
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ val->intval = pbi->time_remaining;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static enum power_supply_property pmu_bat_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_ENERGY_AVG,
+ POWER_SUPPLY_PROP_ENERGY_FULL,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+};
+
+/*********************************************************************
+ * Initialisation
+ *********************************************************************/
+
+static struct platform_device *bat_pdev;
+
+static int __init pmu_bat_init(void)
+{
+ int ret;
+ int i;
+
+ bat_pdev = platform_device_register_simple("pmu-battery",
+ 0, NULL, 0);
+ if (IS_ERR(bat_pdev)) {
+ ret = PTR_ERR(bat_pdev);
+ goto pdev_register_failed;
+ }
+
+ ret = power_supply_register(&bat_pdev->dev, &pmu_ac);
+ if (ret)
+ goto ac_register_failed;
+
+ for (i = 0; i < pmu_battery_count; i++) {
+ struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat),
+ GFP_KERNEL);
+ if (!pbat)
+ break;
+
+ sprintf(pbat->name, "PMU battery %d", i);
+ pbat->bat.name = pbat->name;
+ pbat->bat.properties = pmu_bat_props;
+ pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props);
+ pbat->bat.get_property = pmu_bat_get_property;
+ pbat->pbi = &pmu_batteries[i];
+
+ ret = power_supply_register(&bat_pdev->dev, &pbat->bat);
+ if (ret) {
+ kfree(pbat);
+ goto battery_register_failed;
+ }
+ pbats[i] = pbat;
+ }
+
+ goto success;
+
+battery_register_failed:
+ while (i--) {
+ if (!pbats[i])
+ continue;
+ power_supply_unregister(&pbats[i]->bat);
+ kfree(pbats[i]);
+ }
+ power_supply_unregister(&pmu_ac);
+ac_register_failed:
+ platform_device_unregister(bat_pdev);
+pdev_register_failed:
+success:
+ return ret;
+}
+
+static void __exit pmu_bat_exit(void)
+{
+ int i;
+
+ for (i = 0; i < PMU_MAX_BATTERIES; i++) {
+ if (!pbats[i])
+ continue;
+ power_supply_unregister(&pbats[i]->bat);
+ kfree(pbats[i]);
+ }
+ power_supply_unregister(&pmu_ac);
+ platform_device_unregister(bat_pdev);
+
+ return;
+}
+
+module_init(pmu_bat_init);
+module_exit(pmu_bat_exit);
+
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PMU battery driver");
diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h
new file mode 100644
index 000000000000..a9880d468ee4
--- /dev/null
+++ b/drivers/power/power_supply.h
@@ -0,0 +1,42 @@
+/*
+ * Functions private to power supply class
+ *
+ * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
+ * Copyright © 2004 Szabolcs Gyurko
+ * Copyright © 2003 Ian Molton <spyro@f2s.com>
+ *
+ * Modified: 2004, Oct Szabolcs Gyurko
+ *
+ * You may use this code as per GPL version 2
+ */
+
+#ifdef CONFIG_SYSFS
+
+extern int power_supply_create_attrs(struct power_supply *psy);
+extern void power_supply_remove_attrs(struct power_supply *psy);
+extern int power_supply_uevent(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size);
+
+#else
+
+static inline int power_supply_create_attrs(struct power_supply *psy)
+{ return 0; }
+static inline void power_supply_remove_attrs(struct power_supply *psy) {}
+#define power_supply_uevent NULL
+
+#endif /* CONFIG_SYSFS */
+
+#ifdef CONFIG_LEDS_TRIGGERS
+
+extern void power_supply_update_leds(struct power_supply *psy);
+extern int power_supply_create_triggers(struct power_supply *psy);
+extern void power_supply_remove_triggers(struct power_supply *psy);
+
+#else
+
+static inline void power_supply_update_leds(struct power_supply *psy) {}
+static inline int power_supply_create_triggers(struct power_supply *psy)
+{ return 0; }
+static inline void power_supply_remove_triggers(struct power_supply *psy) {}
+
+#endif /* CONFIG_LEDS_TRIGGERS */
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
new file mode 100644
index 000000000000..e87ea5156755
--- /dev/null
+++ b/drivers/power/power_supply_core.c
@@ -0,0 +1,168 @@
+/*
+ * Universal power supply monitor class
+ *
+ * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
+ * Copyright © 2004 Szabolcs Gyurko
+ * Copyright © 2003 Ian Molton <spyro@f2s.com>
+ *
+ * Modified: 2004, Oct Szabolcs Gyurko
+ *
+ * You may use this code as per GPL version 2
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include "power_supply.h"
+
+struct class *power_supply_class;
+
+static void power_supply_changed_work(struct work_struct *work)
+{
+ struct power_supply *psy = container_of(work, struct power_supply,
+ changed_work);
+ int i;
+
+ dev_dbg(psy->dev, "%s\n", __FUNCTION__);
+
+ for (i = 0; i < psy->num_supplicants; i++) {
+ struct device *dev;
+
+ down(&power_supply_class->sem);
+ list_for_each_entry(dev, &power_supply_class->devices, node) {
+ struct power_supply *pst = dev_get_drvdata(dev);
+
+ if (!strcmp(psy->supplied_to[i], pst->name)) {
+ if (pst->external_power_changed)
+ pst->external_power_changed(pst);
+ }
+ }
+ up(&power_supply_class->sem);
+ }
+
+ power_supply_update_leds(psy);
+
+ kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);
+
+ return;
+}
+
+void power_supply_changed(struct power_supply *psy)
+{
+ dev_dbg(psy->dev, "%s\n", __FUNCTION__);
+
+ schedule_work(&psy->changed_work);
+
+ return;
+}
+
+int power_supply_am_i_supplied(struct power_supply *psy)
+{
+ union power_supply_propval ret = {0,};
+ struct device *dev;
+
+ down(&power_supply_class->sem);
+ list_for_each_entry(dev, &power_supply_class->devices, node) {
+ struct power_supply *epsy = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < epsy->num_supplicants; i++) {
+ if (!strcmp(epsy->supplied_to[i], psy->name)) {
+ if (epsy->get_property(epsy,
+ POWER_SUPPLY_PROP_ONLINE, &ret))
+ continue;
+ if (ret.intval)
+ goto out;
+ }
+ }
+ }
+out:
+ up(&power_supply_class->sem);
+
+ dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, ret.intval);
+
+ return ret.intval;
+}
+
+int power_supply_register(struct device *parent, struct power_supply *psy)
+{
+ int rc = 0;
+
+ psy->dev = device_create(power_supply_class, parent, 0,
+ "%s", psy->name);
+ if (IS_ERR(psy->dev)) {
+ rc = PTR_ERR(psy->dev);
+ goto dev_create_failed;
+ }
+
+ dev_set_drvdata(psy->dev, psy);
+
+ INIT_WORK(&psy->changed_work, power_supply_changed_work);
+
+ rc = power_supply_create_attrs(psy);
+ if (rc)
+ goto create_attrs_failed;
+
+ rc = power_supply_create_triggers(psy);
+ if (rc)
+ goto create_triggers_failed;
+
+ power_supply_changed(psy);
+
+ goto success;
+
+create_triggers_failed:
+ power_supply_remove_attrs(psy);
+create_attrs_failed:
+ device_unregister(psy->dev);
+dev_create_failed:
+success:
+ return rc;
+}
+
+void power_supply_unregister(struct power_supply *psy)
+{
+ flush_scheduled_work();
+ power_supply_remove_triggers(psy);
+ power_supply_remove_attrs(psy);
+ device_unregister(psy->dev);
+ return;
+}
+
+static int __init power_supply_class_init(void)
+{
+ power_supply_class = class_create(THIS_MODULE, "power_supply");
+
+ if (IS_ERR(power_supply_class))
+ return PTR_ERR(power_supply_class);
+
+ power_supply_class->dev_uevent = power_supply_uevent;
+
+ return 0;
+}
+
+static void __exit power_supply_class_exit(void)
+{
+ class_destroy(power_supply_class);
+ return;
+}
+
+EXPORT_SYMBOL_GPL(power_supply_changed);
+EXPORT_SYMBOL_GPL(power_supply_am_i_supplied);
+EXPORT_SYMBOL_GPL(power_supply_register);
+EXPORT_SYMBOL_GPL(power_supply_unregister);
+
+/* exported for the APM Power driver, APM emulation */
+EXPORT_SYMBOL_GPL(power_supply_class);
+
+subsys_initcall(power_supply_class_init);
+module_exit(power_supply_class_exit);
+
+MODULE_DESCRIPTION("Universal power supply monitor class");
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>, "
+ "Szabolcs Gyurko, "
+ "Anton Vorontsov <cbou@mail.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c
new file mode 100644
index 000000000000..7232490bb595
--- /dev/null
+++ b/drivers/power/power_supply_leds.c
@@ -0,0 +1,176 @@
+/*
+ * LEDs triggers for power supply class
+ *
+ * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
+ * Copyright © 2004 Szabolcs Gyurko
+ * Copyright © 2003 Ian Molton <spyro@f2s.com>
+ *
+ * Modified: 2004, Oct Szabolcs Gyurko
+ *
+ * You may use this code as per GPL version 2
+ */
+
+#include <linux/power_supply.h>
+
+/* Battery specific LEDs triggers. */
+
+static void power_supply_update_bat_leds(struct power_supply *psy)
+{
+ union power_supply_propval status;
+
+ if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
+ return;
+
+ dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, status.intval);
+
+ switch (status.intval) {
+ case POWER_SUPPLY_STATUS_FULL:
+ led_trigger_event(psy->charging_full_trig, LED_FULL);
+ led_trigger_event(psy->charging_trig, LED_OFF);
+ led_trigger_event(psy->full_trig, LED_FULL);
+ break;
+ case POWER_SUPPLY_STATUS_CHARGING:
+ led_trigger_event(psy->charging_full_trig, LED_FULL);
+ led_trigger_event(psy->charging_trig, LED_FULL);
+ led_trigger_event(psy->full_trig, LED_OFF);
+ break;
+ default:
+ led_trigger_event(psy->charging_full_trig, LED_OFF);
+ led_trigger_event(psy->charging_trig, LED_OFF);
+ led_trigger_event(psy->full_trig, LED_OFF);
+ break;
+ }
+
+ return;
+}
+
+static int power_supply_create_bat_triggers(struct power_supply *psy)
+{
+ int rc = 0;
+
+ psy->charging_full_trig_name = kmalloc(strlen(psy->name) +
+ sizeof("-charging-or-full"), GFP_KERNEL);
+ if (!psy->charging_full_trig_name)
+ goto charging_full_failed;
+
+ psy->charging_trig_name = kmalloc(strlen(psy->name) +
+ sizeof("-charging"), GFP_KERNEL);
+ if (!psy->charging_trig_name)
+ goto charging_failed;
+
+ psy->full_trig_name = kmalloc(strlen(psy->name) +
+ sizeof("-full"), GFP_KERNEL);
+ if (!psy->full_trig_name)
+ goto full_failed;
+
+ strcpy(psy->charging_full_trig_name, psy->name);
+ strcat(psy->charging_full_trig_name, "-charging-or-full");
+ strcpy(psy->charging_trig_name, psy->name);
+ strcat(psy->charging_trig_name, "-charging");
+ strcpy(psy->full_trig_name, psy->name);
+ strcat(psy->full_trig_name, "-full");
+
+ led_trigger_register_simple(psy->charging_full_trig_name,
+ &psy->charging_full_trig);
+ led_trigger_register_simple(psy->charging_trig_name,
+ &psy->charging_trig);
+ led_trigger_register_simple(psy->full_trig_name,
+ &psy->full_trig);
+
+ goto success;
+
+full_failed:
+ kfree(psy->charging_trig_name);
+charging_failed:
+ kfree(psy->charging_full_trig_name);
+charging_full_failed:
+ rc = -ENOMEM;
+success:
+ return rc;
+}
+
+static void power_supply_remove_bat_triggers(struct power_supply *psy)
+{
+ led_trigger_unregister_simple(psy->charging_full_trig);
+ led_trigger_unregister_simple(psy->charging_trig);
+ led_trigger_unregister_simple(psy->full_trig);
+ kfree(psy->full_trig_name);
+ kfree(psy->charging_trig_name);
+ kfree(psy->charging_full_trig_name);
+ return;
+}
+
+/* Generated power specific LEDs triggers. */
+
+static void power_supply_update_gen_leds(struct power_supply *psy)
+{
+ union power_supply_propval online;
+
+ if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online))
+ return;
+
+ dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, online.intval);
+
+ if (online.intval)
+ led_trigger_event(psy->online_trig, LED_FULL);
+ else
+ led_trigger_event(psy->online_trig, LED_OFF);
+
+ return;
+}
+
+static int power_supply_create_gen_triggers(struct power_supply *psy)
+{
+ int rc = 0;
+
+ psy->online_trig_name = kmalloc(strlen(psy->name) + sizeof("-online"),
+ GFP_KERNEL);
+ if (!psy->online_trig_name)
+ goto online_failed;
+
+ strcpy(psy->online_trig_name, psy->name);
+ strcat(psy->online_trig_name, "-online");
+
+ led_trigger_register_simple(psy->online_trig_name, &psy->online_trig);
+
+ goto success;
+
+online_failed:
+ rc = -ENOMEM;
+success:
+ return rc;
+}
+
+static void power_supply_remove_gen_triggers(struct power_supply *psy)
+{
+ led_trigger_unregister_simple(psy->online_trig);
+ kfree(psy->online_trig_name);
+ return;
+}
+
+/* Choice what triggers to create&update. */
+
+void power_supply_update_leds(struct power_supply *psy)
+{
+ if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
+ power_supply_update_bat_leds(psy);
+ else
+ power_supply_update_gen_leds(psy);
+ return;
+}
+
+int power_supply_create_triggers(struct power_supply *psy)
+{
+ if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
+ return power_supply_create_bat_triggers(psy);
+ return power_supply_create_gen_triggers(psy);
+}
+
+void power_supply_remove_triggers(struct power_supply *psy)
+{
+ if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
+ power_supply_remove_bat_triggers(psy);
+ else
+ power_supply_remove_gen_triggers(psy);
+ return;
+}
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
new file mode 100644
index 000000000000..c07d4258d347
--- /dev/null
+++ b/drivers/power/power_supply_sysfs.c
@@ -0,0 +1,299 @@
+/*
+ * Sysfs interface for the universal power supply monitor class
+ *
+ * Copyright © 2007 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
+ * Copyright © 2004 Szabolcs Gyurko
+ * Copyright © 2003 Ian Molton <spyro@f2s.com>
+ *
+ * Modified: 2004, Oct Szabolcs Gyurko
+ *
+ * You may use this code as per GPL version 2
+ */
+
+#include <linux/ctype.h>
+#include <linux/power_supply.h>
+
+/*
+ * This is because the name "current" breaks the device attr macro.
+ * The "current" word resolves to "(get_current())" so instead of
+ * "current" "(get_current())" appears in the sysfs.
+ *
+ * The source of this definition is the device.h which calls __ATTR
+ * macro in sysfs.h which calls the __stringify macro.
+ *
+ * Only modification that the name is not tried to be resolved
+ * (as a macro let's say).
+ */
+
+#define POWER_SUPPLY_ATTR(_name) \
+{ \
+ .attr = { .name = #_name, .mode = 0444, .owner = THIS_MODULE }, \
+ .show = power_supply_show_property, \
+ .store = NULL, \
+}
+
+static struct device_attribute power_supply_attrs[];
+
+static ssize_t power_supply_show_property(struct device *dev,
+ struct device_attribute *attr,
+ char *buf) {
+ static char *status_text[] = {
+ "Unknown", "Charging", "Discharging", "Not charging", "Full"
+ };
+ static char *health_text[] = {
+ "Unknown", "Good", "Overheat", "Dead", "Over voltage",
+ "Unspecified failure"
+ };
+ static char *technology_text[] = {
+ "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd"
+ };
+ static char *capacity_level_text[] = {
+ "Unknown", "Critical", "Low", "Normal", "High", "Full"
+ };
+ ssize_t ret;
+ struct power_supply *psy = dev_get_drvdata(dev);
+ const ptrdiff_t off = attr - power_supply_attrs;
+ union power_supply_propval value;
+
+ ret = psy->get_property(psy, off, &value);
+
+ if (ret < 0) {
+ if (ret != -ENODEV)
+ dev_err(dev, "driver failed to report `%s' property\n",
+ attr->attr.name);
+ return ret;
+ }
+
+ if (off == POWER_SUPPLY_PROP_STATUS)
+ return sprintf(buf, "%s\n", status_text[value.intval]);
+ else if (off == POWER_SUPPLY_PROP_HEALTH)
+ return sprintf(buf, "%s\n", health_text[value.intval]);
+ else if (off == POWER_SUPPLY_PROP_TECHNOLOGY)
+ return sprintf(buf, "%s\n", technology_text[value.intval]);
+ else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL)
+ return sprintf(buf, "%s\n",
+ capacity_level_text[value.intval]);
+ else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
+ return sprintf(buf, "%s\n", value.strval);
+
+ return sprintf(buf, "%d\n", value.intval);
+}
+
+/* Must be in the same order as POWER_SUPPLY_PROP_* */
+static struct device_attribute power_supply_attrs[] = {
+ /* Properties of type `int' */
+ POWER_SUPPLY_ATTR(status),
+ POWER_SUPPLY_ATTR(health),
+ POWER_SUPPLY_ATTR(present),
+ POWER_SUPPLY_ATTR(online),
+ POWER_SUPPLY_ATTR(technology),
+ POWER_SUPPLY_ATTR(voltage_max_design),
+ POWER_SUPPLY_ATTR(voltage_min_design),
+ POWER_SUPPLY_ATTR(voltage_now),
+ POWER_SUPPLY_ATTR(voltage_avg),
+ POWER_SUPPLY_ATTR(current_now),
+ POWER_SUPPLY_ATTR(current_avg),
+ POWER_SUPPLY_ATTR(charge_full_design),
+ POWER_SUPPLY_ATTR(charge_empty_design),
+ POWER_SUPPLY_ATTR(charge_full),
+ POWER_SUPPLY_ATTR(charge_empty),
+ POWER_SUPPLY_ATTR(charge_now),
+ POWER_SUPPLY_ATTR(charge_avg),
+ POWER_SUPPLY_ATTR(energy_full_design),
+ POWER_SUPPLY_ATTR(energy_empty_design),
+ POWER_SUPPLY_ATTR(energy_full),
+ POWER_SUPPLY_ATTR(energy_empty),
+ POWER_SUPPLY_ATTR(energy_now),
+ POWER_SUPPLY_ATTR(energy_avg),
+ POWER_SUPPLY_ATTR(capacity),
+ POWER_SUPPLY_ATTR(capacity_level),
+ POWER_SUPPLY_ATTR(temp),
+ POWER_SUPPLY_ATTR(temp_ambient),
+ POWER_SUPPLY_ATTR(time_to_empty_now),
+ POWER_SUPPLY_ATTR(time_to_empty_avg),
+ POWER_SUPPLY_ATTR(time_to_full_now),
+ POWER_SUPPLY_ATTR(time_to_full_avg),
+ /* Properties of type `const char *' */
+ POWER_SUPPLY_ATTR(model_name),
+ POWER_SUPPLY_ATTR(manufacturer),
+};
+
+static ssize_t power_supply_show_static_attrs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf) {
+ static char *type_text[] = { "Battery", "UPS", "Mains", "USB" };
+ struct power_supply *psy = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%s\n", type_text[psy->type]);
+}
+
+static struct device_attribute power_supply_static_attrs[] = {
+ __ATTR(type, 0444, power_supply_show_static_attrs, NULL),
+};
+
+int power_supply_create_attrs(struct power_supply *psy)
+{
+ int rc = 0;
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) {
+ rc = device_create_file(psy->dev,
+ &power_supply_static_attrs[i]);
+ if (rc)
+ goto statics_failed;
+ }
+
+ for (j = 0; j < psy->num_properties; j++) {
+ rc = device_create_file(psy->dev,
+ &power_supply_attrs[psy->properties[j]]);
+ if (rc)
+ goto dynamics_failed;
+ }
+
+ goto succeed;
+
+dynamics_failed:
+ while (j--)
+ device_remove_file(psy->dev,
+ &power_supply_attrs[psy->properties[j]]);
+statics_failed:
+ while (i--)
+ device_remove_file(psy->dev,
+ &power_supply_static_attrs[psy->properties[i]]);
+succeed:
+ return rc;
+}
+
+void power_supply_remove_attrs(struct power_supply *psy)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++)
+ device_remove_file(psy->dev,
+ &power_supply_static_attrs[i]);
+
+ for (i = 0; i < psy->num_properties; i++)
+ device_remove_file(psy->dev,
+ &power_supply_attrs[psy->properties[i]]);
+
+ return;
+}
+
+static char *kstruprdup(const char *str, gfp_t gfp)
+{
+ char *ret, *ustr;
+
+ ustr = ret = kmalloc(strlen(str) + 1, gfp);
+
+ if (!ret)
+ return NULL;
+
+ while (*str)
+ *ustr++ = toupper(*str++);
+
+ *ustr = 0;
+
+ return ret;
+}
+
+int power_supply_uevent(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ struct power_supply *psy = dev_get_drvdata(dev);
+ int i = 0, length = 0, ret = 0, j;
+ char *prop_buf;
+ char *attrname;
+
+ dev_dbg(dev, "uevent\n");
+
+ if (!psy) {
+ dev_dbg(dev, "No power supply yet\n");
+ return ret;
+ }
+
+ dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name);
+
+ ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "POWER_SUPPLY_NAME=%s", psy->name);
+ if (ret)
+ return ret;
+
+ prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
+ if (!prop_buf)
+ return -ENOMEM;
+
+ for (j = 0; j < ARRAY_SIZE(power_supply_static_attrs); j++) {
+ struct device_attribute *attr;
+ char *line;
+
+ attr = &power_supply_static_attrs[j];
+
+ ret = power_supply_show_static_attrs(dev, attr, prop_buf);
+ if (ret < 0)
+ goto out;
+
+ line = strchr(prop_buf, '\n');
+ if (line)
+ *line = 0;
+
+ attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
+ if (!attrname) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf);
+
+ ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "POWER_SUPPLY_%s=%s",
+ attrname, prop_buf);
+ kfree(attrname);
+ if (ret)
+ goto out;
+ }
+
+ dev_dbg(dev, "%zd dynamic props\n", psy->num_properties);
+
+ for (j = 0; j < psy->num_properties; j++) {
+ struct device_attribute *attr;
+ char *line;
+
+ attr = &power_supply_attrs[psy->properties[j]];
+
+ ret = power_supply_show_property(dev, attr, prop_buf);
+ if (ret == -ENODEV) {
+ /* When a battery is absent, we expect -ENODEV. Don't abort;
+ send the uevent with at least the the PRESENT=0 property */
+ ret = 0;
+ continue;
+ }
+
+ if (ret < 0)
+ goto out;
+
+ line = strchr(prop_buf, '\n');
+ if (line)
+ *line = 0;
+
+ attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
+ if (!attrname) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
+
+ ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "POWER_SUPPLY_%s=%s",
+ attrname, prop_buf);
+ kfree(attrname);
+ if (ret)
+ goto out;
+ }
+
+out:
+ free_page((unsigned long)prop_buf);
+
+ return ret;
+}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 8b3b0f4a157c..ac7e8ef504cb 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL;
static struct proc_dir_entry *dasd_devices_entry = NULL;
static struct proc_dir_entry *dasd_statistics_entry = NULL;
+#ifdef CONFIG_DASD_PROFILE
static char *
dasd_get_user_string(const char __user *user_buf, size_t user_len)
{
@@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len)
buffer[user_len] = 0;
return buffer;
}
+#endif /* CONFIG_DASD_PROFILE */
static int
dasd_devices_show(struct seq_file *m, void *v)
@@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off,
return len;
}
+#ifdef CONFIG_DASD_PROFILE
static char *
dasd_statistics_array(char *str, unsigned int *array, int shift)
{
@@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift)
str += sprintf(str,"\n");
return str;
}
+#endif /* CONFIG_DASD_PROFILE */
static int
dasd_statistics_read(char *page, char **start, off_t off,
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index dbb99d1b6f57..c7318a125852 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -72,6 +72,18 @@ typedef unsigned int sclp_cmdw_t;
typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
+struct sccb_header {
+ u16 length;
+ u8 function_code;
+ u8 control_mask[3];
+ u16 response_code;
+} __attribute__((packed));
+
+extern u64 sclp_facilities;
+
+#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
+#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
+
struct gds_subvector {
u8 length;
u8 key;
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c
index a66b914519b5..c68f5e7e63a0 100644
--- a/drivers/s390/char/sclp_chp.c
+++ b/drivers/s390/char/sclp_chp.c
@@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd)
struct chp_cfg_data *data;
int rc;
+ if (!SCLP_HAS_CHP_RECONFIG)
+ return -EOPNOTSUPP;
/* Prepare sccb. */
data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!data)
@@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info)
struct chp_info_data *data;
int rc;
+ if (!SCLP_HAS_CHP_INFO)
+ return -EOPNOTSUPP;
/* Prepare sccb. */
data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!data)
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c
index 7bcbe643b087..a1136e052750 100644
--- a/drivers/s390/char/sclp_info.c
+++ b/drivers/s390/char/sclp_info.c
@@ -11,47 +11,106 @@
#include <asm/sclp.h>
#include "sclp.h"
-struct sclp_readinfo_sccb s390_readinfo_sccb;
+struct sclp_readinfo_sccb {
+ struct sccb_header header; /* 0-7 */
+ u16 rnmax; /* 8-9 */
+ u8 rnsize; /* 10 */
+ u8 _reserved0[24 - 11]; /* 11-23 */
+ u8 loadparm[8]; /* 24-31 */
+ u8 _reserved1[48 - 32]; /* 32-47 */
+ u64 facilities; /* 48-55 */
+ u8 _reserved2[91 - 56]; /* 56-90 */
+ u8 flags; /* 91 */
+ u8 _reserved3[100 - 92]; /* 92-99 */
+ u32 rnsize2; /* 100-103 */
+ u64 rnmax2; /* 104-111 */
+ u8 _reserved4[4096 - 112]; /* 112-4095 */
+} __attribute__((packed, aligned(4096)));
+
+static struct sclp_readinfo_sccb __initdata early_readinfo_sccb;
+static int __initdata early_readinfo_sccb_valid;
+
+u64 sclp_facilities;
void __init sclp_readinfo_early(void)
{
- sclp_cmdw_t command;
- struct sccb_header *sccb;
int ret;
+ int i;
+ struct sclp_readinfo_sccb *sccb;
+ sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
+ SCLP_CMDW_READ_SCP_INFO};
- __ctl_set_bit(0, 9); /* enable service signal subclass mask */
-
- sccb = &s390_readinfo_sccb.header;
- command = SCLP_CMDW_READ_SCP_INFO_FORCED;
- while (1) {
- u16 response;
-
- memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb));
- sccb->length = sizeof(s390_readinfo_sccb);
- sccb->control_mask[2] = 0x80;
-
- ret = sclp_service_call(command, &s390_readinfo_sccb);
-
- if (ret == -EIO)
- goto out;
- if (ret == -EBUSY)
- continue;
+ /* Enable service signal subclass mask. */
+ __ctl_set_bit(0, 9);
+ sccb = &early_readinfo_sccb;
+ for (i = 0; i < ARRAY_SIZE(commands); i++) {
+ do {
+ memset(sccb, 0, sizeof(*sccb));
+ sccb->header.length = sizeof(*sccb);
+ sccb->header.control_mask[2] = 0x80;
+ ret = sclp_service_call(commands[i], sccb);
+ } while (ret == -EBUSY);
+ if (ret)
+ break;
__load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
PSW_MASK_WAIT | PSW_DEFAULT_KEY);
local_irq_disable();
+ /*
+ * Contents of the sccb might have changed
+ * therefore a barrier is needed.
+ */
barrier();
+ if (sccb->header.response_code == 0x10) {
+ early_readinfo_sccb_valid = 1;
+ break;
+ }
+ if (sccb->header.response_code != 0x1f0)
+ break;
+ }
+ /* Disable service signal subclass mask again. */
+ __ctl_clear_bit(0, 9);
+}
- response = sccb->response_code;
+void __init sclp_facilities_detect(void)
+{
+ if (!early_readinfo_sccb_valid)
+ return;
+ sclp_facilities = early_readinfo_sccb.facilities;
+}
- if (response == 0x10)
- break;
+unsigned long long __init sclp_memory_detect(void)
+{
+ unsigned long long memsize;
+ struct sclp_readinfo_sccb *sccb;
- if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO)
- break;
+ if (!early_readinfo_sccb_valid)
+ return 0;
+ sccb = &early_readinfo_sccb;
+ if (sccb->rnsize)
+ memsize = sccb->rnsize << 20;
+ else
+ memsize = sccb->rnsize2 << 20;
+ if (sccb->rnmax)
+ memsize *= sccb->rnmax;
+ else
+ memsize *= sccb->rnmax2;
+ return memsize;
+}
- command = SCLP_CMDW_READ_SCP_INFO;
- }
-out:
- __ctl_clear_bit(0, 9); /* disable service signal subclass mask */
+/*
+ * This function will be called after sclp_memory_detect(), which gets called
+ * early from early.c code. Therefore the sccb should have valid contents.
+ */
+void __init sclp_get_ipl_info(struct sclp_ipl_info *info)
+{
+ struct sclp_readinfo_sccb *sccb;
+
+ if (!early_readinfo_sccb_valid)
+ return;
+ sccb = &early_readinfo_sccb;
+ info->is_valid = 1;
+ if (sccb->flags & 0x2)
+ info->has_dump = 1;
+ memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);
}
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index fce3dac5cb3e..82e6a6b253eb 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static const struct file_operations vmcp_fops = {
.owner = THIS_MODULE,
- .open = &vmcp_open,
- .release = &vmcp_release,
- .read = &vmcp_read,
- .llseek = &no_llseek,
- .write = &vmcp_write,
- .unlocked_ioctl = &vmcp_ioctl,
- .compat_ioctl = &vmcp_ioctl
+ .open = vmcp_open,
+ .release = vmcp_release,
+ .read = vmcp_read,
+ .write = vmcp_write,
+ .unlocked_ioctl = vmcp_ioctl,
+ .compat_ioctl = vmcp_ioctl
};
static struct miscdevice vmcp_dev = {
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index a5a00e9ae4d0..12f7a4ce82c1 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void)
}
-static int vmlogrdr_init(void)
+static int __init vmlogrdr_init(void)
{
int rc;
int i;
@@ -885,7 +885,7 @@ cleanup:
}
-static void vmlogrdr_exit(void)
+static void __exit vmlogrdr_exit(void)
{
vmlogrdr_cleanup();
printk (KERN_INFO "vmlogrdr: driver unloaded\n");
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 4e711a985d59..3712ede16723 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count)
return rc;
}
-static int memcpy_real_user(__user void *dest, unsigned long src, size_t count)
+static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
{
static char buf[4096];
int offs = 0, size;
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 997f46874537..60b9347f7c92 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -27,7 +27,6 @@
/*
* diag210 is used under VM to get information about a virtual device
*/
-#ifdef CONFIG_64BIT
int
diag210(struct diag210 * addr)
{
@@ -43,6 +42,7 @@ diag210(struct diag210 * addr)
spin_lock_irqsave(&diag210_lock, flags);
diag210_tmp = *addr;
+#ifdef CONFIG_64BIT
asm volatile(
" lhi %0,-1\n"
" sam31\n"
@@ -51,19 +51,8 @@ diag210(struct diag210 * addr)
" srl %0,28\n"
"1: sam64\n"
EX_TABLE(0b,1b)
- : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory");
-
- *addr = diag210_tmp;
- spin_unlock_irqrestore(&diag210_lock, flags);
-
- return ccode;
-}
+ : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
#else
-int
-diag210(struct diag210 * addr)
-{
- int ccode;
-
asm volatile(
" lhi %0,-1\n"
" diag %1,0,0x210\n"
@@ -71,11 +60,14 @@ diag210(struct diag210 * addr)
" srl %0,28\n"
"1:\n"
EX_TABLE(0b,1b)
- : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory");
+ : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
+#endif
+
+ *addr = diag210_tmp;
+ spin_unlock_irqrestore(&diag210_lock, flags);
return ccode;
}
-#endif
/*
* Input :
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 5aac0ec36368..90bd22014513 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long);
static void ap_poll_timeout(unsigned long);
static int ap_poll_thread_start(void);
static void ap_poll_thread_stop(void);
+static void ap_request_timeout(unsigned long);
/**
* Module description.
@@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
case AP_RESPONSE_NORMAL:
return 0;
case AP_RESPONSE_Q_FULL:
+ case AP_RESPONSE_RESET_IN_PROGRESS:
return -EBUSY;
default: /* Device is gone. */
return -ENODEV;
@@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
if (status.queue_empty)
return -ENOENT;
return -EBUSY;
+ case AP_RESPONSE_RESET_IN_PROGRESS:
+ return -EBUSY;
default:
return -ENODEV;
}
@@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid)
i = AP_MAX_RESET; /* return with -ENODEV */
break;
case AP_RESPONSE_RESET_IN_PROGRESS:
+ rc = -EBUSY;
case AP_RESPONSE_BUSY:
default:
break;
}
- if (rc != -ENODEV)
+ if (rc != -ENODEV && rc != -EBUSY)
break;
if (i < AP_MAX_RESET - 1) {
udelay(5);
@@ -341,6 +346,40 @@ static int ap_init_queue(ap_qid_t qid)
}
/**
+ * Arm request timeout if a AP device was idle and a new request is submitted.
+ */
+static void ap_increase_queue_count(struct ap_device *ap_dev)
+{
+ int timeout = ap_dev->drv->request_timeout;
+
+ ap_dev->queue_count++;
+ if (ap_dev->queue_count == 1) {
+ mod_timer(&ap_dev->timeout, jiffies + timeout);
+ ap_dev->reset = AP_RESET_ARMED;
+ }
+}
+
+/**
+ * AP device is still alive, re-schedule request timeout if there are still
+ * pending requests.
+ */
+static void ap_decrease_queue_count(struct ap_device *ap_dev)
+{
+ int timeout = ap_dev->drv->request_timeout;
+
+ ap_dev->queue_count--;
+ if (ap_dev->queue_count > 0)
+ mod_timer(&ap_dev->timeout, jiffies + timeout);
+ else
+ /**
+ * The timeout timer should to be disabled now - since
+ * del_timer_sync() is very expensive, we just tell via the
+ * reset flag to ignore the pending timeout timer.
+ */
+ ap_dev->reset = AP_RESET_IGNORE;
+}
+
+/**
* AP device related attributes.
*/
static ssize_t ap_hwtype_show(struct device *dev,
@@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev)
struct ap_driver *ap_drv = ap_dev->drv;
ap_flush_queue(ap_dev);
+ del_timer_sync(&ap_dev->timeout);
if (ap_drv->remove)
ap_drv->remove(ap_dev);
spin_lock_bh(&ap_device_lock);
@@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused)
__ap_scan_bus);
rc = ap_query_queue(qid, &queue_depth, &device_type);
if (dev) {
+ if (rc == -EBUSY) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(AP_RESET_TIMEOUT);
+ rc = ap_query_queue(qid, &queue_depth,
+ &device_type);
+ }
ap_dev = to_ap_dev(dev);
spin_lock_bh(&ap_dev->lock);
if (rc || ap_dev->unregistered) {
spin_unlock_bh(&ap_dev->lock);
- put_device(dev);
device_unregister(dev);
+ put_device(dev);
continue;
- } else
- spin_unlock_bh(&ap_dev->lock);
- }
- if (dev) {
+ }
+ spin_unlock_bh(&ap_dev->lock);
put_device(dev);
continue;
}
@@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused)
INIT_LIST_HEAD(&ap_dev->pendingq);
INIT_LIST_HEAD(&ap_dev->requestq);
INIT_LIST_HEAD(&ap_dev->list);
+ setup_timer(&ap_dev->timeout, ap_request_timeout,
+ (unsigned long) ap_dev);
if (device_type == 0)
ap_probe_device_type(ap_dev);
else
@@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
switch (status.response_code) {
case AP_RESPONSE_NORMAL:
atomic_dec(&ap_poll_requests);
- ap_dev->queue_count--;
+ ap_decrease_queue_count(ap_dev);
list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
if (ap_msg->psmid != ap_dev->reply->psmid)
continue;
@@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
switch (status.response_code) {
case AP_RESPONSE_NORMAL:
atomic_inc(&ap_poll_requests);
- ap_dev->queue_count++;
+ ap_increase_queue_count(ap_dev);
list_move_tail(&ap_msg->list, &ap_dev->pendingq);
ap_dev->requestq_count--;
ap_dev->pendingq_count++;
@@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
*flags |= 2;
break;
case AP_RESPONSE_Q_FULL:
+ case AP_RESPONSE_RESET_IN_PROGRESS:
*flags |= 2;
break;
case AP_RESPONSE_MESSAGE_TOO_BIG:
@@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms
list_add_tail(&ap_msg->list, &ap_dev->pendingq);
atomic_inc(&ap_poll_requests);
ap_dev->pendingq_count++;
- ap_dev->queue_count++;
+ ap_increase_queue_count(ap_dev);
ap_dev->total_request_count++;
break;
case AP_RESPONSE_Q_FULL:
+ case AP_RESPONSE_RESET_IN_PROGRESS:
list_add_tail(&ap_msg->list, &ap_dev->requestq);
ap_dev->requestq_count++;
ap_dev->total_request_count++;
@@ -1046,6 +1094,25 @@ static void ap_poll_timeout(unsigned long unused)
}
/**
+ * Reset a not responding AP device and move all requests from the
+ * pending queue to the request queue.
+ */
+static void ap_reset(struct ap_device *ap_dev)
+{
+ int rc;
+
+ ap_dev->reset = AP_RESET_IGNORE;
+ atomic_sub(ap_dev->queue_count, &ap_poll_requests);
+ ap_dev->queue_count = 0;
+ list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
+ ap_dev->requestq_count += ap_dev->pendingq_count;
+ ap_dev->pendingq_count = 0;
+ rc = ap_init_queue(ap_dev->qid);
+ if (rc == -ENODEV)
+ ap_dev->unregistered = 1;
+}
+
+/**
* Poll all AP devices on the bus in a round robin fashion. Continue
* polling until bit 2^0 of the control flags is not set. If bit 2^1
* of the control flags has been set arm the poll timer.
@@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
if (!ap_dev->unregistered) {
if (ap_poll_queue(ap_dev, flags))
ap_dev->unregistered = 1;
+ if (ap_dev->reset == AP_RESET_DO)
+ ap_reset(ap_dev);
}
spin_unlock(&ap_dev->lock);
return 0;
@@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void)
mutex_unlock(&ap_poll_thread_mutex);
}
+/**
+ * Handling of request timeouts
+ */
+static void ap_request_timeout(unsigned long data)
+{
+ struct ap_device *ap_dev = (struct ap_device *) data;
+
+ if (ap_dev->reset == AP_RESET_ARMED)
+ ap_dev->reset = AP_RESET_DO;
+}
+
static void ap_reset_domain(void)
{
int i;
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 008559ea742b..87c2d6442875 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -33,6 +33,7 @@
#define AP_DEVICES 64 /* Number of AP devices. */
#define AP_DOMAINS 16 /* Number of AP domains. */
#define AP_MAX_RESET 90 /* Maximum number of resets. */
+#define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */
#define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
#define AP_POLL_TIME 1 /* Time in ticks between receive polls. */
@@ -83,6 +84,13 @@ struct ap_queue_status {
#define AP_DEVICE_TYPE_CEX2A 6
#define AP_DEVICE_TYPE_CEX2C 7
+/**
+ * AP reset flag states
+ */
+#define AP_RESET_IGNORE 0 /* request timeout will be ignored */
+#define AP_RESET_ARMED 1 /* request timeout timer is active */
+#define AP_RESET_DO 2 /* AP reset required */
+
struct ap_device;
struct ap_message;
@@ -95,6 +103,7 @@ struct ap_driver {
/* receive is called from tasklet context */
void (*receive)(struct ap_device *, struct ap_message *,
struct ap_message *);
+ int request_timeout; /* request timeout in jiffies */
};
#define to_ap_drv(x) container_of((x), struct ap_driver, driver)
@@ -112,6 +121,8 @@ struct ap_device {
int queue_depth; /* AP queue depth.*/
int device_type; /* AP device type. */
int unregistered; /* marks AP device as unregistered */
+ struct timer_list timeout; /* Timer for request timeouts. */
+ int reset; /* Reset required after req. timeout. */
int queue_count; /* # messages currently on AP queue. */
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 5bb13a9d0898..08657f604b8c 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = {
.remove = zcrypt_cex2a_remove,
.receive = zcrypt_cex2a_receive,
.ids = zcrypt_cex2a_ids,
+ .request_timeout = CEX2A_CLEANUP_TIME,
};
/**
@@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
goto out_free;
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &work, CEX2A_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&work);
+ if (rc == 0)
rc = convert_response(zdev, &ap_msg, mex->outputdata,
mex->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
kfree(ap_msg.message);
return rc;
@@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
goto out_free;
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &work, CEX2A_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&work);
+ if (rc == 0)
rc = convert_response(zdev, &ap_msg, crt->outputdata,
crt->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
kfree(ap_msg.message);
return rc;
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 818ffe05ac00..6e93b4751782 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = {
.remove = zcrypt_pcica_remove,
.receive = zcrypt_pcica_receive,
.ids = zcrypt_pcica_ids,
+ .request_timeout = PCICA_CLEANUP_TIME,
};
/**
@@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
goto out_free;
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &work, PCICA_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&work);
+ if (rc == 0)
rc = convert_response(zdev, &ap_msg, mex->outputdata,
mex->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
kfree(ap_msg.message);
return rc;
@@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
goto out_free;
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &work, PCICA_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&work);
+ if (rc == 0)
rc = convert_response(zdev, &ap_msg, crt->outputdata,
crt->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
kfree(ap_msg.message);
return rc;
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index f295a403b29a..d6d59bf9ac38 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = {
.remove = zcrypt_pcicc_remove,
.receive = zcrypt_pcicc_receive,
.ids = zcrypt_pcicc_ids,
+ .request_timeout = PCICC_CLEANUP_TIME,
};
/**
@@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
goto out_free;
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &work, PCICC_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&work);
+ if (rc == 0)
rc = convert_response(zdev, &ap_msg, mex->outputdata,
mex->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
free_page((unsigned long) ap_msg.message);
return rc;
@@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
goto out_free;
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &work, PCICC_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&work);
+ if (rc == 0)
rc = convert_response(zdev, &ap_msg, crt->outputdata,
crt->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
free_page((unsigned long) ap_msg.message);
return rc;
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 252443b6bd1b..64948788d301 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = {
.remove = zcrypt_pcixcc_remove,
.receive = zcrypt_pcixcc_receive,
.ids = zcrypt_pcixcc_ids,
+ .request_timeout = PCIXCC_CLEANUP_TIME,
};
/**
@@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
goto out_free;
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &resp_type.work, PCIXCC_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&resp_type.work);
+ if (rc == 0)
rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
mex->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
free_page((unsigned long) ap_msg.message);
return rc;
@@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
goto out_free;
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &resp_type.work, PCIXCC_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&resp_type.work);
+ if (rc == 0)
rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
crt->outputdatalength);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
free_page((unsigned long) ap_msg.message);
return rc;
@@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
goto out_free;
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
- rc = wait_for_completion_interruptible_timeout(
- &resp_type.work, PCIXCC_CLEANUP_TIME);
- if (rc > 0)
+ rc = wait_for_completion_interruptible(&resp_type.work);
+ if (rc == 0)
rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
- else {
- /* Signal pending or message timed out. */
+ else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
- if (rc == 0)
- /* Message timed out. */
- rc = -ETIME;
- }
out_free:
memset(ap_msg.message, 0x0, ap_msg.length);
kfree(ap_msg.message);
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 61de78a9f6ee..4fff61b32dcb 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -143,7 +143,7 @@ static struct console sercons;
static unsigned long break_pressed; /* break, really ... */
#endif
-static unsigned char zs_init_regs[16] __initdata = {
+static unsigned char zs_init_regs[16] = {
0, /* write 0 */
0, /* write 1 */
0, /* write 2 */
@@ -1581,7 +1581,7 @@ static void __init show_serial_version(void)
/* Initialize Z8530s zs_channels
*/
-static void __init probe_sccs(void)
+static void probe_sccs(void)
{
struct dec_serial **pp;
int i, n, n_chips = 0, n_channels, chip, channel;
@@ -1923,7 +1923,7 @@ static struct tty_driver *serial_console_device(struct console *c, int *index)
* - initialize the serial port
* Return non-zero if we didn't find a serial port.
*/
-static int __init serial_console_setup(struct console *co, char *options)
+static int serial_console_setup(struct console *co, char *options)
{
struct dec_serial *info;
int baud = 9600;
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index 904e5aeb696c..df95d6c2cefa 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -35,4 +35,17 @@ config W1_SLAVE_DS2433_CRC
Each block has 30 bytes of data and a two byte CRC16.
Full block writes are only allowed if the CRC is valid.
+config W1_SLAVE_DS2760
+ tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)"
+ depends on W1
+ help
+ If you enable this you will have the DS2760 battery monitor
+ chip support.
+
+ The battery monitor chip is used in many batteries/devices
+ as the one who is responsible for charging/discharging/monitoring
+ Li+ batteries.
+
+ If you are unsure, say N.
+
endmenu
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 725dcfdfddb4..a8eb7524df1d 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -5,4 +5,5 @@
obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
+obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
new file mode 100644
index 000000000000..88a37fbccc3f
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.c
@@ -0,0 +1,213 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/idr.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+#include "../w1_family.h"
+#include "w1_ds2760.h"
+
+static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
+ int io)
+{
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+
+ if (!dev)
+ return 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ if (addr > DS2760_DATA_SIZE || addr < 0) {
+ count = 0;
+ goto out;
+ }
+ if (addr + count > DS2760_DATA_SIZE)
+ count = DS2760_DATA_SIZE - addr;
+
+ if (!w1_reset_select_slave(sl)) {
+ if (!io) {
+ w1_write_8(sl->master, W1_DS2760_READ_DATA);
+ w1_write_8(sl->master, addr);
+ count = w1_read_block(sl->master, buf, count);
+ } else {
+ w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
+ w1_write_8(sl->master, addr);
+ w1_write_block(sl->master, buf, count);
+ /* XXX w1_write_block returns void, not n_written */
+ }
+ }
+
+out:
+ mutex_unlock(&sl->master->mutex);
+
+ return count;
+}
+
+int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
+{
+ return w1_ds2760_io(dev, buf, addr, count, 0);
+}
+
+int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
+{
+ return w1_ds2760_io(dev, buf, addr, count, 1);
+}
+
+static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ return w1_ds2760_read(dev, buf, off, count);
+}
+
+static struct bin_attribute w1_ds2760_bin_attr = {
+ .attr = {
+ .name = "w1_slave",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = DS2760_DATA_SIZE,
+ .read = w1_ds2760_read_bin,
+};
+
+static DEFINE_IDR(bat_idr);
+static DEFINE_MUTEX(bat_idr_lock);
+
+static int new_bat_id(void)
+{
+ int ret;
+
+ while (1) {
+ int id;
+
+ ret = idr_pre_get(&bat_idr, GFP_KERNEL);
+ if (ret == 0)
+ return -ENOMEM;
+
+ mutex_lock(&bat_idr_lock);
+ ret = idr_get_new(&bat_idr, NULL, &id);
+ mutex_unlock(&bat_idr_lock);
+
+ if (ret == 0) {
+ ret = id & MAX_ID_MASK;
+ break;
+ } else if (ret == -EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static void release_bat_id(int id)
+{
+ mutex_lock(&bat_idr_lock);
+ idr_remove(&bat_idr, id);
+ mutex_unlock(&bat_idr_lock);
+
+ return;
+}
+
+static int w1_ds2760_add_slave(struct w1_slave *sl)
+{
+ int ret;
+ int id;
+ struct platform_device *pdev;
+
+ id = new_bat_id();
+ if (id < 0) {
+ ret = id;
+ goto noid;
+ }
+
+ pdev = platform_device_alloc("ds2760-battery", id);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto pdev_alloc_failed;
+ }
+ pdev->dev.parent = &sl->dev;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto pdev_add_failed;
+
+ ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+ if (ret)
+ goto bin_attr_failed;
+
+ dev_set_drvdata(&sl->dev, pdev);
+
+ goto success;
+
+bin_attr_failed:
+pdev_add_failed:
+ platform_device_unregister(pdev);
+pdev_alloc_failed:
+ release_bat_id(id);
+noid:
+success:
+ return ret;
+}
+
+static void w1_ds2760_remove_slave(struct w1_slave *sl)
+{
+ struct platform_device *pdev = dev_get_drvdata(&sl->dev);
+ int id = pdev->id;
+
+ platform_device_unregister(pdev);
+ release_bat_id(id);
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+
+ return;
+}
+
+static struct w1_family_ops w1_ds2760_fops = {
+ .add_slave = w1_ds2760_add_slave,
+ .remove_slave = w1_ds2760_remove_slave,
+};
+
+static struct w1_family w1_ds2760_family = {
+ .fid = W1_FAMILY_DS2760,
+ .fops = &w1_ds2760_fops,
+};
+
+static int __init w1_ds2760_init(void)
+{
+ printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor "
+ " chip - (c) 2004-2005, Szabolcs Gyurko\n");
+ idr_init(&bat_idr);
+ return w1_register_family(&w1_ds2760_family);
+}
+
+static void __exit w1_ds2760_exit(void)
+{
+ w1_unregister_family(&w1_ds2760_family);
+ idr_destroy(&bat_idr);
+}
+
+EXPORT_SYMBOL(w1_ds2760_read);
+EXPORT_SYMBOL(w1_ds2760_write);
+
+module_init(w1_ds2760_init);
+module_exit(w1_ds2760_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>");
+MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h
new file mode 100644
index 000000000000..f1302429cb02
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.h
@@ -0,0 +1,50 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#ifndef __w1_ds2760_h__
+#define __w1_ds2760_h__
+
+/* Known commands to the DS2760 chip */
+#define W1_DS2760_SWAP 0xAA
+#define W1_DS2760_READ_DATA 0x69
+#define W1_DS2760_WRITE_DATA 0x6C
+#define W1_DS2760_COPY_DATA 0x48
+#define W1_DS2760_RECALL_DATA 0xB8
+#define W1_DS2760_LOCK 0x6A
+
+/* Number of valid register addresses */
+#define DS2760_DATA_SIZE 0x40
+
+#define DS2760_PROTECTION_REG 0x00
+#define DS2760_STATUS_REG 0x01
+#define DS2760_EEPROM_REG 0x07
+#define DS2760_SPECIAL_FEATURE_REG 0x08
+#define DS2760_VOLTAGE_MSB 0x0c
+#define DS2760_VOLTAGE_LSB 0x0d
+#define DS2760_CURRENT_MSB 0x0e
+#define DS2760_CURRENT_LSB 0x0f
+#define DS2760_CURRENT_ACCUM_MSB 0x10
+#define DS2760_CURRENT_ACCUM_LSB 0x11
+#define DS2760_TEMP_MSB 0x18
+#define DS2760_TEMP_LSB 0x19
+#define DS2760_EEPROM_BLOCK0 0x20
+#define DS2760_ACTIVE_FULL 0x20
+#define DS2760_EEPROM_BLOCK1 0x30
+#define DS2760_RATED_CAPACITY 0x32
+#define DS2760_CURRENT_OFFSET_BIAS 0x33
+#define DS2760_ACTIVE_EMPTY 0x3b
+
+extern int w1_ds2760_read(struct device *dev, char *buf, int addr,
+ size_t count);
+extern int w1_ds2760_write(struct device *dev, char *buf, int addr,
+ size_t count);
+
+#endif /* !__w1_ds2760_h__ */
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 1e2ac40c2c14..ef1e1dafa19a 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -33,6 +33,7 @@
#define W1_THERM_DS1822 0x22
#define W1_EEPROM_DS2433 0x23
#define W1_THERM_DS18B20 0x28
+#define W1_FAMILY_DS2760 0x30
#define MAXNAMELEN 32