diff options
Diffstat (limited to 'drivers')
104 files changed, 2177 insertions, 1870 deletions
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 003a9876c968..5a8445959f67 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c | |||
@@ -352,7 +352,7 @@ static char *next_cmd(char **cmds) | |||
352 | return start; | 352 | return start; |
353 | } | 353 | } |
354 | 354 | ||
355 | static int driver_init(void) | 355 | static int ibm_acpi_driver_init(void) |
356 | { | 356 | { |
357 | printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); | 357 | printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); |
358 | printk(IBM_INFO "%s\n", IBM_URL); | 358 | printk(IBM_INFO "%s\n", IBM_URL); |
@@ -1605,7 +1605,7 @@ static int fan_write(char *buf) | |||
1605 | static struct ibm_struct ibms[] = { | 1605 | static struct ibm_struct ibms[] = { |
1606 | { | 1606 | { |
1607 | .name = "driver", | 1607 | .name = "driver", |
1608 | .init = driver_init, | 1608 | .init = ibm_acpi_driver_init, |
1609 | .read = driver_read, | 1609 | .read = driver_read, |
1610 | }, | 1610 | }, |
1611 | { | 1611 | { |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index dbae6d971041..b517d2493551 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -402,6 +402,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
402 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ | 402 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ |
403 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ | 403 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ |
404 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ | 404 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ |
405 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */ | ||
406 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */ | ||
407 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */ | ||
408 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */ | ||
409 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ | ||
410 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ | ||
411 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ | ||
412 | { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci }, /* MCP67 */ | ||
405 | { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */ | 413 | { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */ |
406 | { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */ | 414 | { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */ |
407 | { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */ | 415 | { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */ |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a4790be41d1c..836947da5b14 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -51,7 +51,7 @@ | |||
51 | 51 | ||
52 | #define SECTOR_SIZE 512 | 52 | #define SECTOR_SIZE 512 |
53 | 53 | ||
54 | typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd); | 54 | typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); |
55 | 55 | ||
56 | static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, | 56 | static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, |
57 | const struct scsi_device *scsidev); | 57 | const struct scsi_device *scsidev); |
@@ -935,7 +935,6 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |||
935 | /** | 935 | /** |
936 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | 936 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command |
937 | * @qc: Storage for translated ATA taskfile | 937 | * @qc: Storage for translated ATA taskfile |
938 | * @scsicmd: SCSI command to translate | ||
939 | * | 938 | * |
940 | * Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY | 939 | * Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY |
941 | * (to start). Perhaps these commands should be preceded by | 940 | * (to start). Perhaps these commands should be preceded by |
@@ -948,22 +947,25 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |||
948 | * RETURNS: | 947 | * RETURNS: |
949 | * Zero on success, non-zero on error. | 948 | * Zero on success, non-zero on error. |
950 | */ | 949 | */ |
951 | 950 | static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |
952 | static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, | ||
953 | const u8 *scsicmd) | ||
954 | { | 951 | { |
952 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
955 | struct ata_taskfile *tf = &qc->tf; | 953 | struct ata_taskfile *tf = &qc->tf; |
954 | const u8 *cdb = scmd->cmnd; | ||
955 | |||
956 | if (scmd->cmd_len < 5) | ||
957 | goto invalid_fld; | ||
956 | 958 | ||
957 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | 959 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; |
958 | tf->protocol = ATA_PROT_NODATA; | 960 | tf->protocol = ATA_PROT_NODATA; |
959 | if (scsicmd[1] & 0x1) { | 961 | if (cdb[1] & 0x1) { |
960 | ; /* ignore IMMED bit, violates sat-r05 */ | 962 | ; /* ignore IMMED bit, violates sat-r05 */ |
961 | } | 963 | } |
962 | if (scsicmd[4] & 0x2) | 964 | if (cdb[4] & 0x2) |
963 | goto invalid_fld; /* LOEJ bit set not supported */ | 965 | goto invalid_fld; /* LOEJ bit set not supported */ |
964 | if (((scsicmd[4] >> 4) & 0xf) != 0) | 966 | if (((cdb[4] >> 4) & 0xf) != 0) |
965 | goto invalid_fld; /* power conditions not supported */ | 967 | goto invalid_fld; /* power conditions not supported */ |
966 | if (scsicmd[4] & 0x1) { | 968 | if (cdb[4] & 0x1) { |
967 | tf->nsect = 1; /* 1 sector, lba=0 */ | 969 | tf->nsect = 1; /* 1 sector, lba=0 */ |
968 | 970 | ||
969 | if (qc->dev->flags & ATA_DFLAG_LBA) { | 971 | if (qc->dev->flags & ATA_DFLAG_LBA) { |
@@ -996,7 +998,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, | |||
996 | return 0; | 998 | return 0; |
997 | 999 | ||
998 | invalid_fld: | 1000 | invalid_fld: |
999 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); | 1001 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); |
1000 | /* "Invalid field in cbd" */ | 1002 | /* "Invalid field in cbd" */ |
1001 | return 1; | 1003 | return 1; |
1002 | } | 1004 | } |
@@ -1005,7 +1007,6 @@ invalid_fld: | |||
1005 | /** | 1007 | /** |
1006 | * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command | 1008 | * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command |
1007 | * @qc: Storage for translated ATA taskfile | 1009 | * @qc: Storage for translated ATA taskfile |
1008 | * @scsicmd: SCSI command to translate (ignored) | ||
1009 | * | 1010 | * |
1010 | * Sets up an ATA taskfile to issue FLUSH CACHE or | 1011 | * Sets up an ATA taskfile to issue FLUSH CACHE or |
1011 | * FLUSH CACHE EXT. | 1012 | * FLUSH CACHE EXT. |
@@ -1016,8 +1017,7 @@ invalid_fld: | |||
1016 | * RETURNS: | 1017 | * RETURNS: |
1017 | * Zero on success, non-zero on error. | 1018 | * Zero on success, non-zero on error. |
1018 | */ | 1019 | */ |
1019 | 1020 | static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc) | |
1020 | static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) | ||
1021 | { | 1021 | { |
1022 | struct ata_taskfile *tf = &qc->tf; | 1022 | struct ata_taskfile *tf = &qc->tf; |
1023 | 1023 | ||
@@ -1034,7 +1034,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs | |||
1034 | 1034 | ||
1035 | /** | 1035 | /** |
1036 | * scsi_6_lba_len - Get LBA and transfer length | 1036 | * scsi_6_lba_len - Get LBA and transfer length |
1037 | * @scsicmd: SCSI command to translate | 1037 | * @cdb: SCSI command to translate |
1038 | * | 1038 | * |
1039 | * Calculate LBA and transfer length for 6-byte commands. | 1039 | * Calculate LBA and transfer length for 6-byte commands. |
1040 | * | 1040 | * |
@@ -1042,18 +1042,17 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs | |||
1042 | * @plba: the LBA | 1042 | * @plba: the LBA |
1043 | * @plen: the transfer length | 1043 | * @plen: the transfer length |
1044 | */ | 1044 | */ |
1045 | 1045 | static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen) | |
1046 | static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | ||
1047 | { | 1046 | { |
1048 | u64 lba = 0; | 1047 | u64 lba = 0; |
1049 | u32 len = 0; | 1048 | u32 len = 0; |
1050 | 1049 | ||
1051 | VPRINTK("six-byte command\n"); | 1050 | VPRINTK("six-byte command\n"); |
1052 | 1051 | ||
1053 | lba |= ((u64)scsicmd[2]) << 8; | 1052 | lba |= ((u64)cdb[2]) << 8; |
1054 | lba |= ((u64)scsicmd[3]); | 1053 | lba |= ((u64)cdb[3]); |
1055 | 1054 | ||
1056 | len |= ((u32)scsicmd[4]); | 1055 | len |= ((u32)cdb[4]); |
1057 | 1056 | ||
1058 | *plba = lba; | 1057 | *plba = lba; |
1059 | *plen = len; | 1058 | *plen = len; |
@@ -1061,7 +1060,7 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | |||
1061 | 1060 | ||
1062 | /** | 1061 | /** |
1063 | * scsi_10_lba_len - Get LBA and transfer length | 1062 | * scsi_10_lba_len - Get LBA and transfer length |
1064 | * @scsicmd: SCSI command to translate | 1063 | * @cdb: SCSI command to translate |
1065 | * | 1064 | * |
1066 | * Calculate LBA and transfer length for 10-byte commands. | 1065 | * Calculate LBA and transfer length for 10-byte commands. |
1067 | * | 1066 | * |
@@ -1069,21 +1068,20 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | |||
1069 | * @plba: the LBA | 1068 | * @plba: the LBA |
1070 | * @plen: the transfer length | 1069 | * @plen: the transfer length |
1071 | */ | 1070 | */ |
1072 | 1071 | static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen) | |
1073 | static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | ||
1074 | { | 1072 | { |
1075 | u64 lba = 0; | 1073 | u64 lba = 0; |
1076 | u32 len = 0; | 1074 | u32 len = 0; |
1077 | 1075 | ||
1078 | VPRINTK("ten-byte command\n"); | 1076 | VPRINTK("ten-byte command\n"); |
1079 | 1077 | ||
1080 | lba |= ((u64)scsicmd[2]) << 24; | 1078 | lba |= ((u64)cdb[2]) << 24; |
1081 | lba |= ((u64)scsicmd[3]) << 16; | 1079 | lba |= ((u64)cdb[3]) << 16; |
1082 | lba |= ((u64)scsicmd[4]) << 8; | 1080 | lba |= ((u64)cdb[4]) << 8; |
1083 | lba |= ((u64)scsicmd[5]); | 1081 | lba |= ((u64)cdb[5]); |
1084 | 1082 | ||
1085 | len |= ((u32)scsicmd[7]) << 8; | 1083 | len |= ((u32)cdb[7]) << 8; |
1086 | len |= ((u32)scsicmd[8]); | 1084 | len |= ((u32)cdb[8]); |
1087 | 1085 | ||
1088 | *plba = lba; | 1086 | *plba = lba; |
1089 | *plen = len; | 1087 | *plen = len; |
@@ -1091,7 +1089,7 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | |||
1091 | 1089 | ||
1092 | /** | 1090 | /** |
1093 | * scsi_16_lba_len - Get LBA and transfer length | 1091 | * scsi_16_lba_len - Get LBA and transfer length |
1094 | * @scsicmd: SCSI command to translate | 1092 | * @cdb: SCSI command to translate |
1095 | * | 1093 | * |
1096 | * Calculate LBA and transfer length for 16-byte commands. | 1094 | * Calculate LBA and transfer length for 16-byte commands. |
1097 | * | 1095 | * |
@@ -1099,27 +1097,26 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | |||
1099 | * @plba: the LBA | 1097 | * @plba: the LBA |
1100 | * @plen: the transfer length | 1098 | * @plen: the transfer length |
1101 | */ | 1099 | */ |
1102 | 1100 | static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen) | |
1103 | static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | ||
1104 | { | 1101 | { |
1105 | u64 lba = 0; | 1102 | u64 lba = 0; |
1106 | u32 len = 0; | 1103 | u32 len = 0; |
1107 | 1104 | ||
1108 | VPRINTK("sixteen-byte command\n"); | 1105 | VPRINTK("sixteen-byte command\n"); |
1109 | 1106 | ||
1110 | lba |= ((u64)scsicmd[2]) << 56; | 1107 | lba |= ((u64)cdb[2]) << 56; |
1111 | lba |= ((u64)scsicmd[3]) << 48; | 1108 | lba |= ((u64)cdb[3]) << 48; |
1112 | lba |= ((u64)scsicmd[4]) << 40; | 1109 | lba |= ((u64)cdb[4]) << 40; |
1113 | lba |= ((u64)scsicmd[5]) << 32; | 1110 | lba |= ((u64)cdb[5]) << 32; |
1114 | lba |= ((u64)scsicmd[6]) << 24; | 1111 | lba |= ((u64)cdb[6]) << 24; |
1115 | lba |= ((u64)scsicmd[7]) << 16; | 1112 | lba |= ((u64)cdb[7]) << 16; |
1116 | lba |= ((u64)scsicmd[8]) << 8; | 1113 | lba |= ((u64)cdb[8]) << 8; |
1117 | lba |= ((u64)scsicmd[9]); | 1114 | lba |= ((u64)cdb[9]); |
1118 | 1115 | ||
1119 | len |= ((u32)scsicmd[10]) << 24; | 1116 | len |= ((u32)cdb[10]) << 24; |
1120 | len |= ((u32)scsicmd[11]) << 16; | 1117 | len |= ((u32)cdb[11]) << 16; |
1121 | len |= ((u32)scsicmd[12]) << 8; | 1118 | len |= ((u32)cdb[12]) << 8; |
1122 | len |= ((u32)scsicmd[13]); | 1119 | len |= ((u32)cdb[13]); |
1123 | 1120 | ||
1124 | *plba = lba; | 1121 | *plba = lba; |
1125 | *plen = len; | 1122 | *plen = len; |
@@ -1128,7 +1125,6 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | |||
1128 | /** | 1125 | /** |
1129 | * ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one | 1126 | * ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one |
1130 | * @qc: Storage for translated ATA taskfile | 1127 | * @qc: Storage for translated ATA taskfile |
1131 | * @scsicmd: SCSI command to translate | ||
1132 | * | 1128 | * |
1133 | * Converts SCSI VERIFY command to an ATA READ VERIFY command. | 1129 | * Converts SCSI VERIFY command to an ATA READ VERIFY command. |
1134 | * | 1130 | * |
@@ -1138,23 +1134,28 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen) | |||
1138 | * RETURNS: | 1134 | * RETURNS: |
1139 | * Zero on success, non-zero on error. | 1135 | * Zero on success, non-zero on error. |
1140 | */ | 1136 | */ |
1141 | 1137 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) | |
1142 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) | ||
1143 | { | 1138 | { |
1139 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
1144 | struct ata_taskfile *tf = &qc->tf; | 1140 | struct ata_taskfile *tf = &qc->tf; |
1145 | struct ata_device *dev = qc->dev; | 1141 | struct ata_device *dev = qc->dev; |
1146 | u64 dev_sectors = qc->dev->n_sectors; | 1142 | u64 dev_sectors = qc->dev->n_sectors; |
1143 | const u8 *cdb = scmd->cmnd; | ||
1147 | u64 block; | 1144 | u64 block; |
1148 | u32 n_block; | 1145 | u32 n_block; |
1149 | 1146 | ||
1150 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 1147 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
1151 | tf->protocol = ATA_PROT_NODATA; | 1148 | tf->protocol = ATA_PROT_NODATA; |
1152 | 1149 | ||
1153 | if (scsicmd[0] == VERIFY) | 1150 | if (cdb[0] == VERIFY) { |
1154 | scsi_10_lba_len(scsicmd, &block, &n_block); | 1151 | if (scmd->cmd_len < 10) |
1155 | else if (scsicmd[0] == VERIFY_16) | 1152 | goto invalid_fld; |
1156 | scsi_16_lba_len(scsicmd, &block, &n_block); | 1153 | scsi_10_lba_len(cdb, &block, &n_block); |
1157 | else | 1154 | } else if (cdb[0] == VERIFY_16) { |
1155 | if (scmd->cmd_len < 16) | ||
1156 | goto invalid_fld; | ||
1157 | scsi_16_lba_len(cdb, &block, &n_block); | ||
1158 | } else | ||
1158 | goto invalid_fld; | 1159 | goto invalid_fld; |
1159 | 1160 | ||
1160 | if (!n_block) | 1161 | if (!n_block) |
@@ -1229,24 +1230,23 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc | |||
1229 | return 0; | 1230 | return 0; |
1230 | 1231 | ||
1231 | invalid_fld: | 1232 | invalid_fld: |
1232 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); | 1233 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); |
1233 | /* "Invalid field in cbd" */ | 1234 | /* "Invalid field in cbd" */ |
1234 | return 1; | 1235 | return 1; |
1235 | 1236 | ||
1236 | out_of_range: | 1237 | out_of_range: |
1237 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0); | 1238 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0); |
1238 | /* "Logical Block Address out of range" */ | 1239 | /* "Logical Block Address out of range" */ |
1239 | return 1; | 1240 | return 1; |
1240 | 1241 | ||
1241 | nothing_to_do: | 1242 | nothing_to_do: |
1242 | qc->scsicmd->result = SAM_STAT_GOOD; | 1243 | scmd->result = SAM_STAT_GOOD; |
1243 | return 1; | 1244 | return 1; |
1244 | } | 1245 | } |
1245 | 1246 | ||
1246 | /** | 1247 | /** |
1247 | * ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one | 1248 | * ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one |
1248 | * @qc: Storage for translated ATA taskfile | 1249 | * @qc: Storage for translated ATA taskfile |
1249 | * @scsicmd: SCSI command to translate | ||
1250 | * | 1250 | * |
1251 | * Converts any of six SCSI read/write commands into the | 1251 | * Converts any of six SCSI read/write commands into the |
1252 | * ATA counterpart, including starting sector (LBA), | 1252 | * ATA counterpart, including starting sector (LBA), |
@@ -1262,29 +1262,33 @@ nothing_to_do: | |||
1262 | * RETURNS: | 1262 | * RETURNS: |
1263 | * Zero on success, non-zero on error. | 1263 | * Zero on success, non-zero on error. |
1264 | */ | 1264 | */ |
1265 | 1265 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) | |
1266 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) | ||
1267 | { | 1266 | { |
1267 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
1268 | const u8 *cdb = scmd->cmnd; | ||
1268 | unsigned int tf_flags = 0; | 1269 | unsigned int tf_flags = 0; |
1269 | u64 block; | 1270 | u64 block; |
1270 | u32 n_block; | 1271 | u32 n_block; |
1271 | int rc; | 1272 | int rc; |
1272 | 1273 | ||
1273 | if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 || | 1274 | if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16) |
1274 | scsicmd[0] == WRITE_16) | ||
1275 | tf_flags |= ATA_TFLAG_WRITE; | 1275 | tf_flags |= ATA_TFLAG_WRITE; |
1276 | 1276 | ||
1277 | /* Calculate the SCSI LBA, transfer length and FUA. */ | 1277 | /* Calculate the SCSI LBA, transfer length and FUA. */ |
1278 | switch (scsicmd[0]) { | 1278 | switch (cdb[0]) { |
1279 | case READ_10: | 1279 | case READ_10: |
1280 | case WRITE_10: | 1280 | case WRITE_10: |
1281 | scsi_10_lba_len(scsicmd, &block, &n_block); | 1281 | if (unlikely(scmd->cmd_len < 10)) |
1282 | if (unlikely(scsicmd[1] & (1 << 3))) | 1282 | goto invalid_fld; |
1283 | scsi_10_lba_len(cdb, &block, &n_block); | ||
1284 | if (unlikely(cdb[1] & (1 << 3))) | ||
1283 | tf_flags |= ATA_TFLAG_FUA; | 1285 | tf_flags |= ATA_TFLAG_FUA; |
1284 | break; | 1286 | break; |
1285 | case READ_6: | 1287 | case READ_6: |
1286 | case WRITE_6: | 1288 | case WRITE_6: |
1287 | scsi_6_lba_len(scsicmd, &block, &n_block); | 1289 | if (unlikely(scmd->cmd_len < 6)) |
1290 | goto invalid_fld; | ||
1291 | scsi_6_lba_len(cdb, &block, &n_block); | ||
1288 | 1292 | ||
1289 | /* for 6-byte r/w commands, transfer length 0 | 1293 | /* for 6-byte r/w commands, transfer length 0 |
1290 | * means 256 blocks of data, not 0 block. | 1294 | * means 256 blocks of data, not 0 block. |
@@ -1294,8 +1298,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1294 | break; | 1298 | break; |
1295 | case READ_16: | 1299 | case READ_16: |
1296 | case WRITE_16: | 1300 | case WRITE_16: |
1297 | scsi_16_lba_len(scsicmd, &block, &n_block); | 1301 | if (unlikely(scmd->cmd_len < 16)) |
1298 | if (unlikely(scsicmd[1] & (1 << 3))) | 1302 | goto invalid_fld; |
1303 | scsi_16_lba_len(cdb, &block, &n_block); | ||
1304 | if (unlikely(cdb[1] & (1 << 3))) | ||
1299 | tf_flags |= ATA_TFLAG_FUA; | 1305 | tf_flags |= ATA_TFLAG_FUA; |
1300 | break; | 1306 | break; |
1301 | default: | 1307 | default: |
@@ -1326,17 +1332,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1326 | goto out_of_range; | 1332 | goto out_of_range; |
1327 | /* treat all other errors as -EINVAL, fall through */ | 1333 | /* treat all other errors as -EINVAL, fall through */ |
1328 | invalid_fld: | 1334 | invalid_fld: |
1329 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); | 1335 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); |
1330 | /* "Invalid field in cbd" */ | 1336 | /* "Invalid field in cbd" */ |
1331 | return 1; | 1337 | return 1; |
1332 | 1338 | ||
1333 | out_of_range: | 1339 | out_of_range: |
1334 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0); | 1340 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0); |
1335 | /* "Logical Block Address out of range" */ | 1341 | /* "Logical Block Address out of range" */ |
1336 | return 1; | 1342 | return 1; |
1337 | 1343 | ||
1338 | nothing_to_do: | 1344 | nothing_to_do: |
1339 | qc->scsicmd->result = SAM_STAT_GOOD; | 1345 | scmd->result = SAM_STAT_GOOD; |
1340 | return 1; | 1346 | return 1; |
1341 | } | 1347 | } |
1342 | 1348 | ||
@@ -1456,7 +1462,6 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
1456 | ata_xlat_func_t xlat_func) | 1462 | ata_xlat_func_t xlat_func) |
1457 | { | 1463 | { |
1458 | struct ata_queued_cmd *qc; | 1464 | struct ata_queued_cmd *qc; |
1459 | u8 *scsicmd = cmd->cmnd; | ||
1460 | int is_io = xlat_func == ata_scsi_rw_xlat; | 1465 | int is_io = xlat_func == ata_scsi_rw_xlat; |
1461 | 1466 | ||
1462 | VPRINTK("ENTER\n"); | 1467 | VPRINTK("ENTER\n"); |
@@ -1488,7 +1493,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
1488 | 1493 | ||
1489 | qc->complete_fn = ata_scsi_qc_complete; | 1494 | qc->complete_fn = ata_scsi_qc_complete; |
1490 | 1495 | ||
1491 | if (xlat_func(qc, scsicmd)) | 1496 | if (xlat_func(qc)) |
1492 | goto early_finish; | 1497 | goto early_finish; |
1493 | 1498 | ||
1494 | /* select device, send command to hardware */ | 1499 | /* select device, send command to hardware */ |
@@ -2344,7 +2349,6 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) | |||
2344 | /** | 2349 | /** |
2345 | * atapi_xlat - Initialize PACKET taskfile | 2350 | * atapi_xlat - Initialize PACKET taskfile |
2346 | * @qc: command structure to be initialized | 2351 | * @qc: command structure to be initialized |
2347 | * @scsicmd: SCSI CDB associated with this PACKET command | ||
2348 | * | 2352 | * |
2349 | * LOCKING: | 2353 | * LOCKING: |
2350 | * spin_lock_irqsave(host lock) | 2354 | * spin_lock_irqsave(host lock) |
@@ -2352,25 +2356,25 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) | |||
2352 | * RETURNS: | 2356 | * RETURNS: |
2353 | * Zero on success, non-zero on failure. | 2357 | * Zero on success, non-zero on failure. |
2354 | */ | 2358 | */ |
2355 | 2359 | static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |
2356 | static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) | ||
2357 | { | 2360 | { |
2358 | struct scsi_cmnd *cmd = qc->scsicmd; | 2361 | struct scsi_cmnd *scmd = qc->scsicmd; |
2359 | struct ata_device *dev = qc->dev; | 2362 | struct ata_device *dev = qc->dev; |
2360 | int using_pio = (dev->flags & ATA_DFLAG_PIO); | 2363 | int using_pio = (dev->flags & ATA_DFLAG_PIO); |
2361 | int nodata = (cmd->sc_data_direction == DMA_NONE); | 2364 | int nodata = (scmd->sc_data_direction == DMA_NONE); |
2362 | 2365 | ||
2363 | if (!using_pio) | 2366 | if (!using_pio) |
2364 | /* Check whether ATAPI DMA is safe */ | 2367 | /* Check whether ATAPI DMA is safe */ |
2365 | if (ata_check_atapi_dma(qc)) | 2368 | if (ata_check_atapi_dma(qc)) |
2366 | using_pio = 1; | 2369 | using_pio = 1; |
2367 | 2370 | ||
2368 | memcpy(&qc->cdb, scsicmd, dev->cdb_len); | 2371 | memset(qc->cdb, 0, dev->cdb_len); |
2372 | memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len); | ||
2369 | 2373 | ||
2370 | qc->complete_fn = atapi_qc_complete; | 2374 | qc->complete_fn = atapi_qc_complete; |
2371 | 2375 | ||
2372 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 2376 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
2373 | if (cmd->sc_data_direction == DMA_TO_DEVICE) { | 2377 | if (scmd->sc_data_direction == DMA_TO_DEVICE) { |
2374 | qc->tf.flags |= ATA_TFLAG_WRITE; | 2378 | qc->tf.flags |= ATA_TFLAG_WRITE; |
2375 | DPRINTK("direction: write\n"); | 2379 | DPRINTK("direction: write\n"); |
2376 | } | 2380 | } |
@@ -2392,12 +2396,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2392 | qc->tf.protocol = ATA_PROT_ATAPI_DMA; | 2396 | qc->tf.protocol = ATA_PROT_ATAPI_DMA; |
2393 | qc->tf.feature |= ATAPI_PKT_DMA; | 2397 | qc->tf.feature |= ATAPI_PKT_DMA; |
2394 | 2398 | ||
2395 | if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE)) | 2399 | if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE)) |
2396 | /* some SATA bridges need us to indicate data xfer direction */ | 2400 | /* some SATA bridges need us to indicate data xfer direction */ |
2397 | qc->tf.feature |= ATAPI_DMADIR; | 2401 | qc->tf.feature |= ATAPI_DMADIR; |
2398 | } | 2402 | } |
2399 | 2403 | ||
2400 | qc->nbytes = cmd->request_bufflen; | 2404 | qc->nbytes = scmd->request_bufflen; |
2401 | 2405 | ||
2402 | return 0; | 2406 | return 0; |
2403 | } | 2407 | } |
@@ -2517,28 +2521,27 @@ ata_scsi_map_proto(u8 byte1) | |||
2517 | /** | 2521 | /** |
2518 | * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile | 2522 | * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile |
2519 | * @qc: command structure to be initialized | 2523 | * @qc: command structure to be initialized |
2520 | * @scsicmd: SCSI command to convert | ||
2521 | * | 2524 | * |
2522 | * Handles either 12 or 16-byte versions of the CDB. | 2525 | * Handles either 12 or 16-byte versions of the CDB. |
2523 | * | 2526 | * |
2524 | * RETURNS: | 2527 | * RETURNS: |
2525 | * Zero on success, non-zero on failure. | 2528 | * Zero on success, non-zero on failure. |
2526 | */ | 2529 | */ |
2527 | static unsigned int | 2530 | static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) |
2528 | ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | ||
2529 | { | 2531 | { |
2530 | struct ata_taskfile *tf = &(qc->tf); | 2532 | struct ata_taskfile *tf = &(qc->tf); |
2531 | struct scsi_cmnd *cmd = qc->scsicmd; | 2533 | struct scsi_cmnd *scmd = qc->scsicmd; |
2532 | struct ata_device *dev = qc->dev; | 2534 | struct ata_device *dev = qc->dev; |
2535 | const u8 *cdb = scmd->cmnd; | ||
2533 | 2536 | ||
2534 | if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) | 2537 | if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) |
2535 | goto invalid_fld; | 2538 | goto invalid_fld; |
2536 | 2539 | ||
2537 | /* We may not issue DMA commands if no DMA mode is set */ | 2540 | /* We may not issue DMA commands if no DMA mode is set */ |
2538 | if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) | 2541 | if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) |
2539 | goto invalid_fld; | 2542 | goto invalid_fld; |
2540 | 2543 | ||
2541 | if (scsicmd[1] & 0xe0) | 2544 | if (cdb[1] & 0xe0) |
2542 | /* PIO multi not supported yet */ | 2545 | /* PIO multi not supported yet */ |
2543 | goto invalid_fld; | 2546 | goto invalid_fld; |
2544 | 2547 | ||
@@ -2546,18 +2549,18 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2546 | * 12 and 16 byte CDBs use different offsets to | 2549 | * 12 and 16 byte CDBs use different offsets to |
2547 | * provide the various register values. | 2550 | * provide the various register values. |
2548 | */ | 2551 | */ |
2549 | if (scsicmd[0] == ATA_16) { | 2552 | if (cdb[0] == ATA_16) { |
2550 | /* | 2553 | /* |
2551 | * 16-byte CDB - may contain extended commands. | 2554 | * 16-byte CDB - may contain extended commands. |
2552 | * | 2555 | * |
2553 | * If that is the case, copy the upper byte register values. | 2556 | * If that is the case, copy the upper byte register values. |
2554 | */ | 2557 | */ |
2555 | if (scsicmd[1] & 0x01) { | 2558 | if (cdb[1] & 0x01) { |
2556 | tf->hob_feature = scsicmd[3]; | 2559 | tf->hob_feature = cdb[3]; |
2557 | tf->hob_nsect = scsicmd[5]; | 2560 | tf->hob_nsect = cdb[5]; |
2558 | tf->hob_lbal = scsicmd[7]; | 2561 | tf->hob_lbal = cdb[7]; |
2559 | tf->hob_lbam = scsicmd[9]; | 2562 | tf->hob_lbam = cdb[9]; |
2560 | tf->hob_lbah = scsicmd[11]; | 2563 | tf->hob_lbah = cdb[11]; |
2561 | tf->flags |= ATA_TFLAG_LBA48; | 2564 | tf->flags |= ATA_TFLAG_LBA48; |
2562 | } else | 2565 | } else |
2563 | tf->flags &= ~ATA_TFLAG_LBA48; | 2566 | tf->flags &= ~ATA_TFLAG_LBA48; |
@@ -2565,26 +2568,26 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2565 | /* | 2568 | /* |
2566 | * Always copy low byte, device and command registers. | 2569 | * Always copy low byte, device and command registers. |
2567 | */ | 2570 | */ |
2568 | tf->feature = scsicmd[4]; | 2571 | tf->feature = cdb[4]; |
2569 | tf->nsect = scsicmd[6]; | 2572 | tf->nsect = cdb[6]; |
2570 | tf->lbal = scsicmd[8]; | 2573 | tf->lbal = cdb[8]; |
2571 | tf->lbam = scsicmd[10]; | 2574 | tf->lbam = cdb[10]; |
2572 | tf->lbah = scsicmd[12]; | 2575 | tf->lbah = cdb[12]; |
2573 | tf->device = scsicmd[13]; | 2576 | tf->device = cdb[13]; |
2574 | tf->command = scsicmd[14]; | 2577 | tf->command = cdb[14]; |
2575 | } else { | 2578 | } else { |
2576 | /* | 2579 | /* |
2577 | * 12-byte CDB - incapable of extended commands. | 2580 | * 12-byte CDB - incapable of extended commands. |
2578 | */ | 2581 | */ |
2579 | tf->flags &= ~ATA_TFLAG_LBA48; | 2582 | tf->flags &= ~ATA_TFLAG_LBA48; |
2580 | 2583 | ||
2581 | tf->feature = scsicmd[3]; | 2584 | tf->feature = cdb[3]; |
2582 | tf->nsect = scsicmd[4]; | 2585 | tf->nsect = cdb[4]; |
2583 | tf->lbal = scsicmd[5]; | 2586 | tf->lbal = cdb[5]; |
2584 | tf->lbam = scsicmd[6]; | 2587 | tf->lbam = cdb[6]; |
2585 | tf->lbah = scsicmd[7]; | 2588 | tf->lbah = cdb[7]; |
2586 | tf->device = scsicmd[8]; | 2589 | tf->device = cdb[8]; |
2587 | tf->command = scsicmd[9]; | 2590 | tf->command = cdb[9]; |
2588 | } | 2591 | } |
2589 | /* | 2592 | /* |
2590 | * If slave is possible, enforce correct master/slave bit | 2593 | * If slave is possible, enforce correct master/slave bit |
@@ -2611,7 +2614,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2611 | */ | 2614 | */ |
2612 | tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE); | 2615 | tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE); |
2613 | 2616 | ||
2614 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | 2617 | if (scmd->sc_data_direction == DMA_TO_DEVICE) |
2615 | tf->flags |= ATA_TFLAG_WRITE; | 2618 | tf->flags |= ATA_TFLAG_WRITE; |
2616 | 2619 | ||
2617 | /* | 2620 | /* |
@@ -2620,7 +2623,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2620 | * TODO: find out if we need to do more here to | 2623 | * TODO: find out if we need to do more here to |
2621 | * cover scatter/gather case. | 2624 | * cover scatter/gather case. |
2622 | */ | 2625 | */ |
2623 | qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE; | 2626 | qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE; |
2624 | 2627 | ||
2625 | /* request result TF */ | 2628 | /* request result TF */ |
2626 | qc->flags |= ATA_QCFLAG_RESULT_TF; | 2629 | qc->flags |= ATA_QCFLAG_RESULT_TF; |
@@ -2628,7 +2631,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) | |||
2628 | return 0; | 2631 | return 0; |
2629 | 2632 | ||
2630 | invalid_fld: | 2633 | invalid_fld: |
2631 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00); | 2634 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00); |
2632 | /* "Invalid field in cdb" */ | 2635 | /* "Invalid field in cdb" */ |
2633 | return 1; | 2636 | return 1; |
2634 | } | 2637 | } |
@@ -2701,22 +2704,29 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, | |||
2701 | #endif | 2704 | #endif |
2702 | } | 2705 | } |
2703 | 2706 | ||
2704 | static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd, | 2707 | static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, |
2705 | void (*done)(struct scsi_cmnd *), | 2708 | void (*done)(struct scsi_cmnd *), |
2706 | struct ata_device *dev) | 2709 | struct ata_device *dev) |
2707 | { | 2710 | { |
2708 | int rc = 0; | 2711 | int rc = 0; |
2709 | 2712 | ||
2713 | if (unlikely(!scmd->cmd_len)) { | ||
2714 | ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n"); | ||
2715 | scmd->result = DID_ERROR << 16; | ||
2716 | done(scmd); | ||
2717 | return 0; | ||
2718 | } | ||
2719 | |||
2710 | if (dev->class == ATA_DEV_ATA) { | 2720 | if (dev->class == ATA_DEV_ATA) { |
2711 | ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, | 2721 | ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, |
2712 | cmd->cmnd[0]); | 2722 | scmd->cmnd[0]); |
2713 | 2723 | ||
2714 | if (xlat_func) | 2724 | if (xlat_func) |
2715 | rc = ata_scsi_translate(dev, cmd, done, xlat_func); | 2725 | rc = ata_scsi_translate(dev, scmd, done, xlat_func); |
2716 | else | 2726 | else |
2717 | ata_scsi_simulate(dev, cmd, done); | 2727 | ata_scsi_simulate(dev, scmd, done); |
2718 | } else | 2728 | } else |
2719 | rc = ata_scsi_translate(dev, cmd, done, atapi_xlat); | 2729 | rc = ata_scsi_translate(dev, scmd, done, atapi_xlat); |
2720 | 2730 | ||
2721 | return rc; | 2731 | return rc; |
2722 | } | 2732 | } |
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 1c628014dae6..b1ca207e3545 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c | |||
@@ -372,7 +372,8 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
372 | static int cs5530_reinit_one(struct pci_dev *pdev) | 372 | static int cs5530_reinit_one(struct pci_dev *pdev) |
373 | { | 373 | { |
374 | /* If we fail on resume we are doomed */ | 374 | /* If we fail on resume we are doomed */ |
375 | BUG_ON(cs5530_init_chip()); | 375 | if (cs5530_init_chip()) |
376 | BUG(); | ||
376 | return ata_pci_device_resume(pdev); | 377 | return ata_pci_device_resume(pdev); |
377 | } | 378 | } |
378 | 379 | ||
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index ff93e8f71cf8..f0d4f7e9ed31 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -395,7 +395,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags) | |||
395 | enable &= 3; | 395 | enable &= 3; |
396 | 396 | ||
397 | if (flags & VIA_SET_FIFO) { | 397 | if (flags & VIA_SET_FIFO) { |
398 | u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; | 398 | static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; |
399 | u8 fifo; | 399 | u8 fifo; |
400 | 400 | ||
401 | pci_read_config_byte(pdev, 0x43, &fifo); | 401 | pci_read_config_byte(pdev, 0x43, &fifo); |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 0d316eb3c214..f6d498e1cf80 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -270,14 +270,6 @@ static const struct pci_device_id nv_pci_tbl[] = { | |||
270 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, | 270 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, |
271 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, | 271 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, |
272 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, | 272 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, |
273 | { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */ | ||
274 | { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */ | ||
275 | { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */ | ||
276 | { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */ | ||
277 | { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */ | ||
278 | { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */ | ||
279 | { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */ | ||
280 | { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */ | ||
281 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, | 273 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, |
282 | PCI_ANY_ID, PCI_ANY_ID, | 274 | PCI_ANY_ID, PCI_ANY_ID, |
283 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, | 275 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index d89c9590b845..46d8a94669b4 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -135,26 +135,31 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | |||
135 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | 135 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; |
136 | 136 | ||
137 | if (tf->ctl != ap->last_ctl) { | 137 | if (tf->ctl != ap->last_ctl) { |
138 | writeb(tf->ctl, ioaddr->ctl_addr); | 138 | writeb(tf->ctl, (void __iomem *) ioaddr->ctl_addr); |
139 | ap->last_ctl = tf->ctl; | 139 | ap->last_ctl = tf->ctl; |
140 | ata_wait_idle(ap); | 140 | ata_wait_idle(ap); |
141 | } | 141 | } |
142 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | 142 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { |
143 | writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr); | 143 | writew(tf->feature | (((u16)tf->hob_feature) << 8), |
144 | writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); | 144 | (void __iomem *) ioaddr->feature_addr); |
145 | writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr); | 145 | writew(tf->nsect | (((u16)tf->hob_nsect) << 8), |
146 | writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr); | 146 | (void __iomem *) ioaddr->nsect_addr); |
147 | writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr); | 147 | writew(tf->lbal | (((u16)tf->hob_lbal) << 8), |
148 | (void __iomem *) ioaddr->lbal_addr); | ||
149 | writew(tf->lbam | (((u16)tf->hob_lbam) << 8), | ||
150 | (void __iomem *) ioaddr->lbam_addr); | ||
151 | writew(tf->lbah | (((u16)tf->hob_lbah) << 8), | ||
152 | (void __iomem *) ioaddr->lbah_addr); | ||
148 | } else if (is_addr) { | 153 | } else if (is_addr) { |
149 | writew(tf->feature, ioaddr->feature_addr); | 154 | writew(tf->feature, (void __iomem *) ioaddr->feature_addr); |
150 | writew(tf->nsect, ioaddr->nsect_addr); | 155 | writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr); |
151 | writew(tf->lbal, ioaddr->lbal_addr); | 156 | writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr); |
152 | writew(tf->lbam, ioaddr->lbam_addr); | 157 | writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr); |
153 | writew(tf->lbah, ioaddr->lbah_addr); | 158 | writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr); |
154 | } | 159 | } |
155 | 160 | ||
156 | if (tf->flags & ATA_TFLAG_DEVICE) | 161 | if (tf->flags & ATA_TFLAG_DEVICE) |
157 | writeb(tf->device, ioaddr->device_addr); | 162 | writeb(tf->device, (void __iomem *) ioaddr->device_addr); |
158 | 163 | ||
159 | ata_wait_idle(ap); | 164 | ata_wait_idle(ap); |
160 | } | 165 | } |
@@ -166,12 +171,12 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
166 | u16 nsect, lbal, lbam, lbah, feature; | 171 | u16 nsect, lbal, lbam, lbah, feature; |
167 | 172 | ||
168 | tf->command = k2_stat_check_status(ap); | 173 | tf->command = k2_stat_check_status(ap); |
169 | tf->device = readw(ioaddr->device_addr); | 174 | tf->device = readw((void __iomem *)ioaddr->device_addr); |
170 | feature = readw(ioaddr->error_addr); | 175 | feature = readw((void __iomem *)ioaddr->error_addr); |
171 | nsect = readw(ioaddr->nsect_addr); | 176 | nsect = readw((void __iomem *)ioaddr->nsect_addr); |
172 | lbal = readw(ioaddr->lbal_addr); | 177 | lbal = readw((void __iomem *)ioaddr->lbal_addr); |
173 | lbam = readw(ioaddr->lbam_addr); | 178 | lbam = readw((void __iomem *)ioaddr->lbam_addr); |
174 | lbah = readw(ioaddr->lbah_addr); | 179 | lbah = readw((void __iomem *)ioaddr->lbah_addr); |
175 | 180 | ||
176 | tf->feature = feature; | 181 | tf->feature = feature; |
177 | tf->nsect = nsect; | 182 | tf->nsect = nsect; |
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index e654b990b905..0fa1b89f76d5 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -149,21 +149,26 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | |||
149 | vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN); | 149 | vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN); |
150 | } | 150 | } |
151 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | 151 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { |
152 | writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr); | 152 | writew(tf->feature | (((u16)tf->hob_feature) << 8), |
153 | writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); | 153 | (void __iomem *) ioaddr->feature_addr); |
154 | writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr); | 154 | writew(tf->nsect | (((u16)tf->hob_nsect) << 8), |
155 | writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr); | 155 | (void __iomem *) ioaddr->nsect_addr); |
156 | writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr); | 156 | writew(tf->lbal | (((u16)tf->hob_lbal) << 8), |
157 | (void __iomem *) ioaddr->lbal_addr); | ||
158 | writew(tf->lbam | (((u16)tf->hob_lbam) << 8), | ||
159 | (void __iomem *) ioaddr->lbam_addr); | ||
160 | writew(tf->lbah | (((u16)tf->hob_lbah) << 8), | ||
161 | (void __iomem *) ioaddr->lbah_addr); | ||
157 | } else if (is_addr) { | 162 | } else if (is_addr) { |
158 | writew(tf->feature, ioaddr->feature_addr); | 163 | writew(tf->feature, (void __iomem *) ioaddr->feature_addr); |
159 | writew(tf->nsect, ioaddr->nsect_addr); | 164 | writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr); |
160 | writew(tf->lbal, ioaddr->lbal_addr); | 165 | writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr); |
161 | writew(tf->lbam, ioaddr->lbam_addr); | 166 | writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr); |
162 | writew(tf->lbah, ioaddr->lbah_addr); | 167 | writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr); |
163 | } | 168 | } |
164 | 169 | ||
165 | if (tf->flags & ATA_TFLAG_DEVICE) | 170 | if (tf->flags & ATA_TFLAG_DEVICE) |
166 | writeb(tf->device, ioaddr->device_addr); | 171 | writeb(tf->device, (void __iomem *) ioaddr->device_addr); |
167 | 172 | ||
168 | ata_wait_idle(ap); | 173 | ata_wait_idle(ap); |
169 | } | 174 | } |
@@ -175,12 +180,12 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
175 | u16 nsect, lbal, lbam, lbah, feature; | 180 | u16 nsect, lbal, lbam, lbah, feature; |
176 | 181 | ||
177 | tf->command = ata_check_status(ap); | 182 | tf->command = ata_check_status(ap); |
178 | tf->device = readw(ioaddr->device_addr); | 183 | tf->device = readw((void __iomem *) ioaddr->device_addr); |
179 | feature = readw(ioaddr->error_addr); | 184 | feature = readw((void __iomem *) ioaddr->error_addr); |
180 | nsect = readw(ioaddr->nsect_addr); | 185 | nsect = readw((void __iomem *) ioaddr->nsect_addr); |
181 | lbal = readw(ioaddr->lbal_addr); | 186 | lbal = readw((void __iomem *) ioaddr->lbal_addr); |
182 | lbam = readw(ioaddr->lbam_addr); | 187 | lbam = readw((void __iomem *) ioaddr->lbam_addr); |
183 | lbah = readw(ioaddr->lbah_addr); | 188 | lbah = readw((void __iomem *) ioaddr->lbah_addr); |
184 | 189 | ||
185 | tf->feature = feature; | 190 | tf->feature = feature; |
186 | tf->nsect = nsect; | 191 | tf->nsect = nsect; |
@@ -327,8 +332,8 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned lon | |||
327 | port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET; | 332 | port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET; |
328 | port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET; | 333 | port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET; |
329 | port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET; | 334 | port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET; |
330 | writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET); | 335 | writel(0, (void __iomem *) base + VSC_SATA_UP_DESCRIPTOR_OFFSET); |
331 | writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET); | 336 | writel(0, (void __iomem *) base + VSC_SATA_UP_DATA_BUFFER_OFFSET); |
332 | } | 337 | } |
333 | 338 | ||
334 | 339 | ||
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index e19ba4ebcd4e..68592c336011 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <asm/iseries/hv_lp_event.h> | 49 | #include <asm/iseries/hv_lp_event.h> |
50 | #include <asm/iseries/hv_lp_config.h> | 50 | #include <asm/iseries/hv_lp_config.h> |
51 | #include <asm/iseries/vio.h> | 51 | #include <asm/iseries/vio.h> |
52 | #include <asm/firmware.h> | ||
52 | 53 | ||
53 | MODULE_DESCRIPTION("iSeries Virtual DASD"); | 54 | MODULE_DESCRIPTION("iSeries Virtual DASD"); |
54 | MODULE_AUTHOR("Dave Boutcher"); | 55 | MODULE_AUTHOR("Dave Boutcher"); |
@@ -769,6 +770,11 @@ static int __init viodasd_init(void) | |||
769 | { | 770 | { |
770 | int rc; | 771 | int rc; |
771 | 772 | ||
773 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
774 | rc = -ENODEV; | ||
775 | goto early_fail; | ||
776 | } | ||
777 | |||
772 | /* Try to open to our host lp */ | 778 | /* Try to open to our host lp */ |
773 | if (viopath_hostLp == HvLpIndexInvalid) | 779 | if (viopath_hostLp == HvLpIndexInvalid) |
774 | vio_set_hostlp(); | 780 | vio_set_hostlp(); |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index fdea58ae16b2..aeefec97fdee 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
@@ -126,6 +126,7 @@ static struct usb_device_id blacklist_ids[] = { | |||
126 | 126 | ||
127 | /* Kensington Bluetooth USB adapter */ | 127 | /* Kensington Bluetooth USB adapter */ |
128 | { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET }, | 128 | { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET }, |
129 | { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU }, | ||
129 | 130 | ||
130 | /* ISSC Bluetooth Adapter v3.1 */ | 131 | /* ISSC Bluetooth Adapter v3.1 */ |
131 | { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, | 132 | { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 54ca931e19ea..93fbf84dcc4a 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <asm/iseries/hv_types.h> | 47 | #include <asm/iseries/hv_types.h> |
48 | #include <asm/iseries/hv_lp_event.h> | 48 | #include <asm/iseries/hv_lp_event.h> |
49 | #include <asm/iseries/vio.h> | 49 | #include <asm/iseries/vio.h> |
50 | #include <asm/firmware.h> | ||
50 | 51 | ||
51 | #define VIOCD_DEVICE "iseries/vcd" | 52 | #define VIOCD_DEVICE "iseries/vcd" |
52 | 53 | ||
@@ -748,6 +749,9 @@ static int __init viocd_init(void) | |||
748 | struct proc_dir_entry *e; | 749 | struct proc_dir_entry *e; |
749 | int ret = 0; | 750 | int ret = 0; |
750 | 751 | ||
752 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
753 | return -ENODEV; | ||
754 | |||
751 | if (viopath_hostLp == HvLpIndexInvalid) { | 755 | if (viopath_hostLp == HvLpIndexInvalid) { |
752 | vio_set_hostlp(); | 756 | vio_set_hostlp(); |
753 | /* If we don't have a host, bail out */ | 757 | /* If we don't have a host, bail out */ |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 0bbb04f2390f..6dcdceb81203 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -561,8 +561,7 @@ struct drm_driver { | |||
561 | int (*context_dtor) (struct drm_device * dev, int context); | 561 | int (*context_dtor) (struct drm_device * dev, int context); |
562 | int (*kernel_context_switch) (struct drm_device * dev, int old, | 562 | int (*kernel_context_switch) (struct drm_device * dev, int old, |
563 | int new); | 563 | int new); |
564 | void (*kernel_context_switch_unlock) (struct drm_device * dev, | 564 | void (*kernel_context_switch_unlock) (struct drm_device * dev); |
565 | drm_lock_t *lock); | ||
566 | int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); | 565 | int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence); |
567 | int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence); | 566 | int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence); |
568 | int (*dri_library_name) (struct drm_device *dev, char *buf); | 567 | int (*dri_library_name) (struct drm_device *dev, char *buf); |
@@ -1143,9 +1142,5 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area); | |||
1143 | extern unsigned long drm_core_get_map_ofs(drm_map_t * map); | 1142 | extern unsigned long drm_core_get_map_ofs(drm_map_t * map); |
1144 | extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); | 1143 | extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); |
1145 | 1144 | ||
1146 | #ifndef pci_pretty_name | ||
1147 | #define pci_pretty_name(dev) "" | ||
1148 | #endif | ||
1149 | |||
1150 | #endif /* __KERNEL__ */ | 1145 | #endif /* __KERNEL__ */ |
1151 | #endif | 1146 | #endif |
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index 116ed0f2ac09..e9993ba461a2 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c | |||
@@ -182,7 +182,7 @@ int drm_unlock(struct inode *inode, struct file *filp, | |||
182 | * modules but is required by the Sparc driver. | 182 | * modules but is required by the Sparc driver. |
183 | */ | 183 | */ |
184 | if (dev->driver->kernel_context_switch_unlock) | 184 | if (dev->driver->kernel_context_switch_unlock) |
185 | dev->driver->kernel_context_switch_unlock(dev, &lock); | 185 | dev->driver->kernel_context_switch_unlock(dev); |
186 | else { | 186 | else { |
187 | drm_lock_transfer(dev, &dev->lock.hw_lock->lock, | 187 | drm_lock_transfer(dev, &dev->lock.hw_lock->lock, |
188 | DRM_KERNEL_CONTEXT); | 188 | DRM_KERNEL_CONTEXT); |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 5fd6dc0870cf..120d10256feb 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -211,14 +211,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
211 | if (!dev) | 211 | if (!dev) |
212 | return -ENOMEM; | 212 | return -ENOMEM; |
213 | 213 | ||
214 | pci_enable_device(pdev); | 214 | ret = pci_enable_device(pdev); |
215 | if (ret) | ||
216 | goto err_g1; | ||
215 | 217 | ||
216 | if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { | 218 | if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { |
217 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | 219 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
218 | goto err_g1; | 220 | goto err_g2; |
219 | } | 221 | } |
220 | if ((ret = drm_get_head(dev, &dev->primary))) | 222 | if ((ret = drm_get_head(dev, &dev->primary))) |
221 | goto err_g1; | 223 | goto err_g2; |
222 | 224 | ||
223 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 225 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
224 | driver->name, driver->major, driver->minor, driver->patchlevel, | 226 | driver->name, driver->major, driver->minor, driver->patchlevel, |
@@ -226,7 +228,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
226 | 228 | ||
227 | return 0; | 229 | return 0; |
228 | 230 | ||
229 | err_g1: | 231 | err_g2: |
232 | pci_disable_device(pdev); | ||
233 | err_g1: | ||
230 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); | 234 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); |
231 | return ret; | 235 | return ret; |
232 | } | 236 | } |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index ba4b8de83cf0..cc8e2ebe128c 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -45,8 +45,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name) | |||
45 | int err; | 45 | int err; |
46 | 46 | ||
47 | class = class_create(owner, name); | 47 | class = class_create(owner, name); |
48 | if (!class) { | 48 | if (IS_ERR(class)) { |
49 | err = -ENOMEM; | 49 | err = PTR_ERR(class); |
50 | goto err_out; | 50 | goto err_out; |
51 | } | 51 | } |
52 | 52 | ||
@@ -113,8 +113,8 @@ struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) | |||
113 | MKDEV(DRM_MAJOR, head->minor), | 113 | MKDEV(DRM_MAJOR, head->minor), |
114 | &(head->dev->pdev)->dev, | 114 | &(head->dev->pdev)->dev, |
115 | "card%d", head->minor); | 115 | "card%d", head->minor); |
116 | if (!class_dev) { | 116 | if (IS_ERR(class_dev)) { |
117 | err = -ENOMEM; | 117 | err = PTR_ERR(class_dev); |
118 | goto err_out; | 118 | goto err_out; |
119 | } | 119 | } |
120 | 120 | ||
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index e5463b111fc0..e2c4b3a41b1e 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -46,88 +46,167 @@ static void i915_vblank_tasklet(drm_device_t *dev) | |||
46 | { | 46 | { |
47 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 47 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
48 | unsigned long irqflags; | 48 | unsigned long irqflags; |
49 | struct list_head *list, *tmp; | 49 | struct list_head *list, *tmp, hits, *hit; |
50 | int nhits, nrects, slice[2], upper[2], lower[2], i; | ||
51 | unsigned counter[2] = { atomic_read(&dev->vbl_received), | ||
52 | atomic_read(&dev->vbl_received2) }; | ||
53 | drm_drawable_info_t *drw; | ||
54 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | ||
55 | u32 cpp = dev_priv->cpp; | ||
56 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | | ||
57 | XY_SRC_COPY_BLT_WRITE_ALPHA | | ||
58 | XY_SRC_COPY_BLT_WRITE_RGB) | ||
59 | : XY_SRC_COPY_BLT_CMD; | ||
60 | u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | | ||
61 | (cpp << 23) | (1 << 24); | ||
62 | RING_LOCALS; | ||
50 | 63 | ||
51 | DRM_DEBUG("\n"); | 64 | DRM_DEBUG("\n"); |
52 | 65 | ||
66 | INIT_LIST_HEAD(&hits); | ||
67 | |||
68 | nhits = nrects = 0; | ||
69 | |||
53 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 70 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
54 | 71 | ||
72 | /* Find buffer swaps scheduled for this vertical blank */ | ||
55 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { | 73 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { |
56 | drm_i915_vbl_swap_t *vbl_swap = | 74 | drm_i915_vbl_swap_t *vbl_swap = |
57 | list_entry(list, drm_i915_vbl_swap_t, head); | 75 | list_entry(list, drm_i915_vbl_swap_t, head); |
58 | atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 : | ||
59 | &dev->vbl_received; | ||
60 | |||
61 | if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) { | ||
62 | drm_drawable_info_t *drw; | ||
63 | |||
64 | spin_unlock(&dev_priv->swaps_lock); | ||
65 | |||
66 | spin_lock(&dev->drw_lock); | ||
67 | |||
68 | drw = drm_get_drawable_info(dev, vbl_swap->drw_id); | ||
69 | |||
70 | if (drw) { | ||
71 | int i, num_rects = drw->num_rects; | ||
72 | drm_clip_rect_t *rect = drw->rects; | ||
73 | drm_i915_sarea_t *sarea_priv = | ||
74 | dev_priv->sarea_priv; | ||
75 | u32 cpp = dev_priv->cpp; | ||
76 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | | ||
77 | XY_SRC_COPY_BLT_WRITE_ALPHA | | ||
78 | XY_SRC_COPY_BLT_WRITE_RGB) | ||
79 | : XY_SRC_COPY_BLT_CMD; | ||
80 | u32 pitchropcpp = (sarea_priv->pitch * cpp) | | ||
81 | (0xcc << 16) | (cpp << 23) | | ||
82 | (1 << 24); | ||
83 | RING_LOCALS; | ||
84 | |||
85 | i915_kernel_lost_context(dev); | ||
86 | |||
87 | BEGIN_LP_RING(6); | ||
88 | |||
89 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
90 | OUT_RING(0); | ||
91 | OUT_RING(0); | ||
92 | OUT_RING(sarea_priv->width | | ||
93 | sarea_priv->height << 16); | ||
94 | OUT_RING(sarea_priv->width | | ||
95 | sarea_priv->height << 16); | ||
96 | OUT_RING(0); | ||
97 | 76 | ||
98 | ADVANCE_LP_RING(); | 77 | if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) |
78 | continue; | ||
79 | |||
80 | list_del(list); | ||
81 | dev_priv->swaps_pending--; | ||
99 | 82 | ||
100 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | 83 | spin_unlock(&dev_priv->swaps_lock); |
84 | spin_lock(&dev->drw_lock); | ||
101 | 85 | ||
102 | for (i = 0; i < num_rects; i++, rect++) { | 86 | drw = drm_get_drawable_info(dev, vbl_swap->drw_id); |
103 | BEGIN_LP_RING(8); | 87 | |
88 | if (!drw) { | ||
89 | spin_unlock(&dev->drw_lock); | ||
90 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
91 | spin_lock(&dev_priv->swaps_lock); | ||
92 | continue; | ||
93 | } | ||
104 | 94 | ||
105 | OUT_RING(cmd); | 95 | list_for_each(hit, &hits) { |
106 | OUT_RING(pitchropcpp); | 96 | drm_i915_vbl_swap_t *swap_cmp = |
107 | OUT_RING((rect->y1 << 16) | rect->x1); | 97 | list_entry(hit, drm_i915_vbl_swap_t, head); |
108 | OUT_RING((rect->y2 << 16) | rect->x2); | 98 | drm_drawable_info_t *drw_cmp = |
109 | OUT_RING(sarea_priv->front_offset); | 99 | drm_get_drawable_info(dev, swap_cmp->drw_id); |
110 | OUT_RING((rect->y1 << 16) | rect->x1); | ||
111 | OUT_RING(pitchropcpp & 0xffff); | ||
112 | OUT_RING(sarea_priv->back_offset); | ||
113 | 100 | ||
114 | ADVANCE_LP_RING(); | 101 | if (drw_cmp && |
115 | } | 102 | drw_cmp->rects[0].y1 > drw->rects[0].y1) { |
103 | list_add_tail(list, hit); | ||
104 | break; | ||
116 | } | 105 | } |
106 | } | ||
117 | 107 | ||
118 | spin_unlock(&dev->drw_lock); | 108 | spin_unlock(&dev->drw_lock); |
119 | 109 | ||
120 | spin_lock(&dev_priv->swaps_lock); | 110 | /* List of hits was empty, or we reached the end of it */ |
111 | if (hit == &hits) | ||
112 | list_add_tail(list, hits.prev); | ||
121 | 113 | ||
122 | list_del(list); | 114 | nhits++; |
123 | 115 | ||
124 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | 116 | spin_lock(&dev_priv->swaps_lock); |
117 | } | ||
118 | |||
119 | if (nhits == 0) { | ||
120 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | spin_unlock(&dev_priv->swaps_lock); | ||
125 | 125 | ||
126 | dev_priv->swaps_pending--; | 126 | i915_kernel_lost_context(dev); |
127 | |||
128 | BEGIN_LP_RING(6); | ||
129 | |||
130 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
131 | OUT_RING(0); | ||
132 | OUT_RING(0); | ||
133 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
134 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
135 | OUT_RING(0); | ||
136 | |||
137 | ADVANCE_LP_RING(); | ||
138 | |||
139 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | ||
140 | |||
141 | upper[0] = upper[1] = 0; | ||
142 | slice[0] = max(sarea_priv->pipeA_h / nhits, 1); | ||
143 | slice[1] = max(sarea_priv->pipeB_h / nhits, 1); | ||
144 | lower[0] = sarea_priv->pipeA_y + slice[0]; | ||
145 | lower[1] = sarea_priv->pipeB_y + slice[0]; | ||
146 | |||
147 | spin_lock(&dev->drw_lock); | ||
148 | |||
149 | /* Emit blits for buffer swaps, partitioning both outputs into as many | ||
150 | * slices as there are buffer swaps scheduled in order to avoid tearing | ||
151 | * (based on the assumption that a single buffer swap would always | ||
152 | * complete before scanout starts). | ||
153 | */ | ||
154 | for (i = 0; i++ < nhits; | ||
155 | upper[0] = lower[0], lower[0] += slice[0], | ||
156 | upper[1] = lower[1], lower[1] += slice[1]) { | ||
157 | if (i == nhits) | ||
158 | lower[0] = lower[1] = sarea_priv->height; | ||
159 | |||
160 | list_for_each(hit, &hits) { | ||
161 | drm_i915_vbl_swap_t *swap_hit = | ||
162 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
163 | drm_clip_rect_t *rect; | ||
164 | int num_rects, pipe; | ||
165 | unsigned short top, bottom; | ||
166 | |||
167 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); | ||
168 | |||
169 | if (!drw) | ||
170 | continue; | ||
171 | |||
172 | rect = drw->rects; | ||
173 | pipe = swap_hit->pipe; | ||
174 | top = upper[pipe]; | ||
175 | bottom = lower[pipe]; | ||
176 | |||
177 | for (num_rects = drw->num_rects; num_rects--; rect++) { | ||
178 | int y1 = max(rect->y1, top); | ||
179 | int y2 = min(rect->y2, bottom); | ||
180 | |||
181 | if (y1 >= y2) | ||
182 | continue; | ||
183 | |||
184 | BEGIN_LP_RING(8); | ||
185 | |||
186 | OUT_RING(cmd); | ||
187 | OUT_RING(pitchropcpp); | ||
188 | OUT_RING((y1 << 16) | rect->x1); | ||
189 | OUT_RING((y2 << 16) | rect->x2); | ||
190 | OUT_RING(sarea_priv->front_offset); | ||
191 | OUT_RING((y1 << 16) | rect->x1); | ||
192 | OUT_RING(pitchropcpp & 0xffff); | ||
193 | OUT_RING(sarea_priv->back_offset); | ||
194 | |||
195 | ADVANCE_LP_RING(); | ||
196 | } | ||
127 | } | 197 | } |
128 | } | 198 | } |
129 | 199 | ||
130 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | 200 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
201 | |||
202 | list_for_each_safe(hit, tmp, &hits) { | ||
203 | drm_i915_vbl_swap_t *swap_hit = | ||
204 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
205 | |||
206 | list_del(hit); | ||
207 | |||
208 | drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER); | ||
209 | } | ||
131 | } | 210 | } |
132 | 211 | ||
133 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 212 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h index 5d835b006f55..6e8af313f2b4 100644 --- a/drivers/char/drm/r128_drm.h +++ b/drivers/char/drm/r128_drm.h | |||
@@ -1,7 +1,8 @@ | |||
1 | /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- | 1 | /* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- |
2 | * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com | 2 | * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com |
3 | */ | 3 | */ |
4 | /* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. | 4 | /* |
5 | * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. | ||
5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 6 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
6 | * All rights reserved. | 7 | * All rights reserved. |
7 | * | 8 | * |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 94abffb2cca5..f1efb49de8df 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -1,7 +1,8 @@ | |||
1 | /* r128_drv.h -- Private header for r128 driver -*- linux-c -*- | 1 | /* r128_drv.h -- Private header for r128 driver -*- linux-c -*- |
2 | * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com | 2 | * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com |
3 | */ | 3 | */ |
4 | /* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | 4 | /* |
5 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | ||
5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 6 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
6 | * All rights reserved. | 7 | * All rights reserved. |
7 | * | 8 | * |
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c index a080cdd6081e..17b11e7d8f32 100644 --- a/drivers/char/drm/r128_state.c +++ b/drivers/char/drm/r128_state.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* r128_state.c -- State support for r128 -*- linux-c -*- | 1 | /* r128_state.c -- State support for r128 -*- linux-c -*- |
2 | * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com | 2 | * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com |
3 | */ | 3 | */ |
4 | /* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | 4 | /* |
5 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | ||
5 | * All Rights Reserved. | 6 | * All Rights Reserved. |
6 | * | 7 | * |
7 | * Permission is hereby granted, free of charge, to any person obtaining a | 8 | * Permission is hereby granted, free of charge, to any person obtaining a |
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index d14477ba3679..032a022ec6a8 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -242,26 +242,6 @@ static __inline__ int r300_check_range(unsigned reg, int count) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | /* | ||
246 | * we expect offsets passed to the framebuffer to be either within video | ||
247 | * memory or within AGP space | ||
248 | */ | ||
249 | static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, | ||
250 | u32 offset) | ||
251 | { | ||
252 | /* we realy want to check against end of video aperture | ||
253 | but this value is not being kept. | ||
254 | This code is correct for now (does the same thing as the | ||
255 | code that sets MC_FB_LOCATION) in radeon_cp.c */ | ||
256 | if (offset >= dev_priv->fb_location && | ||
257 | offset < (dev_priv->fb_location + dev_priv->fb_size)) | ||
258 | return 0; | ||
259 | if (offset >= dev_priv->gart_vm_start && | ||
260 | offset < (dev_priv->gart_vm_start + dev_priv->gart_size)) | ||
261 | return 0; | ||
262 | return 1; | ||
263 | } | ||
264 | |||
265 | static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * | 245 | static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * |
266 | dev_priv, | 246 | dev_priv, |
267 | drm_radeon_kcmd_buffer_t | 247 | drm_radeon_kcmd_buffer_t |
@@ -290,7 +270,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * | |||
290 | case MARK_SAFE: | 270 | case MARK_SAFE: |
291 | break; | 271 | break; |
292 | case MARK_CHECK_OFFSET: | 272 | case MARK_CHECK_OFFSET: |
293 | if (r300_check_offset(dev_priv, (u32) values[i])) { | 273 | if (!radeon_check_offset(dev_priv, (u32) values[i])) { |
294 | DRM_ERROR | 274 | DRM_ERROR |
295 | ("Offset failed range check (reg=%04x sz=%d)\n", | 275 | ("Offset failed range check (reg=%04x sz=%d)\n", |
296 | reg, sz); | 276 | reg, sz); |
@@ -452,7 +432,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, | |||
452 | i = 1; | 432 | i = 1; |
453 | while ((k < narrays) && (i < (count + 1))) { | 433 | while ((k < narrays) && (i < (count + 1))) { |
454 | i++; /* skip attribute field */ | 434 | i++; /* skip attribute field */ |
455 | if (r300_check_offset(dev_priv, payload[i])) { | 435 | if (!radeon_check_offset(dev_priv, payload[i])) { |
456 | DRM_ERROR | 436 | DRM_ERROR |
457 | ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", | 437 | ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", |
458 | k, i); | 438 | k, i); |
@@ -463,7 +443,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, | |||
463 | if (k == narrays) | 443 | if (k == narrays) |
464 | break; | 444 | break; |
465 | /* have one more to process, they come in pairs */ | 445 | /* have one more to process, they come in pairs */ |
466 | if (r300_check_offset(dev_priv, payload[i])) { | 446 | if (!radeon_check_offset(dev_priv, payload[i])) { |
467 | DRM_ERROR | 447 | DRM_ERROR |
468 | ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", | 448 | ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", |
469 | k, i); | 449 | k, i); |
@@ -508,7 +488,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, | |||
508 | if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 488 | if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
509 | | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | 489 | | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { |
510 | offset = cmd[2] << 10; | 490 | offset = cmd[2] << 10; |
511 | ret = r300_check_offset(dev_priv, offset); | 491 | ret = !radeon_check_offset(dev_priv, offset); |
512 | if (ret) { | 492 | if (ret) { |
513 | DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); | 493 | DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); |
514 | return DRM_ERR(EINVAL); | 494 | return DRM_ERR(EINVAL); |
@@ -518,7 +498,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, | |||
518 | if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && | 498 | if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && |
519 | (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | 499 | (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { |
520 | offset = cmd[3] << 10; | 500 | offset = cmd[3] << 10; |
521 | ret = r300_check_offset(dev_priv, offset); | 501 | ret = !radeon_check_offset(dev_priv, offset); |
522 | if (ret) { | 502 | if (ret) { |
523 | DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); | 503 | DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); |
524 | return DRM_ERR(EINVAL); | 504 | return DRM_ERR(EINVAL); |
@@ -551,7 +531,7 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, | |||
551 | DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); | 531 | DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); |
552 | return DRM_ERR(EINVAL); | 532 | return DRM_ERR(EINVAL); |
553 | } | 533 | } |
554 | ret = r300_check_offset(dev_priv, cmd[2]); | 534 | ret = !radeon_check_offset(dev_priv, cmd[2]); |
555 | if (ret) { | 535 | if (ret) { |
556 | DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); | 536 | DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); |
557 | return DRM_ERR(EINVAL); | 537 | return DRM_ERR(EINVAL); |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index f45cd7f147a5..8b105f1460a7 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -303,6 +303,21 @@ extern int radeon_no_wb; | |||
303 | extern drm_ioctl_desc_t radeon_ioctls[]; | 303 | extern drm_ioctl_desc_t radeon_ioctls[]; |
304 | extern int radeon_max_ioctl; | 304 | extern int radeon_max_ioctl; |
305 | 305 | ||
306 | /* Check whether the given hardware address is inside the framebuffer or the | ||
307 | * GART area. | ||
308 | */ | ||
309 | static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, | ||
310 | u64 off) | ||
311 | { | ||
312 | u32 fb_start = dev_priv->fb_location; | ||
313 | u32 fb_end = fb_start + dev_priv->fb_size - 1; | ||
314 | u32 gart_start = dev_priv->gart_vm_start; | ||
315 | u32 gart_end = gart_start + dev_priv->gart_size - 1; | ||
316 | |||
317 | return ((off >= fb_start && off <= fb_end) || | ||
318 | (off >= gart_start && off <= gart_end)); | ||
319 | } | ||
320 | |||
306 | /* radeon_cp.c */ | 321 | /* radeon_cp.c */ |
307 | extern int radeon_cp_init(DRM_IOCTL_ARGS); | 322 | extern int radeon_cp_init(DRM_IOCTL_ARGS); |
308 | extern int radeon_cp_start(DRM_IOCTL_ARGS); | 323 | extern int radeon_cp_start(DRM_IOCTL_ARGS); |
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index d60519de887b..3ff0baa2fbfa 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- | 1 | /* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */ |
2 | * | 2 | /* |
3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. | 3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. |
4 | * | 4 | * |
5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the | 5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the |
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c index 030a6fad0d86..517cad8b6e3a 100644 --- a/drivers/char/drm/radeon_mem.c +++ b/drivers/char/drm/radeon_mem.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- | 1 | /* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */ |
2 | * | 2 | /* |
3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. | 3 | * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. |
4 | * | 4 | * |
5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the | 5 | * The Weather Channel (TM) funded Tungsten Graphics to develop the |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 6e04fdd732ac..938eccb78cc0 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -43,10 +43,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * | |||
43 | u32 *offset) | 43 | u32 *offset) |
44 | { | 44 | { |
45 | u64 off = *offset; | 45 | u64 off = *offset; |
46 | u32 fb_start = dev_priv->fb_location; | 46 | u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1; |
47 | u32 fb_end = fb_start + dev_priv->fb_size - 1; | ||
48 | u32 gart_start = dev_priv->gart_vm_start; | ||
49 | u32 gart_end = gart_start + dev_priv->gart_size - 1; | ||
50 | struct drm_radeon_driver_file_fields *radeon_priv; | 47 | struct drm_radeon_driver_file_fields *radeon_priv; |
51 | 48 | ||
52 | /* Hrm ... the story of the offset ... So this function converts | 49 | /* Hrm ... the story of the offset ... So this function converts |
@@ -66,8 +63,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * | |||
66 | /* First, the best case, the offset already lands in either the | 63 | /* First, the best case, the offset already lands in either the |
67 | * framebuffer or the GART mapped space | 64 | * framebuffer or the GART mapped space |
68 | */ | 65 | */ |
69 | if ((off >= fb_start && off <= fb_end) || | 66 | if (radeon_check_offset(dev_priv, off)) |
70 | (off >= gart_start && off <= gart_end)) | ||
71 | return 0; | 67 | return 0; |
72 | 68 | ||
73 | /* Ok, that didn't happen... now check if we have a zero based | 69 | /* Ok, that didn't happen... now check if we have a zero based |
@@ -81,11 +77,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * | |||
81 | 77 | ||
82 | /* Finally, assume we aimed at a GART offset if beyond the fb */ | 78 | /* Finally, assume we aimed at a GART offset if beyond the fb */ |
83 | if (off > fb_end) | 79 | if (off > fb_end) |
84 | off = off - fb_end - 1 + gart_start; | 80 | off = off - fb_end - 1 + dev_priv->gart_vm_start; |
85 | 81 | ||
86 | /* Now recheck and fail if out of bounds */ | 82 | /* Now recheck and fail if out of bounds */ |
87 | if ((off >= fb_start && off <= fb_end) || | 83 | if (radeon_check_offset(dev_priv, off)) { |
88 | (off >= gart_start && off <= gart_end)) { | ||
89 | DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); | 84 | DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); |
90 | *offset = off; | 85 | *offset = off; |
91 | return 0; | 86 | return 0; |
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index a9a84f88df5e..b94fab556809 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c | |||
@@ -963,8 +963,8 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS) | |||
963 | 963 | ||
964 | event.count = savage_bci_emit_event(dev_priv, event.flags); | 964 | event.count = savage_bci_emit_event(dev_priv, event.flags); |
965 | event.count |= dev_priv->event_wrap << 16; | 965 | event.count |= dev_priv->event_wrap << 16; |
966 | DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)-> | 966 | DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *) data, |
967 | count, event.count, sizeof(event.count)); | 967 | event, sizeof(event)); |
968 | return 0; | 968 | return 0; |
969 | } | 969 | } |
970 | 970 | ||
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 0e0da443cbd5..8de6b95aeb84 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/tty_flip.h> | 42 | #include <linux/tty_flip.h> |
43 | #include <linux/sysrq.h> | 43 | #include <linux/sysrq.h> |
44 | 44 | ||
45 | #include <asm/firmware.h> | ||
45 | #include <asm/iseries/vio.h> | 46 | #include <asm/iseries/vio.h> |
46 | #include <asm/iseries/hv_lp_event.h> | 47 | #include <asm/iseries/hv_lp_event.h> |
47 | #include <asm/iseries/hv_call_event.h> | 48 | #include <asm/iseries/hv_call_event.h> |
@@ -1060,6 +1061,9 @@ static int __init viocons_init2(void) | |||
1060 | atomic_t wait_flag; | 1061 | atomic_t wait_flag; |
1061 | int rc; | 1062 | int rc; |
1062 | 1063 | ||
1064 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1065 | return -ENODEV; | ||
1066 | |||
1063 | /* +2 for fudge */ | 1067 | /* +2 for fudge */ |
1064 | rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), | 1068 | rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), |
1065 | viomajorsubtype_chario, VIOCHAR_WINDOW + 2); | 1069 | viomajorsubtype_chario, VIOCHAR_WINDOW + 2); |
@@ -1145,6 +1149,9 @@ static int __init viocons_init(void) | |||
1145 | { | 1149 | { |
1146 | int i; | 1150 | int i; |
1147 | 1151 | ||
1152 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1153 | return -ENODEV; | ||
1154 | |||
1148 | printk(VIOCONS_KERN_INFO "registering console\n"); | 1155 | printk(VIOCONS_KERN_INFO "registering console\n"); |
1149 | for (i = 0; i < VTTY_PORTS; i++) { | 1156 | for (i = 0; i < VTTY_PORTS; i++) { |
1150 | port_info[i].lp = HvLpIndexInvalid; | 1157 | port_info[i].lp = HvLpIndexInvalid; |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 94d79cb8ce8d..9438512b17f1 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -49,7 +49,7 @@ | |||
49 | 49 | ||
50 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
51 | #include <asm/ioctls.h> | 51 | #include <asm/ioctls.h> |
52 | 52 | #include <asm/firmware.h> | |
53 | #include <asm/vio.h> | 53 | #include <asm/vio.h> |
54 | #include <asm/iseries/vio.h> | 54 | #include <asm/iseries/vio.h> |
55 | #include <asm/iseries/hv_lp_event.h> | 55 | #include <asm/iseries/hv_lp_event.h> |
@@ -997,6 +997,9 @@ int __init viotap_init(void) | |||
997 | int ret; | 997 | int ret; |
998 | struct proc_dir_entry *e; | 998 | struct proc_dir_entry *e; |
999 | 999 | ||
1000 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1001 | return -ENODEV; | ||
1002 | |||
1000 | op_struct_list = NULL; | 1003 | op_struct_list = NULL; |
1001 | if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) { | 1004 | if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) { |
1002 | printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n"); | 1005 | printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n"); |
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index b418b16e910e..296f51002b55 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c | |||
@@ -34,7 +34,7 @@ | |||
34 | void cn_queue_wrapper(struct work_struct *work) | 34 | void cn_queue_wrapper(struct work_struct *work) |
35 | { | 35 | { |
36 | struct cn_callback_entry *cbq = | 36 | struct cn_callback_entry *cbq = |
37 | container_of(work, struct cn_callback_entry, work.work); | 37 | container_of(work, struct cn_callback_entry, work); |
38 | struct cn_callback_data *d = &cbq->data; | 38 | struct cn_callback_data *d = &cbq->data; |
39 | 39 | ||
40 | d->callback(d->callback_priv); | 40 | d->callback(d->callback_priv); |
@@ -59,13 +59,12 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc | |||
59 | memcpy(&cbq->id.id, id, sizeof(struct cb_id)); | 59 | memcpy(&cbq->id.id, id, sizeof(struct cb_id)); |
60 | cbq->data.callback = callback; | 60 | cbq->data.callback = callback; |
61 | 61 | ||
62 | INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper); | 62 | INIT_WORK(&cbq->work, &cn_queue_wrapper); |
63 | return cbq; | 63 | return cbq; |
64 | } | 64 | } |
65 | 65 | ||
66 | static void cn_queue_free_callback(struct cn_callback_entry *cbq) | 66 | static void cn_queue_free_callback(struct cn_callback_entry *cbq) |
67 | { | 67 | { |
68 | cancel_delayed_work(&cbq->work); | ||
69 | flush_workqueue(cbq->pdev->cn_queue); | 68 | flush_workqueue(cbq->pdev->cn_queue); |
70 | 69 | ||
71 | kfree(cbq); | 70 | kfree(cbq); |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 5e7cd45d10ee..a44db75bc25b 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -135,17 +135,15 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v | |||
135 | spin_lock_bh(&dev->cbdev->queue_lock); | 135 | spin_lock_bh(&dev->cbdev->queue_lock); |
136 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { | 136 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { |
137 | if (cn_cb_equal(&__cbq->id.id, &msg->id)) { | 137 | if (cn_cb_equal(&__cbq->id.id, &msg->id)) { |
138 | if (likely(!test_bit(WORK_STRUCT_PENDING, | 138 | if (likely(!work_pending(&__cbq->work) && |
139 | &__cbq->work.work.management) && | ||
140 | __cbq->data.ddata == NULL)) { | 139 | __cbq->data.ddata == NULL)) { |
141 | __cbq->data.callback_priv = msg; | 140 | __cbq->data.callback_priv = msg; |
142 | 141 | ||
143 | __cbq->data.ddata = data; | 142 | __cbq->data.ddata = data; |
144 | __cbq->data.destruct_data = destruct_data; | 143 | __cbq->data.destruct_data = destruct_data; |
145 | 144 | ||
146 | if (queue_delayed_work( | 145 | if (queue_work(dev->cbdev->cn_queue, |
147 | dev->cbdev->cn_queue, | 146 | &__cbq->work)) |
148 | &__cbq->work, 0)) | ||
149 | err = 0; | 147 | err = 0; |
150 | } else { | 148 | } else { |
151 | struct cn_callback_data *d; | 149 | struct cn_callback_data *d; |
@@ -159,12 +157,11 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v | |||
159 | d->destruct_data = destruct_data; | 157 | d->destruct_data = destruct_data; |
160 | d->free = __cbq; | 158 | d->free = __cbq; |
161 | 159 | ||
162 | INIT_DELAYED_WORK(&__cbq->work, | 160 | INIT_WORK(&__cbq->work, |
163 | &cn_queue_wrapper); | 161 | &cn_queue_wrapper); |
164 | 162 | ||
165 | if (queue_delayed_work( | 163 | if (queue_work(dev->cbdev->cn_queue, |
166 | dev->cbdev->cn_queue, | 164 | &__cbq->work)) |
167 | &__cbq->work, 0)) | ||
168 | err = 0; | 165 | err = 0; |
169 | else { | 166 | else { |
170 | kfree(__cbq); | 167 | kfree(__cbq); |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 14cdf09316ce..998638020ea0 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -415,12 +415,31 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
415 | case 0x000: goto ignore; | 415 | case 0x000: goto ignore; |
416 | case 0x034: map_key_clear(KEY_SLEEP); break; | 416 | case 0x034: map_key_clear(KEY_SLEEP); break; |
417 | case 0x036: map_key_clear(BTN_MISC); break; | 417 | case 0x036: map_key_clear(BTN_MISC); break; |
418 | case 0x040: map_key_clear(KEY_MENU); break; | ||
418 | case 0x045: map_key_clear(KEY_RADIO); break; | 419 | case 0x045: map_key_clear(KEY_RADIO); break; |
420 | |||
421 | case 0x088: map_key_clear(KEY_PC); break; | ||
422 | case 0x089: map_key_clear(KEY_TV); break; | ||
419 | case 0x08a: map_key_clear(KEY_WWW); break; | 423 | case 0x08a: map_key_clear(KEY_WWW); break; |
424 | case 0x08b: map_key_clear(KEY_DVD); break; | ||
425 | case 0x08c: map_key_clear(KEY_PHONE); break; | ||
420 | case 0x08d: map_key_clear(KEY_PROGRAM); break; | 426 | case 0x08d: map_key_clear(KEY_PROGRAM); break; |
427 | case 0x08e: map_key_clear(KEY_VIDEOPHONE); break; | ||
428 | case 0x08f: map_key_clear(KEY_GAMES); break; | ||
429 | case 0x090: map_key_clear(KEY_MEMO); break; | ||
430 | case 0x091: map_key_clear(KEY_CD); break; | ||
431 | case 0x092: map_key_clear(KEY_VCR); break; | ||
432 | case 0x093: map_key_clear(KEY_TUNER); break; | ||
433 | case 0x094: map_key_clear(KEY_EXIT); break; | ||
421 | case 0x095: map_key_clear(KEY_HELP); break; | 434 | case 0x095: map_key_clear(KEY_HELP); break; |
435 | case 0x096: map_key_clear(KEY_TAPE); break; | ||
436 | case 0x097: map_key_clear(KEY_TV2); break; | ||
437 | case 0x098: map_key_clear(KEY_SAT); break; | ||
438 | |||
422 | case 0x09c: map_key_clear(KEY_CHANNELUP); break; | 439 | case 0x09c: map_key_clear(KEY_CHANNELUP); break; |
423 | case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; | 440 | case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; |
441 | case 0x0a0: map_key_clear(KEY_VCR2); break; | ||
442 | |||
424 | case 0x0b0: map_key_clear(KEY_PLAY); break; | 443 | case 0x0b0: map_key_clear(KEY_PLAY); break; |
425 | case 0x0b1: map_key_clear(KEY_PAUSE); break; | 444 | case 0x0b1: map_key_clear(KEY_PAUSE); break; |
426 | case 0x0b2: map_key_clear(KEY_RECORD); break; | 445 | case 0x0b2: map_key_clear(KEY_RECORD); break; |
@@ -430,6 +449,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
430 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; | 449 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; |
431 | case 0x0b7: map_key_clear(KEY_STOPCD); break; | 450 | case 0x0b7: map_key_clear(KEY_STOPCD); break; |
432 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; | 451 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; |
452 | |||
433 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; | 453 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; |
434 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; | 454 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; |
435 | case 0x0e2: map_key_clear(KEY_MUTE); break; | 455 | case 0x0e2: map_key_clear(KEY_MUTE); break; |
@@ -437,11 +457,30 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
437 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | 457 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; |
438 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | 458 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; |
439 | case 0x183: map_key_clear(KEY_CONFIG); break; | 459 | case 0x183: map_key_clear(KEY_CONFIG); break; |
460 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; | ||
461 | case 0x185: map_key_clear(KEY_EDITOR); break; | ||
462 | case 0x186: map_key_clear(KEY_SPREADSHEET); break; | ||
463 | case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break; | ||
464 | case 0x188: map_key_clear(KEY_PRESENTATION); break; | ||
465 | case 0x189: map_key_clear(KEY_DATABASE); break; | ||
440 | case 0x18a: map_key_clear(KEY_MAIL); break; | 466 | case 0x18a: map_key_clear(KEY_MAIL); break; |
467 | case 0x18b: map_key_clear(KEY_NEWS); break; | ||
468 | case 0x18c: map_key_clear(KEY_VOICEMAIL); break; | ||
469 | case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break; | ||
470 | case 0x18e: map_key_clear(KEY_CALENDAR); break; | ||
471 | case 0x191: map_key_clear(KEY_FINANCE); break; | ||
441 | case 0x192: map_key_clear(KEY_CALC); break; | 472 | case 0x192: map_key_clear(KEY_CALC); break; |
442 | case 0x194: map_key_clear(KEY_FILE); break; | 473 | case 0x194: map_key_clear(KEY_FILE); break; |
474 | case 0x196: map_key_clear(KEY_WWW); break; | ||
475 | case 0x19e: map_key_clear(KEY_COFFEE); break; | ||
476 | case 0x1a6: map_key_clear(KEY_HELP); break; | ||
443 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; | 477 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; |
478 | case 0x1bc: map_key_clear(KEY_MESSENGER); break; | ||
479 | case 0x1bd: map_key_clear(KEY_INFO); break; | ||
444 | case 0x201: map_key_clear(KEY_NEW); break; | 480 | case 0x201: map_key_clear(KEY_NEW); break; |
481 | case 0x202: map_key_clear(KEY_OPEN); break; | ||
482 | case 0x203: map_key_clear(KEY_CLOSE); break; | ||
483 | case 0x204: map_key_clear(KEY_EXIT); break; | ||
445 | case 0x207: map_key_clear(KEY_SAVE); break; | 484 | case 0x207: map_key_clear(KEY_SAVE); break; |
446 | case 0x208: map_key_clear(KEY_PRINT); break; | 485 | case 0x208: map_key_clear(KEY_PRINT); break; |
447 | case 0x209: map_key_clear(KEY_PROPS); break; | 486 | case 0x209: map_key_clear(KEY_PROPS); break; |
@@ -456,10 +495,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
456 | case 0x226: map_key_clear(KEY_STOP); break; | 495 | case 0x226: map_key_clear(KEY_STOP); break; |
457 | case 0x227: map_key_clear(KEY_REFRESH); break; | 496 | case 0x227: map_key_clear(KEY_REFRESH); break; |
458 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; | 497 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; |
498 | case 0x22d: map_key_clear(KEY_ZOOMIN); break; | ||
499 | case 0x22e: map_key_clear(KEY_ZOOMOUT); break; | ||
500 | case 0x22f: map_key_clear(KEY_ZOOMRESET); break; | ||
459 | case 0x233: map_key_clear(KEY_SCROLLUP); break; | 501 | case 0x233: map_key_clear(KEY_SCROLLUP); break; |
460 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; | 502 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; |
461 | case 0x238: map_rel(REL_HWHEEL); break; | 503 | case 0x238: map_rel(REL_HWHEEL); break; |
504 | case 0x25f: map_key_clear(KEY_CANCEL); break; | ||
462 | case 0x279: map_key_clear(KEY_REDO); break; | 505 | case 0x279: map_key_clear(KEY_REDO); break; |
506 | |||
463 | case 0x289: map_key_clear(KEY_REPLY); break; | 507 | case 0x289: map_key_clear(KEY_REPLY); break; |
464 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 508 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
465 | case 0x28c: map_key_clear(KEY_SEND); break; | 509 | case 0x28c: map_key_clear(KEY_SEND); break; |
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index d55b938b1aeb..ffdffb6379ef 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
@@ -368,7 +368,6 @@ static struct pci_device_id atiixp_pci_tbl[] = { | |||
368 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 368 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
369 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 369 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
370 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 370 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
371 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1}, | ||
372 | { 0, }, | 371 | { 0, }, |
373 | }; | 372 | }; |
374 | MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); | 373 | MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7d824cf8ee2d..ada5e9b9988c 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -57,8 +57,8 @@ | |||
57 | 57 | ||
58 | #define DRV_MODULE_NAME "bnx2" | 58 | #define DRV_MODULE_NAME "bnx2" |
59 | #define PFX DRV_MODULE_NAME ": " | 59 | #define PFX DRV_MODULE_NAME ": " |
60 | #define DRV_MODULE_VERSION "1.5.1" | 60 | #define DRV_MODULE_VERSION "1.5.2" |
61 | #define DRV_MODULE_RELDATE "November 15, 2006" | 61 | #define DRV_MODULE_RELDATE "December 13, 2006" |
62 | 62 | ||
63 | #define RUN_AT(x) (jiffies + (x)) | 63 | #define RUN_AT(x) (jiffies + (x)) |
64 | 64 | ||
@@ -217,9 +217,16 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp) | |||
217 | u32 diff; | 217 | u32 diff; |
218 | 218 | ||
219 | smp_mb(); | 219 | smp_mb(); |
220 | diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons); | 220 | |
221 | if (diff > MAX_TX_DESC_CNT) | 221 | /* The ring uses 256 indices for 255 entries, one of them |
222 | diff = (diff & MAX_TX_DESC_CNT) - 1; | 222 | * needs to be skipped. |
223 | */ | ||
224 | diff = bp->tx_prod - bp->tx_cons; | ||
225 | if (unlikely(diff >= TX_DESC_CNT)) { | ||
226 | diff &= 0xffff; | ||
227 | if (diff == TX_DESC_CNT) | ||
228 | diff = MAX_TX_DESC_CNT; | ||
229 | } | ||
223 | return (bp->tx_ring_size - diff); | 230 | return (bp->tx_ring_size - diff); |
224 | } | 231 | } |
225 | 232 | ||
@@ -3089,7 +3096,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3089 | 3096 | ||
3090 | if ((align_start = (offset32 & 3))) { | 3097 | if ((align_start = (offset32 & 3))) { |
3091 | offset32 &= ~3; | 3098 | offset32 &= ~3; |
3092 | len32 += align_start; | 3099 | len32 += (4 - align_start); |
3093 | if ((rc = bnx2_nvram_read(bp, offset32, start, 4))) | 3100 | if ((rc = bnx2_nvram_read(bp, offset32, start, 4))) |
3094 | return rc; | 3101 | return rc; |
3095 | } | 3102 | } |
@@ -3107,7 +3114,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3107 | 3114 | ||
3108 | if (align_start || align_end) { | 3115 | if (align_start || align_end) { |
3109 | buf = kmalloc(len32, GFP_KERNEL); | 3116 | buf = kmalloc(len32, GFP_KERNEL); |
3110 | if (buf == 0) | 3117 | if (buf == NULL) |
3111 | return -ENOMEM; | 3118 | return -ENOMEM; |
3112 | if (align_start) { | 3119 | if (align_start) { |
3113 | memcpy(buf, start, 4); | 3120 | memcpy(buf, start, 4); |
@@ -3998,7 +4005,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
3998 | if (!skb) | 4005 | if (!skb) |
3999 | return -ENOMEM; | 4006 | return -ENOMEM; |
4000 | packet = skb_put(skb, pkt_size); | 4007 | packet = skb_put(skb, pkt_size); |
4001 | memcpy(packet, bp->mac_addr, 6); | 4008 | memcpy(packet, bp->dev->dev_addr, 6); |
4002 | memset(packet + 6, 0x0, 8); | 4009 | memset(packet + 6, 0x0, 8); |
4003 | for (i = 14; i < pkt_size; i++) | 4010 | for (i = 14; i < pkt_size; i++) |
4004 | packet[i] = (unsigned char) (i & 0xff); | 4011 | packet[i] = (unsigned char) (i & 0xff); |
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index d6f4f185bf37..2194b567239f 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -73,7 +73,7 @@ | |||
73 | #include <asm/abs_addr.h> | 73 | #include <asm/abs_addr.h> |
74 | #include <asm/iseries/mf.h> | 74 | #include <asm/iseries/mf.h> |
75 | #include <asm/uaccess.h> | 75 | #include <asm/uaccess.h> |
76 | 76 | #include <asm/firmware.h> | |
77 | #include <asm/iseries/hv_lp_config.h> | 77 | #include <asm/iseries/hv_lp_config.h> |
78 | #include <asm/iseries/hv_types.h> | 78 | #include <asm/iseries/hv_types.h> |
79 | #include <asm/iseries/hv_lp_event.h> | 79 | #include <asm/iseries/hv_lp_event.h> |
@@ -1668,7 +1668,7 @@ static struct vio_driver veth_driver = { | |||
1668 | * Module initialization/cleanup | 1668 | * Module initialization/cleanup |
1669 | */ | 1669 | */ |
1670 | 1670 | ||
1671 | void __exit veth_module_cleanup(void) | 1671 | static void __exit veth_module_cleanup(void) |
1672 | { | 1672 | { |
1673 | int i; | 1673 | int i; |
1674 | struct veth_lpar_connection *cnx; | 1674 | struct veth_lpar_connection *cnx; |
@@ -1697,11 +1697,14 @@ void __exit veth_module_cleanup(void) | |||
1697 | } | 1697 | } |
1698 | module_exit(veth_module_cleanup); | 1698 | module_exit(veth_module_cleanup); |
1699 | 1699 | ||
1700 | int __init veth_module_init(void) | 1700 | static int __init veth_module_init(void) |
1701 | { | 1701 | { |
1702 | int i; | 1702 | int i; |
1703 | int rc; | 1703 | int rc; |
1704 | 1704 | ||
1705 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1706 | return -ENODEV; | ||
1707 | |||
1705 | this_lp = HvLpConfig_getLpIndex_outline(); | 1708 | this_lp = HvLpConfig_getLpIndex_outline(); |
1706 | 1709 | ||
1707 | for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) { | 1710 | for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) { |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 571320ae87ab..4056ba1ff3c7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -68,8 +68,8 @@ | |||
68 | 68 | ||
69 | #define DRV_MODULE_NAME "tg3" | 69 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 70 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.70" | 71 | #define DRV_MODULE_VERSION "3.71" |
72 | #define DRV_MODULE_RELDATE "December 1, 2006" | 72 | #define DRV_MODULE_RELDATE "December 15, 2006" |
73 | 73 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 74 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 75 | #define TG3_DEF_RX_MODE 0 |
@@ -959,6 +959,13 @@ static int tg3_phy_reset(struct tg3 *tp) | |||
959 | u32 phy_status; | 959 | u32 phy_status; |
960 | int err; | 960 | int err; |
961 | 961 | ||
962 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { | ||
963 | u32 val; | ||
964 | |||
965 | val = tr32(GRC_MISC_CFG); | ||
966 | tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ); | ||
967 | udelay(40); | ||
968 | } | ||
962 | err = tg3_readphy(tp, MII_BMSR, &phy_status); | 969 | err = tg3_readphy(tp, MII_BMSR, &phy_status); |
963 | err |= tg3_readphy(tp, MII_BMSR, &phy_status); | 970 | err |= tg3_readphy(tp, MII_BMSR, &phy_status); |
964 | if (err != 0) | 971 | if (err != 0) |
@@ -1170,7 +1177,15 @@ static void tg3_power_down_phy(struct tg3 *tp) | |||
1170 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | 1177 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) |
1171 | return; | 1178 | return; |
1172 | 1179 | ||
1173 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) { | 1180 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { |
1181 | u32 val; | ||
1182 | |||
1183 | tg3_bmcr_reset(tp); | ||
1184 | val = tr32(GRC_MISC_CFG); | ||
1185 | tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); | ||
1186 | udelay(40); | ||
1187 | return; | ||
1188 | } else { | ||
1174 | tg3_writephy(tp, MII_TG3_EXT_CTRL, | 1189 | tg3_writephy(tp, MII_TG3_EXT_CTRL, |
1175 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); | 1190 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); |
1176 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); | 1191 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); |
@@ -4426,7 +4441,7 @@ static void tg3_free_consistent(struct tg3 *tp) | |||
4426 | */ | 4441 | */ |
4427 | static int tg3_alloc_consistent(struct tg3 *tp) | 4442 | static int tg3_alloc_consistent(struct tg3 *tp) |
4428 | { | 4443 | { |
4429 | tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) * | 4444 | tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) * |
4430 | (TG3_RX_RING_SIZE + | 4445 | (TG3_RX_RING_SIZE + |
4431 | TG3_RX_JUMBO_RING_SIZE)) + | 4446 | TG3_RX_JUMBO_RING_SIZE)) + |
4432 | (sizeof(struct tx_ring_info) * | 4447 | (sizeof(struct tx_ring_info) * |
@@ -4435,13 +4450,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) | |||
4435 | if (!tp->rx_std_buffers) | 4450 | if (!tp->rx_std_buffers) |
4436 | return -ENOMEM; | 4451 | return -ENOMEM; |
4437 | 4452 | ||
4438 | memset(tp->rx_std_buffers, 0, | ||
4439 | (sizeof(struct ring_info) * | ||
4440 | (TG3_RX_RING_SIZE + | ||
4441 | TG3_RX_JUMBO_RING_SIZE)) + | ||
4442 | (sizeof(struct tx_ring_info) * | ||
4443 | TG3_TX_RING_SIZE)); | ||
4444 | |||
4445 | tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE]; | 4453 | tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE]; |
4446 | tp->tx_buffers = (struct tx_ring_info *) | 4454 | tp->tx_buffers = (struct tx_ring_info *) |
4447 | &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE]; | 4455 | &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE]; |
@@ -6988,6 +6996,8 @@ static int tg3_open(struct net_device *dev) | |||
6988 | struct tg3 *tp = netdev_priv(dev); | 6996 | struct tg3 *tp = netdev_priv(dev); |
6989 | int err; | 6997 | int err; |
6990 | 6998 | ||
6999 | netif_carrier_off(tp->dev); | ||
7000 | |||
6991 | tg3_full_lock(tp, 0); | 7001 | tg3_full_lock(tp, 0); |
6992 | 7002 | ||
6993 | err = tg3_set_power_state(tp, PCI_D0); | 7003 | err = tg3_set_power_state(tp, PCI_D0); |
@@ -7981,6 +7991,10 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
7981 | tp->link_config.duplex = cmd->duplex; | 7991 | tp->link_config.duplex = cmd->duplex; |
7982 | } | 7992 | } |
7983 | 7993 | ||
7994 | tp->link_config.orig_speed = tp->link_config.speed; | ||
7995 | tp->link_config.orig_duplex = tp->link_config.duplex; | ||
7996 | tp->link_config.orig_autoneg = tp->link_config.autoneg; | ||
7997 | |||
7984 | if (netif_running(dev)) | 7998 | if (netif_running(dev)) |
7985 | tg3_setup_phy(tp, 1); | 7999 | tg3_setup_phy(tp, 1); |
7986 | 8000 | ||
@@ -11923,6 +11937,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
11923 | */ | 11937 | */ |
11924 | pci_save_state(tp->pdev); | 11938 | pci_save_state(tp->pdev); |
11925 | 11939 | ||
11940 | pci_set_drvdata(pdev, dev); | ||
11941 | |||
11926 | err = register_netdev(dev); | 11942 | err = register_netdev(dev); |
11927 | if (err) { | 11943 | if (err) { |
11928 | printk(KERN_ERR PFX "Cannot register net device, " | 11944 | printk(KERN_ERR PFX "Cannot register net device, " |
@@ -11930,8 +11946,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
11930 | goto err_out_iounmap; | 11946 | goto err_out_iounmap; |
11931 | } | 11947 | } |
11932 | 11948 | ||
11933 | pci_set_drvdata(pdev, dev); | ||
11934 | |||
11935 | printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ", | 11949 | printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ", |
11936 | dev->name, | 11950 | dev->name, |
11937 | tp->board_part_number, | 11951 | tp->board_part_number, |
@@ -11962,8 +11976,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
11962 | (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : | 11976 | (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : |
11963 | (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); | 11977 | (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); |
11964 | 11978 | ||
11965 | netif_carrier_off(tp->dev); | ||
11966 | |||
11967 | return 0; | 11979 | return 0; |
11968 | 11980 | ||
11969 | err_out_iounmap: | 11981 | err_out_iounmap: |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index dfaf4ed127bd..cf78a7e5997b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -1350,6 +1350,7 @@ | |||
1350 | #define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 | 1350 | #define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 |
1351 | #define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 | 1351 | #define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 |
1352 | #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 | 1352 | #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 |
1353 | #define GRC_MISC_CFG_EPHY_IDDQ 0x00200000 | ||
1353 | #define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 | 1354 | #define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 |
1354 | #define GRC_LOCAL_CTRL 0x00006808 | 1355 | #define GRC_LOCAL_CTRL 0x00006808 |
1355 | #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 | 1356 | #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0b9d0db1590a..bd1faebf61a0 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -1682,7 +1682,7 @@ int __init acpiphp_glue_init(void) | |||
1682 | * | 1682 | * |
1683 | * This function frees all data allocated in acpiphp_glue_init() | 1683 | * This function frees all data allocated in acpiphp_glue_init() |
1684 | */ | 1684 | */ |
1685 | void __exit acpiphp_glue_exit(void) | 1685 | void acpiphp_glue_exit(void) |
1686 | { | 1686 | { |
1687 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1687 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); |
1688 | } | 1688 | } |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index b771196a654e..3009193f0058 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
@@ -47,21 +47,11 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) | |||
47 | return retval; | 47 | return retval; |
48 | } | 48 | } |
49 | 49 | ||
50 | static struct hotplug_slot_attribute hotplug_slot_attr_location = { | 50 | static struct hotplug_slot_attribute php_attr_location = { |
51 | .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, | 51 | .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, |
52 | .show = location_read_file, | 52 | .show = location_read_file, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot) | ||
56 | { | ||
57 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); | ||
58 | } | ||
59 | |||
60 | static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) | ||
61 | { | ||
62 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); | ||
63 | } | ||
64 | |||
65 | /* free up the memory used by a slot */ | 55 | /* free up the memory used by a slot */ |
66 | static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) | 56 | static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) |
67 | { | 57 | { |
@@ -145,7 +135,7 @@ int rpaphp_deregister_slot(struct slot *slot) | |||
145 | list_del(&slot->rpaphp_slot_list); | 135 | list_del(&slot->rpaphp_slot_list); |
146 | 136 | ||
147 | /* remove "phy_location" file */ | 137 | /* remove "phy_location" file */ |
148 | rpaphp_sysfs_remove_attr_location(php_slot); | 138 | sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr); |
149 | 139 | ||
150 | retval = pci_hp_deregister(php_slot); | 140 | retval = pci_hp_deregister(php_slot); |
151 | if (retval) | 141 | if (retval) |
@@ -160,36 +150,45 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot); | |||
160 | 150 | ||
161 | int rpaphp_register_slot(struct slot *slot) | 151 | int rpaphp_register_slot(struct slot *slot) |
162 | { | 152 | { |
153 | struct hotplug_slot *php_slot = slot->hotplug_slot; | ||
163 | int retval; | 154 | int retval; |
164 | 155 | ||
165 | dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", | 156 | dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", |
166 | __FUNCTION__, slot->dn->full_name, slot->index, slot->name, | 157 | __FUNCTION__, slot->dn->full_name, slot->index, slot->name, |
167 | slot->power_domain, slot->type); | 158 | slot->power_domain, slot->type); |
159 | |||
168 | /* should not try to register the same slot twice */ | 160 | /* should not try to register the same slot twice */ |
169 | if (is_registered(slot)) { /* should't be here */ | 161 | if (is_registered(slot)) { |
170 | err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); | 162 | err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); |
171 | rpaphp_release_slot(slot->hotplug_slot); | 163 | retval = -EAGAIN; |
172 | return -EAGAIN; | 164 | goto register_fail; |
173 | } | 165 | } |
174 | retval = pci_hp_register(slot->hotplug_slot); | 166 | |
167 | retval = pci_hp_register(php_slot); | ||
175 | if (retval) { | 168 | if (retval) { |
176 | err("pci_hp_register failed with error %d\n", retval); | 169 | err("pci_hp_register failed with error %d\n", retval); |
177 | rpaphp_release_slot(slot->hotplug_slot); | 170 | goto register_fail; |
178 | return retval; | ||
179 | } | 171 | } |
180 | |||
181 | /* create "phy_locatoin" file */ | ||
182 | rpaphp_sysfs_add_attr_location(slot->hotplug_slot); | ||
183 | 172 | ||
184 | /* add slot to our internal list */ | 173 | /* create "phy_location" file */ |
185 | dbg("%s adding slot[%s] to rpaphp_slot_list\n", | 174 | retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr); |
186 | __FUNCTION__, slot->name); | 175 | if (retval) { |
176 | err("sysfs_create_file failed with error %d\n", retval); | ||
177 | goto sysfs_fail; | ||
178 | } | ||
187 | 179 | ||
180 | /* add slot to our internal list */ | ||
188 | list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); | 181 | list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); |
189 | info("Slot [%s](PCI location=%s) registered\n", slot->name, | 182 | info("Slot [%s](PCI location=%s) registered\n", slot->name, |
190 | slot->location); | 183 | slot->location); |
191 | num_slots++; | 184 | num_slots++; |
192 | return 0; | 185 | return 0; |
186 | |||
187 | sysfs_fail: | ||
188 | pci_hp_deregister(php_slot); | ||
189 | register_fail: | ||
190 | rpaphp_release_slot(php_slot); | ||
191 | return retval; | ||
193 | } | 192 | } |
194 | 193 | ||
195 | int rpaphp_get_power_status(struct slot *slot, u8 * value) | 194 | int rpaphp_get_power_status(struct slot *slot, u8 * value) |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 50757695844f..3ca6a4f574b3 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -47,11 +47,17 @@ extern int shpchp_poll_time; | |||
47 | extern int shpchp_debug; | 47 | extern int shpchp_debug; |
48 | extern struct workqueue_struct *shpchp_wq; | 48 | extern struct workqueue_struct *shpchp_wq; |
49 | 49 | ||
50 | /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ | 50 | #define dbg(format, arg...) \ |
51 | #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) | 51 | do { \ |
52 | #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | 52 | if (shpchp_debug) \ |
53 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | 53 | printk("%s: " format, MY_NAME , ## arg); \ |
54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | 54 | } while (0) |
55 | #define err(format, arg...) \ | ||
56 | printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | ||
57 | #define info(format, arg...) \ | ||
58 | printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | ||
59 | #define warn(format, arg...) \ | ||
60 | printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | ||
55 | 61 | ||
56 | #define SLOT_NAME_SIZE 10 | 62 | #define SLOT_NAME_SIZE 10 |
57 | struct slot { | 63 | struct slot { |
@@ -83,34 +89,27 @@ struct event_info { | |||
83 | struct controller { | 89 | struct controller { |
84 | struct mutex crit_sect; /* critical section mutex */ | 90 | struct mutex crit_sect; /* critical section mutex */ |
85 | struct mutex cmd_lock; /* command lock */ | 91 | struct mutex cmd_lock; /* command lock */ |
86 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ | ||
87 | int num_slots; /* Number of slots on ctlr */ | 92 | int num_slots; /* Number of slots on ctlr */ |
88 | int slot_num_inc; /* 1 or -1 */ | 93 | int slot_num_inc; /* 1 or -1 */ |
89 | struct pci_dev *pci_dev; | 94 | struct pci_dev *pci_dev; |
90 | struct list_head slot_list; | 95 | struct list_head slot_list; |
91 | struct hpc_ops *hpc_ops; | 96 | struct hpc_ops *hpc_ops; |
92 | wait_queue_head_t queue; /* sleep & wake process */ | 97 | wait_queue_head_t queue; /* sleep & wake process */ |
93 | u8 bus; | ||
94 | u8 device; | ||
95 | u8 function; | ||
96 | u8 slot_device_offset; | 98 | u8 slot_device_offset; |
97 | u8 add_support; | ||
98 | u32 pcix_misc2_reg; /* for amd pogo errata */ | 99 | u32 pcix_misc2_reg; /* for amd pogo errata */ |
99 | enum pci_bus_speed speed; | ||
100 | u32 first_slot; /* First physical slot number */ | 100 | u32 first_slot; /* First physical slot number */ |
101 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ | ||
102 | u32 cap_offset; | 101 | u32 cap_offset; |
103 | unsigned long mmio_base; | 102 | unsigned long mmio_base; |
104 | unsigned long mmio_size; | 103 | unsigned long mmio_size; |
104 | void __iomem *creg; | ||
105 | struct timer_list poll_timer; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | |||
108 | /* Define AMD SHPC ID */ | 108 | /* Define AMD SHPC ID */ |
109 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 | 109 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 |
110 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 | 110 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 |
111 | 111 | ||
112 | /* AMD PCIX bridge registers */ | 112 | /* AMD PCIX bridge registers */ |
113 | |||
114 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C | 113 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C |
115 | #define PCIX_MISCII_OFFSET 0x48 | 114 | #define PCIX_MISCII_OFFSET 0x48 |
116 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 | 115 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 |
@@ -145,8 +144,6 @@ struct controller { | |||
145 | #define POWERON_STATE 3 | 144 | #define POWERON_STATE 3 |
146 | #define POWEROFF_STATE 4 | 145 | #define POWEROFF_STATE 4 |
147 | 146 | ||
148 | #define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 | ||
149 | |||
150 | /* Error messages */ | 147 | /* Error messages */ |
151 | #define INTERLOCK_OPEN 0x00000002 | 148 | #define INTERLOCK_OPEN 0x00000002 |
152 | #define ADD_NOT_SUPPORTED 0x00000003 | 149 | #define ADD_NOT_SUPPORTED 0x00000003 |
@@ -158,50 +155,32 @@ struct controller { | |||
158 | #define WRONG_BUS_FREQUENCY 0x0000000D | 155 | #define WRONG_BUS_FREQUENCY 0x0000000D |
159 | #define POWER_FAILURE 0x0000000E | 156 | #define POWER_FAILURE 0x0000000E |
160 | 157 | ||
161 | #define REMOVE_NOT_SUPPORTED 0x00000003 | ||
162 | |||
163 | #define DISABLE_CARD 1 | ||
164 | |||
165 | /* | ||
166 | * error Messages | ||
167 | */ | ||
168 | #define msg_initialization_err "Initialization failure, error=%d\n" | ||
169 | #define msg_button_on "PCI slot #%s - powering on due to button press.\n" | ||
170 | #define msg_button_off "PCI slot #%s - powering off due to button press.\n" | ||
171 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" | ||
172 | |||
173 | /* sysfs functions for the hotplug controller info */ | ||
174 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); | 158 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); |
175 | 159 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | |
176 | extern int shpchp_sysfs_enable_slot(struct slot *slot); | 160 | extern int shpchp_sysfs_enable_slot(struct slot *slot); |
177 | extern int shpchp_sysfs_disable_slot(struct slot *slot); | 161 | extern int shpchp_sysfs_disable_slot(struct slot *slot); |
178 | 162 | extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); | |
179 | extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id); | 163 | extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); |
180 | extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id); | 164 | extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); |
181 | extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id); | 165 | extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); |
182 | extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id); | 166 | extern int shpchp_configure_device(struct slot *p_slot); |
183 | 167 | extern int shpchp_unconfigure_device(struct slot *p_slot); | |
184 | /* pci functions */ | 168 | extern void cleanup_slots(struct controller *ctrl); |
185 | extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); | 169 | extern void queue_pushbutton_work(struct work_struct *work); |
186 | extern int shpchp_configure_device(struct slot *p_slot); | 170 | extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); |
187 | extern int shpchp_unconfigure_device(struct slot *p_slot); | ||
188 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | ||
189 | extern void cleanup_slots(struct controller *ctrl); | ||
190 | extern void queue_pushbutton_work(struct work_struct *work); | ||
191 | |||
192 | 171 | ||
193 | #ifdef CONFIG_ACPI | 172 | #ifdef CONFIG_ACPI |
194 | static inline int get_hp_params_from_firmware(struct pci_dev *dev, | 173 | static inline int get_hp_params_from_firmware(struct pci_dev *dev, |
195 | struct hotplug_params *hpp) | 174 | struct hotplug_params *hpp) |
196 | { | 175 | { |
197 | if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) | 176 | if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) |
198 | return -ENODEV; | 177 | return -ENODEV; |
199 | return 0; | 178 | return 0; |
200 | } | 179 | } |
201 | #define get_hp_hw_control_from_firmware(pdev) \ | 180 | #define get_hp_hw_control_from_firmware(pdev) \ |
202 | do { \ | 181 | do { \ |
203 | if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ | 182 | if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ |
204 | acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \ | 183 | acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\ |
205 | } while (0) | 184 | } while (0) |
206 | #else | 185 | #else |
207 | #define get_hp_params_from_firmware(dev, hpp) (-ENODEV) | 186 | #define get_hp_params_from_firmware(dev, hpp) (-ENODEV) |
@@ -222,108 +201,40 @@ struct ctrl_reg { | |||
222 | volatile u32 serr_loc; | 201 | volatile u32 serr_loc; |
223 | volatile u32 serr_intr_enable; | 202 | volatile u32 serr_intr_enable; |
224 | volatile u32 slot1; | 203 | volatile u32 slot1; |
225 | volatile u32 slot2; | ||
226 | volatile u32 slot3; | ||
227 | volatile u32 slot4; | ||
228 | volatile u32 slot5; | ||
229 | volatile u32 slot6; | ||
230 | volatile u32 slot7; | ||
231 | volatile u32 slot8; | ||
232 | volatile u32 slot9; | ||
233 | volatile u32 slot10; | ||
234 | volatile u32 slot11; | ||
235 | volatile u32 slot12; | ||
236 | } __attribute__ ((packed)); | 204 | } __attribute__ ((packed)); |
237 | 205 | ||
238 | /* offsets to the controller registers based on the above structure layout */ | 206 | /* offsets to the controller registers based on the above structure layout */ |
239 | enum ctrl_offsets { | 207 | enum ctrl_offsets { |
240 | BASE_OFFSET = offsetof(struct ctrl_reg, base_offset), | 208 | BASE_OFFSET = offsetof(struct ctrl_reg, base_offset), |
241 | SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1), | 209 | SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1), |
242 | SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2), | 210 | SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2), |
243 | SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config), | 211 | SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config), |
244 | SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config), | 212 | SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config), |
245 | MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl), | 213 | MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl), |
246 | PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface), | 214 | PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface), |
247 | CMD = offsetof(struct ctrl_reg, cmd), | 215 | CMD = offsetof(struct ctrl_reg, cmd), |
248 | CMD_STATUS = offsetof(struct ctrl_reg, cmd_status), | 216 | CMD_STATUS = offsetof(struct ctrl_reg, cmd_status), |
249 | INTR_LOC = offsetof(struct ctrl_reg, intr_loc), | 217 | INTR_LOC = offsetof(struct ctrl_reg, intr_loc), |
250 | SERR_LOC = offsetof(struct ctrl_reg, serr_loc), | 218 | SERR_LOC = offsetof(struct ctrl_reg, serr_loc), |
251 | SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable), | 219 | SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable), |
252 | SLOT1 = offsetof(struct ctrl_reg, slot1), | 220 | SLOT1 = offsetof(struct ctrl_reg, slot1), |
253 | SLOT2 = offsetof(struct ctrl_reg, slot2), | ||
254 | SLOT3 = offsetof(struct ctrl_reg, slot3), | ||
255 | SLOT4 = offsetof(struct ctrl_reg, slot4), | ||
256 | SLOT5 = offsetof(struct ctrl_reg, slot5), | ||
257 | SLOT6 = offsetof(struct ctrl_reg, slot6), | ||
258 | SLOT7 = offsetof(struct ctrl_reg, slot7), | ||
259 | SLOT8 = offsetof(struct ctrl_reg, slot8), | ||
260 | SLOT9 = offsetof(struct ctrl_reg, slot9), | ||
261 | SLOT10 = offsetof(struct ctrl_reg, slot10), | ||
262 | SLOT11 = offsetof(struct ctrl_reg, slot11), | ||
263 | SLOT12 = offsetof(struct ctrl_reg, slot12), | ||
264 | }; | ||
265 | typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); | ||
266 | struct php_ctlr_state_s { | ||
267 | struct php_ctlr_state_s *pnext; | ||
268 | struct pci_dev *pci_dev; | ||
269 | unsigned int irq; | ||
270 | unsigned long flags; /* spinlock's */ | ||
271 | u32 slot_device_offset; | ||
272 | u32 num_slots; | ||
273 | struct timer_list int_poll_timer; /* Added for poll event */ | ||
274 | php_intr_callback_t attention_button_callback; | ||
275 | php_intr_callback_t switch_change_callback; | ||
276 | php_intr_callback_t presence_change_callback; | ||
277 | php_intr_callback_t power_fault_callback; | ||
278 | void *callback_instance_id; | ||
279 | void __iomem *creg; /* Ptr to controller register space */ | ||
280 | }; | 221 | }; |
281 | /* Inline functions */ | ||
282 | 222 | ||
283 | 223 | static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) | |
284 | /* Inline functions to check the sanity of a pointer that is passed to us */ | ||
285 | static inline int slot_paranoia_check (struct slot *slot, const char *function) | ||
286 | { | ||
287 | if (!slot) { | ||
288 | dbg("%s - slot == NULL", function); | ||
289 | return -1; | ||
290 | } | ||
291 | if (!slot->hotplug_slot) { | ||
292 | dbg("%s - slot->hotplug_slot == NULL!", function); | ||
293 | return -1; | ||
294 | } | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function) | ||
299 | { | 224 | { |
300 | struct slot *slot; | 225 | return hotplug_slot->private; |
301 | |||
302 | if (!hotplug_slot) { | ||
303 | dbg("%s - hotplug_slot == NULL\n", function); | ||
304 | return NULL; | ||
305 | } | ||
306 | |||
307 | slot = (struct slot *)hotplug_slot->private; | ||
308 | if (slot_paranoia_check (slot, function)) | ||
309 | return NULL; | ||
310 | return slot; | ||
311 | } | 226 | } |
312 | 227 | ||
313 | static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device) | 228 | static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device) |
314 | { | 229 | { |
315 | struct slot *slot; | 230 | struct slot *slot; |
316 | 231 | ||
317 | if (!ctrl) | ||
318 | return NULL; | ||
319 | |||
320 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) { | 232 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) { |
321 | if (slot->device == device) | 233 | if (slot->device == device) |
322 | return slot; | 234 | return slot; |
323 | } | 235 | } |
324 | 236 | ||
325 | err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); | 237 | err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); |
326 | |||
327 | return NULL; | 238 | return NULL; |
328 | } | 239 | } |
329 | 240 | ||
@@ -400,44 +311,27 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot) | |||
400 | pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); | 311 | pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); |
401 | } | 312 | } |
402 | 313 | ||
403 | enum php_ctlr_type { | ||
404 | PCI, | ||
405 | ISA, | ||
406 | ACPI | ||
407 | }; | ||
408 | |||
409 | int shpc_init( struct controller *ctrl, struct pci_dev *pdev); | ||
410 | |||
411 | int shpc_get_ctlr_slot_config( struct controller *ctrl, | ||
412 | int *num_ctlr_slots, | ||
413 | int *first_device_num, | ||
414 | int *physical_slot_num, | ||
415 | int *updown, | ||
416 | int *flags); | ||
417 | |||
418 | struct hpc_ops { | 314 | struct hpc_ops { |
419 | int (*power_on_slot ) (struct slot *slot); | 315 | int (*power_on_slot)(struct slot *slot); |
420 | int (*slot_enable ) (struct slot *slot); | 316 | int (*slot_enable)(struct slot *slot); |
421 | int (*slot_disable ) (struct slot *slot); | 317 | int (*slot_disable)(struct slot *slot); |
422 | int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed); | 318 | int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed); |
423 | int (*get_power_status) (struct slot *slot, u8 *status); | 319 | int (*get_power_status)(struct slot *slot, u8 *status); |
424 | int (*get_attention_status) (struct slot *slot, u8 *status); | 320 | int (*get_attention_status)(struct slot *slot, u8 *status); |
425 | int (*set_attention_status) (struct slot *slot, u8 status); | 321 | int (*set_attention_status)(struct slot *slot, u8 status); |
426 | int (*get_latch_status) (struct slot *slot, u8 *status); | 322 | int (*get_latch_status)(struct slot *slot, u8 *status); |
427 | int (*get_adapter_status) (struct slot *slot, u8 *status); | 323 | int (*get_adapter_status)(struct slot *slot, u8 *status); |
428 | 324 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | |
429 | int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); | 325 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); |
430 | int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); | 326 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); |
431 | int (*get_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed); | 327 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); |
432 | int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode); | 328 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); |
433 | int (*get_prog_int) (struct slot *slot, u8 *prog_int); | 329 | int (*query_power_fault)(struct slot *slot); |
434 | 330 | void (*green_led_on)(struct slot *slot); | |
435 | int (*query_power_fault) (struct slot *slot); | 331 | void (*green_led_off)(struct slot *slot); |
436 | void (*green_led_on) (struct slot *slot); | 332 | void (*green_led_blink)(struct slot *slot); |
437 | void (*green_led_off) (struct slot *slot); | 333 | void (*release_ctlr)(struct controller *ctrl); |
438 | void (*green_led_blink) (struct slot *slot); | 334 | int (*check_cmd_status)(struct controller *ctrl); |
439 | void (*release_ctlr) (struct controller *ctrl); | ||
440 | int (*check_cmd_status) (struct controller *ctrl); | ||
441 | }; | 335 | }; |
442 | 336 | ||
443 | #endif /* _SHPCHP_H */ | 337 | #endif /* _SHPCHP_H */ |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 4eac85b3d90e..590cd3cbe010 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -104,23 +104,6 @@ static void make_slot_name(struct slot *slot) | |||
104 | slot->bus, slot->number); | 104 | slot->bus, slot->number); |
105 | } | 105 | } |
106 | 106 | ||
107 | |||
108 | |||
109 | |||
110 | static int | ||
111 | shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, | ||
112 | u8 busnum, u8 devnum) | ||
113 | { | ||
114 | int offset = devnum - ctrl->slot_device_offset; | ||
115 | |||
116 | dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, | ||
117 | ctrl->slot_num_inc, offset); | ||
118 | *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | |||
123 | |||
124 | static int init_slots(struct controller *ctrl) | 107 | static int init_slots(struct controller *ctrl) |
125 | { | 108 | { |
126 | struct slot *slot; | 109 | struct slot *slot; |
@@ -128,7 +111,6 @@ static int init_slots(struct controller *ctrl) | |||
128 | struct hotplug_slot_info *info; | 111 | struct hotplug_slot_info *info; |
129 | int retval = -ENOMEM; | 112 | int retval = -ENOMEM; |
130 | int i; | 113 | int i; |
131 | u32 sun; | ||
132 | 114 | ||
133 | for (i = 0; i < ctrl->num_slots; i++) { | 115 | for (i = 0; i < ctrl->num_slots; i++) { |
134 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 116 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
@@ -149,16 +131,11 @@ static int init_slots(struct controller *ctrl) | |||
149 | 131 | ||
150 | slot->hp_slot = i; | 132 | slot->hp_slot = i; |
151 | slot->ctrl = ctrl; | 133 | slot->ctrl = ctrl; |
152 | slot->bus = ctrl->slot_bus; | 134 | slot->bus = ctrl->pci_dev->subordinate->number; |
153 | slot->device = ctrl->slot_device_offset + i; | 135 | slot->device = ctrl->slot_device_offset + i; |
154 | slot->hpc_ops = ctrl->hpc_ops; | 136 | slot->hpc_ops = ctrl->hpc_ops; |
137 | slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); | ||
155 | mutex_init(&slot->lock); | 138 | mutex_init(&slot->lock); |
156 | |||
157 | if (shpchprm_get_physical_slot_number(ctrl, &sun, | ||
158 | slot->bus, slot->device)) | ||
159 | goto error_info; | ||
160 | |||
161 | slot->number = sun; | ||
162 | INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); | 139 | INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); |
163 | 140 | ||
164 | /* register this slot with the hotplug pci core */ | 141 | /* register this slot with the hotplug pci core */ |
@@ -211,42 +188,12 @@ void cleanup_slots(struct controller *ctrl) | |||
211 | } | 188 | } |
212 | } | 189 | } |
213 | 190 | ||
214 | static int get_ctlr_slot_config(struct controller *ctrl) | ||
215 | { | ||
216 | int num_ctlr_slots; | ||
217 | int first_device_num; | ||
218 | int physical_slot_num; | ||
219 | int updown; | ||
220 | int rc; | ||
221 | int flags; | ||
222 | |||
223 | rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, | ||
224 | &first_device_num, &physical_slot_num, | ||
225 | &updown, &flags); | ||
226 | if (rc) { | ||
227 | err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", | ||
228 | __FUNCTION__, ctrl->bus, ctrl->device); | ||
229 | return -1; | ||
230 | } | ||
231 | |||
232 | ctrl->num_slots = num_ctlr_slots; | ||
233 | ctrl->slot_device_offset = first_device_num; | ||
234 | ctrl->first_slot = physical_slot_num; | ||
235 | ctrl->slot_num_inc = updown; /* either -1 or 1 */ | ||
236 | |||
237 | dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d " | ||
238 | "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num, | ||
239 | physical_slot_num, updown, ctrl->bus, ctrl->device); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | /* | 191 | /* |
245 | * set_attention_status - Turns the Amber LED for a slot on, off or blink | 192 | * set_attention_status - Turns the Amber LED for a slot on, off or blink |
246 | */ | 193 | */ |
247 | static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) | 194 | static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) |
248 | { | 195 | { |
249 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 196 | struct slot *slot = get_slot(hotplug_slot); |
250 | 197 | ||
251 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 198 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
252 | 199 | ||
@@ -258,7 +205,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) | |||
258 | 205 | ||
259 | static int enable_slot (struct hotplug_slot *hotplug_slot) | 206 | static int enable_slot (struct hotplug_slot *hotplug_slot) |
260 | { | 207 | { |
261 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 208 | struct slot *slot = get_slot(hotplug_slot); |
262 | 209 | ||
263 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 210 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
264 | 211 | ||
@@ -267,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot) | |||
267 | 214 | ||
268 | static int disable_slot (struct hotplug_slot *hotplug_slot) | 215 | static int disable_slot (struct hotplug_slot *hotplug_slot) |
269 | { | 216 | { |
270 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 217 | struct slot *slot = get_slot(hotplug_slot); |
271 | 218 | ||
272 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 219 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
273 | 220 | ||
@@ -276,7 +223,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot) | |||
276 | 223 | ||
277 | static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) | 224 | static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) |
278 | { | 225 | { |
279 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 226 | struct slot *slot = get_slot(hotplug_slot); |
280 | int retval; | 227 | int retval; |
281 | 228 | ||
282 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 229 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -290,7 +237,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
290 | 237 | ||
291 | static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) | 238 | static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) |
292 | { | 239 | { |
293 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 240 | struct slot *slot = get_slot(hotplug_slot); |
294 | int retval; | 241 | int retval; |
295 | 242 | ||
296 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 243 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -304,7 +251,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
304 | 251 | ||
305 | static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) | 252 | static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) |
306 | { | 253 | { |
307 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 254 | struct slot *slot = get_slot(hotplug_slot); |
308 | int retval; | 255 | int retval; |
309 | 256 | ||
310 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 257 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -318,7 +265,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
318 | 265 | ||
319 | static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | 266 | static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) |
320 | { | 267 | { |
321 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 268 | struct slot *slot = get_slot(hotplug_slot); |
322 | int retval; | 269 | int retval; |
323 | 270 | ||
324 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 271 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -332,7 +279,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
332 | 279 | ||
333 | static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) | 280 | static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) |
334 | { | 281 | { |
335 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 282 | struct slot *slot = get_slot(hotplug_slot); |
336 | struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; | 283 | struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; |
337 | 284 | ||
338 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 285 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -344,7 +291,7 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) | |||
344 | 291 | ||
345 | static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 292 | static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) |
346 | { | 293 | { |
347 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 294 | struct slot *slot = get_slot(hotplug_slot); |
348 | int retval; | 295 | int retval; |
349 | 296 | ||
350 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 297 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -358,7 +305,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp | |||
358 | 305 | ||
359 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 306 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) |
360 | { | 307 | { |
361 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 308 | struct slot *slot = get_slot(hotplug_slot); |
362 | int retval; | 309 | int retval; |
363 | 310 | ||
364 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 311 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
@@ -385,9 +332,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
385 | { | 332 | { |
386 | int rc; | 333 | int rc; |
387 | struct controller *ctrl; | 334 | struct controller *ctrl; |
388 | struct slot *t_slot; | ||
389 | int first_device_num; /* first PCI device number */ | ||
390 | int num_ctlr_slots; /* number of slots implemented */ | ||
391 | 335 | ||
392 | if (!is_shpc_capable(pdev)) | 336 | if (!is_shpc_capable(pdev)) |
393 | return -ENODEV; | 337 | return -ENODEV; |
@@ -408,47 +352,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
408 | 352 | ||
409 | pci_set_drvdata(pdev, ctrl); | 353 | pci_set_drvdata(pdev, ctrl); |
410 | 354 | ||
411 | ctrl->bus = pdev->bus->number; | ||
412 | ctrl->slot_bus = pdev->subordinate->number; | ||
413 | ctrl->device = PCI_SLOT(pdev->devfn); | ||
414 | ctrl->function = PCI_FUNC(pdev->devfn); | ||
415 | |||
416 | dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", | ||
417 | ctrl->bus, ctrl->device, ctrl->function, pdev->irq); | ||
418 | |||
419 | /* | ||
420 | * Save configuration headers for this and subordinate PCI buses | ||
421 | */ | ||
422 | rc = get_ctlr_slot_config(ctrl); | ||
423 | if (rc) { | ||
424 | err(msg_initialization_err, rc); | ||
425 | goto err_out_release_ctlr; | ||
426 | } | ||
427 | first_device_num = ctrl->slot_device_offset; | ||
428 | num_ctlr_slots = ctrl->num_slots; | ||
429 | |||
430 | ctrl->add_support = 1; | ||
431 | |||
432 | /* Setup the slot information structures */ | 355 | /* Setup the slot information structures */ |
433 | rc = init_slots(ctrl); | 356 | rc = init_slots(ctrl); |
434 | if (rc) { | 357 | if (rc) { |
435 | err(msg_initialization_err, 6); | 358 | err("%s: slot initialization failed\n", SHPC_MODULE_NAME); |
436 | goto err_out_release_ctlr; | 359 | goto err_out_release_ctlr; |
437 | } | 360 | } |
438 | 361 | ||
439 | /* Now hpc_functions (slot->hpc_ops->functions) are ready */ | ||
440 | t_slot = shpchp_find_slot(ctrl, first_device_num); | ||
441 | |||
442 | /* Check for operation bus speed */ | ||
443 | rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed); | ||
444 | dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot); | ||
445 | |||
446 | if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) { | ||
447 | err(SHPC_MODULE_NAME ": Can't get current bus speed. " | ||
448 | "Set to 33MHz PCI.\n"); | ||
449 | ctrl->speed = PCI_SPEED_33MHz; | ||
450 | } | ||
451 | |||
452 | rc = shpchp_create_ctrl_files(ctrl); | 362 | rc = shpchp_create_ctrl_files(ctrl); |
453 | if (rc) | 363 | if (rc) |
454 | goto err_cleanup_slots; | 364 | goto err_cleanup_slots; |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 158ac7836096..6bb84734cd6c 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -57,9 +57,8 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | 60 | u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) |
61 | { | 61 | { |
62 | struct controller *ctrl = (struct controller *) inst_id; | ||
63 | struct slot *p_slot; | 62 | struct slot *p_slot; |
64 | u32 event_type; | 63 | u32 event_type; |
65 | 64 | ||
@@ -81,9 +80,8 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
81 | 80 | ||
82 | } | 81 | } |
83 | 82 | ||
84 | u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | 83 | u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl) |
85 | { | 84 | { |
86 | struct controller *ctrl = (struct controller *) inst_id; | ||
87 | struct slot *p_slot; | 85 | struct slot *p_slot; |
88 | u8 getstatus; | 86 | u8 getstatus; |
89 | u32 event_type; | 87 | u32 event_type; |
@@ -120,9 +118,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
120 | return 1; | 118 | return 1; |
121 | } | 119 | } |
122 | 120 | ||
123 | u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) | 121 | u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) |
124 | { | 122 | { |
125 | struct controller *ctrl = (struct controller *) inst_id; | ||
126 | struct slot *p_slot; | 123 | struct slot *p_slot; |
127 | u32 event_type; | 124 | u32 event_type; |
128 | 125 | ||
@@ -154,9 +151,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) | |||
154 | return 1; | 151 | return 1; |
155 | } | 152 | } |
156 | 153 | ||
157 | u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) | 154 | u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) |
158 | { | 155 | { |
159 | struct controller *ctrl = (struct controller *) inst_id; | ||
160 | struct slot *p_slot; | 156 | struct slot *p_slot; |
161 | u32 event_type; | 157 | u32 event_type; |
162 | 158 | ||
@@ -497,10 +493,12 @@ static void handle_button_press_event(struct slot *p_slot) | |||
497 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 493 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
498 | if (getstatus) { | 494 | if (getstatus) { |
499 | p_slot->state = BLINKINGOFF_STATE; | 495 | p_slot->state = BLINKINGOFF_STATE; |
500 | info(msg_button_off, p_slot->name); | 496 | info("PCI slot #%s - powering off due to button " |
497 | "press.\n", p_slot->name); | ||
501 | } else { | 498 | } else { |
502 | p_slot->state = BLINKINGON_STATE; | 499 | p_slot->state = BLINKINGON_STATE; |
503 | info(msg_button_on, p_slot->name); | 500 | info("PCI slot #%s - powering on due to button " |
501 | "press.\n", p_slot->name); | ||
504 | } | 502 | } |
505 | /* blink green LED and turn off amber */ | 503 | /* blink green LED and turn off amber */ |
506 | p_slot->hpc_ops->green_led_blink(p_slot); | 504 | p_slot->hpc_ops->green_led_blink(p_slot); |
@@ -523,7 +521,8 @@ static void handle_button_press_event(struct slot *p_slot) | |||
523 | else | 521 | else |
524 | p_slot->hpc_ops->green_led_off(p_slot); | 522 | p_slot->hpc_ops->green_led_off(p_slot); |
525 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 523 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
526 | info(msg_button_cancel, p_slot->name); | 524 | info("PCI slot #%s - action canceled due to button press\n", |
525 | p_slot->name); | ||
527 | p_slot->state = STATIC_STATE; | 526 | p_slot->state = STATIC_STATE; |
528 | break; | 527 | break; |
529 | case POWEROFF_STATE: | 528 | case POWEROFF_STATE: |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 83a5226ba9ed..b7bede4b7c27 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -212,44 +212,40 @@ | |||
212 | #define SLOT_SERR_INT_MASK 0x3 | 212 | #define SLOT_SERR_INT_MASK 0x3 |
213 | 213 | ||
214 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ | 214 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ |
215 | static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ | ||
216 | static int ctlr_seq_num = 0; /* Controller sequenc # */ | ||
217 | static spinlock_t list_lock; | ||
218 | |||
219 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); | 215 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); |
220 | 216 | ||
221 | static irqreturn_t shpc_isr(int irq, void *dev_id); | 217 | static irqreturn_t shpc_isr(int irq, void *dev_id); |
222 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec); | 218 | static void start_int_poll_timer(struct controller *ctrl, int sec); |
223 | static int hpc_check_cmd_status(struct controller *ctrl); | 219 | static int hpc_check_cmd_status(struct controller *ctrl); |
224 | 220 | ||
225 | static inline u8 shpc_readb(struct controller *ctrl, int reg) | 221 | static inline u8 shpc_readb(struct controller *ctrl, int reg) |
226 | { | 222 | { |
227 | return readb(ctrl->hpc_ctlr_handle->creg + reg); | 223 | return readb(ctrl->creg + reg); |
228 | } | 224 | } |
229 | 225 | ||
230 | static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) | 226 | static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) |
231 | { | 227 | { |
232 | writeb(val, ctrl->hpc_ctlr_handle->creg + reg); | 228 | writeb(val, ctrl->creg + reg); |
233 | } | 229 | } |
234 | 230 | ||
235 | static inline u16 shpc_readw(struct controller *ctrl, int reg) | 231 | static inline u16 shpc_readw(struct controller *ctrl, int reg) |
236 | { | 232 | { |
237 | return readw(ctrl->hpc_ctlr_handle->creg + reg); | 233 | return readw(ctrl->creg + reg); |
238 | } | 234 | } |
239 | 235 | ||
240 | static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) | 236 | static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) |
241 | { | 237 | { |
242 | writew(val, ctrl->hpc_ctlr_handle->creg + reg); | 238 | writew(val, ctrl->creg + reg); |
243 | } | 239 | } |
244 | 240 | ||
245 | static inline u32 shpc_readl(struct controller *ctrl, int reg) | 241 | static inline u32 shpc_readl(struct controller *ctrl, int reg) |
246 | { | 242 | { |
247 | return readl(ctrl->hpc_ctlr_handle->creg + reg); | 243 | return readl(ctrl->creg + reg); |
248 | } | 244 | } |
249 | 245 | ||
250 | static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) | 246 | static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) |
251 | { | 247 | { |
252 | writel(val, ctrl->hpc_ctlr_handle->creg + reg); | 248 | writel(val, ctrl->creg + reg); |
253 | } | 249 | } |
254 | 250 | ||
255 | static inline int shpc_indirect_read(struct controller *ctrl, int index, | 251 | static inline int shpc_indirect_read(struct controller *ctrl, int index, |
@@ -268,21 +264,20 @@ static inline int shpc_indirect_read(struct controller *ctrl, int index, | |||
268 | /* | 264 | /* |
269 | * This is the interrupt polling timeout function. | 265 | * This is the interrupt polling timeout function. |
270 | */ | 266 | */ |
271 | static void int_poll_timeout(unsigned long lphp_ctlr) | 267 | static void int_poll_timeout(unsigned long data) |
272 | { | 268 | { |
273 | struct php_ctlr_state_s *php_ctlr = | 269 | struct controller *ctrl = (struct controller *)data; |
274 | (struct php_ctlr_state_s *)lphp_ctlr; | ||
275 | 270 | ||
276 | DBG_ENTER_ROUTINE | 271 | DBG_ENTER_ROUTINE |
277 | 272 | ||
278 | /* Poll for interrupt events. regs == NULL => polling */ | 273 | /* Poll for interrupt events. regs == NULL => polling */ |
279 | shpc_isr(0, php_ctlr->callback_instance_id); | 274 | shpc_isr(0, ctrl); |
280 | 275 | ||
281 | init_timer(&php_ctlr->int_poll_timer); | 276 | init_timer(&ctrl->poll_timer); |
282 | if (!shpchp_poll_time) | 277 | if (!shpchp_poll_time) |
283 | shpchp_poll_time = 2; /* default polling interval is 2 sec */ | 278 | shpchp_poll_time = 2; /* default polling interval is 2 sec */ |
284 | 279 | ||
285 | start_int_poll_timer(php_ctlr, shpchp_poll_time); | 280 | start_int_poll_timer(ctrl, shpchp_poll_time); |
286 | 281 | ||
287 | DBG_LEAVE_ROUTINE | 282 | DBG_LEAVE_ROUTINE |
288 | } | 283 | } |
@@ -290,16 +285,16 @@ static void int_poll_timeout(unsigned long lphp_ctlr) | |||
290 | /* | 285 | /* |
291 | * This function starts the interrupt polling timer. | 286 | * This function starts the interrupt polling timer. |
292 | */ | 287 | */ |
293 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) | 288 | static void start_int_poll_timer(struct controller *ctrl, int sec) |
294 | { | 289 | { |
295 | /* Clamp to sane value */ | 290 | /* Clamp to sane value */ |
296 | if ((sec <= 0) || (sec > 60)) | 291 | if ((sec <= 0) || (sec > 60)) |
297 | sec = 2; | 292 | sec = 2; |
298 | 293 | ||
299 | php_ctlr->int_poll_timer.function = &int_poll_timeout; | 294 | ctrl->poll_timer.function = &int_poll_timeout; |
300 | php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; | 295 | ctrl->poll_timer.data = (unsigned long)ctrl; |
301 | php_ctlr->int_poll_timer.expires = jiffies + sec * HZ; | 296 | ctrl->poll_timer.expires = jiffies + sec * HZ; |
302 | add_timer(&php_ctlr->int_poll_timer); | 297 | add_timer(&ctrl->poll_timer); |
303 | } | 298 | } |
304 | 299 | ||
305 | static inline int is_ctrl_busy(struct controller *ctrl) | 300 | static inline int is_ctrl_busy(struct controller *ctrl) |
@@ -666,33 +661,8 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
666 | shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK); | 661 | shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK); |
667 | } | 662 | } |
668 | 663 | ||
669 | int shpc_get_ctlr_slot_config(struct controller *ctrl, | ||
670 | int *num_ctlr_slots, /* number of slots in this HPC */ | ||
671 | int *first_device_num, /* PCI dev num of the first slot in this SHPC */ | ||
672 | int *physical_slot_num, /* phy slot num of the first slot in this SHPC */ | ||
673 | int *updown, /* physical_slot_num increament: 1 or -1 */ | ||
674 | int *flags) | ||
675 | { | ||
676 | u32 slot_config; | ||
677 | |||
678 | DBG_ENTER_ROUTINE | ||
679 | |||
680 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); | ||
681 | *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8; | ||
682 | *num_ctlr_slots = slot_config & SLOT_NUM; | ||
683 | *physical_slot_num = (slot_config & PSN) >> 16; | ||
684 | *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1; | ||
685 | |||
686 | dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); | ||
687 | |||
688 | DBG_LEAVE_ROUTINE | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | static void hpc_release_ctlr(struct controller *ctrl) | 664 | static void hpc_release_ctlr(struct controller *ctrl) |
693 | { | 665 | { |
694 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
695 | struct php_ctlr_state_s *p, *p_prev; | ||
696 | int i; | 666 | int i; |
697 | u32 slot_reg, serr_int; | 667 | u32 slot_reg, serr_int; |
698 | 668 | ||
@@ -722,40 +692,15 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
722 | serr_int &= ~SERR_INTR_RSVDZ_MASK; | 692 | serr_int &= ~SERR_INTR_RSVDZ_MASK; |
723 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); | 693 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); |
724 | 694 | ||
725 | if (shpchp_poll_mode) { | 695 | if (shpchp_poll_mode) |
726 | del_timer(&php_ctlr->int_poll_timer); | 696 | del_timer(&ctrl->poll_timer); |
727 | } else { | 697 | else { |
728 | if (php_ctlr->irq) { | 698 | free_irq(ctrl->pci_dev->irq, ctrl); |
729 | free_irq(php_ctlr->irq, ctrl); | 699 | pci_disable_msi(ctrl->pci_dev); |
730 | php_ctlr->irq = 0; | ||
731 | pci_disable_msi(php_ctlr->pci_dev); | ||
732 | } | ||
733 | } | ||
734 | |||
735 | if (php_ctlr->pci_dev) { | ||
736 | iounmap(php_ctlr->creg); | ||
737 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | ||
738 | php_ctlr->pci_dev = NULL; | ||
739 | } | ||
740 | |||
741 | spin_lock(&list_lock); | ||
742 | p = php_ctlr_list_head; | ||
743 | p_prev = NULL; | ||
744 | while (p) { | ||
745 | if (p == php_ctlr) { | ||
746 | if (p_prev) | ||
747 | p_prev->pnext = p->pnext; | ||
748 | else | ||
749 | php_ctlr_list_head = p->pnext; | ||
750 | break; | ||
751 | } else { | ||
752 | p_prev = p; | ||
753 | p = p->pnext; | ||
754 | } | ||
755 | } | 700 | } |
756 | spin_unlock(&list_lock); | ||
757 | 701 | ||
758 | kfree(php_ctlr); | 702 | iounmap(ctrl->creg); |
703 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | ||
759 | 704 | ||
760 | /* | 705 | /* |
761 | * If this is the last controller to be released, destroy the | 706 | * If this is the last controller to be released, destroy the |
@@ -764,8 +709,7 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
764 | if (atomic_dec_and_test(&shpchp_num_controllers)) | 709 | if (atomic_dec_and_test(&shpchp_num_controllers)) |
765 | destroy_workqueue(shpchp_wq); | 710 | destroy_workqueue(shpchp_wq); |
766 | 711 | ||
767 | DBG_LEAVE_ROUTINE | 712 | DBG_LEAVE_ROUTINE |
768 | |||
769 | } | 713 | } |
770 | 714 | ||
771 | static int hpc_power_on_slot(struct slot * slot) | 715 | static int hpc_power_on_slot(struct slot * slot) |
@@ -891,7 +835,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
891 | static irqreturn_t shpc_isr(int irq, void *dev_id) | 835 | static irqreturn_t shpc_isr(int irq, void *dev_id) |
892 | { | 836 | { |
893 | struct controller *ctrl = (struct controller *)dev_id; | 837 | struct controller *ctrl = (struct controller *)dev_id; |
894 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
895 | u32 serr_int, slot_reg, intr_loc, intr_loc2; | 838 | u32 serr_int, slot_reg, intr_loc, intr_loc2; |
896 | int hp_slot; | 839 | int hp_slot; |
897 | 840 | ||
@@ -942,20 +885,16 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
942 | __FUNCTION__, hp_slot, slot_reg); | 885 | __FUNCTION__, hp_slot, slot_reg); |
943 | 886 | ||
944 | if (slot_reg & MRL_CHANGE_DETECTED) | 887 | if (slot_reg & MRL_CHANGE_DETECTED) |
945 | php_ctlr->switch_change_callback( | 888 | shpchp_handle_switch_change(hp_slot, ctrl); |
946 | hp_slot, php_ctlr->callback_instance_id); | ||
947 | 889 | ||
948 | if (slot_reg & BUTTON_PRESS_DETECTED) | 890 | if (slot_reg & BUTTON_PRESS_DETECTED) |
949 | php_ctlr->attention_button_callback( | 891 | shpchp_handle_attention_button(hp_slot, ctrl); |
950 | hp_slot, php_ctlr->callback_instance_id); | ||
951 | 892 | ||
952 | if (slot_reg & PRSNT_CHANGE_DETECTED) | 893 | if (slot_reg & PRSNT_CHANGE_DETECTED) |
953 | php_ctlr->presence_change_callback( | 894 | shpchp_handle_presence_change(hp_slot, ctrl); |
954 | hp_slot , php_ctlr->callback_instance_id); | ||
955 | 895 | ||
956 | if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)) | 896 | if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)) |
957 | php_ctlr->power_fault_callback( | 897 | shpchp_handle_power_fault(hp_slot, ctrl); |
958 | hp_slot, php_ctlr->callback_instance_id); | ||
959 | 898 | ||
960 | /* Clear all slot events */ | 899 | /* Clear all slot events */ |
961 | slot_reg &= ~SLOT_REG_RSVDZ_MASK; | 900 | slot_reg &= ~SLOT_REG_RSVDZ_MASK; |
@@ -1114,10 +1053,8 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
1114 | .release_ctlr = hpc_release_ctlr, | 1053 | .release_ctlr = hpc_release_ctlr, |
1115 | }; | 1054 | }; |
1116 | 1055 | ||
1117 | int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | 1056 | int shpc_init(struct controller *ctrl, struct pci_dev *pdev) |
1118 | { | 1057 | { |
1119 | struct php_ctlr_state_s *php_ctlr, *p; | ||
1120 | void *instance_id = ctrl; | ||
1121 | int rc = -1, num_slots = 0; | 1058 | int rc = -1, num_slots = 0; |
1122 | u8 hp_slot; | 1059 | u8 hp_slot; |
1123 | u32 shpc_base_offset; | 1060 | u32 shpc_base_offset; |
@@ -1128,16 +1065,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1128 | 1065 | ||
1129 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ | 1066 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ |
1130 | 1067 | ||
1131 | spin_lock_init(&list_lock); | ||
1132 | php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL); | ||
1133 | |||
1134 | if (!php_ctlr) { /* allocate controller state data */ | ||
1135 | err("%s: HPC controller memory allocation error!\n", __FUNCTION__); | ||
1136 | goto abort; | ||
1137 | } | ||
1138 | |||
1139 | php_ctlr->pci_dev = pdev; /* save pci_dev in context */ | ||
1140 | |||
1141 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == | 1068 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == |
1142 | PCI_DEVICE_ID_AMD_GOLAM_7450)) { | 1069 | PCI_DEVICE_ID_AMD_GOLAM_7450)) { |
1143 | /* amd shpc driver doesn't use Base Offset; assume 0 */ | 1070 | /* amd shpc driver doesn't use Base Offset; assume 0 */ |
@@ -1147,20 +1074,20 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1147 | ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC); | 1074 | ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC); |
1148 | if (!ctrl->cap_offset) { | 1075 | if (!ctrl->cap_offset) { |
1149 | err("%s : cap_offset == 0\n", __FUNCTION__); | 1076 | err("%s : cap_offset == 0\n", __FUNCTION__); |
1150 | goto abort_free_ctlr; | 1077 | goto abort; |
1151 | } | 1078 | } |
1152 | dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); | 1079 | dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); |
1153 | 1080 | ||
1154 | rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); | 1081 | rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); |
1155 | if (rc) { | 1082 | if (rc) { |
1156 | err("%s: cannot read base_offset\n", __FUNCTION__); | 1083 | err("%s: cannot read base_offset\n", __FUNCTION__); |
1157 | goto abort_free_ctlr; | 1084 | goto abort; |
1158 | } | 1085 | } |
1159 | 1086 | ||
1160 | rc = shpc_indirect_read(ctrl, 3, &tempdword); | 1087 | rc = shpc_indirect_read(ctrl, 3, &tempdword); |
1161 | if (rc) { | 1088 | if (rc) { |
1162 | err("%s: cannot read slot config\n", __FUNCTION__); | 1089 | err("%s: cannot read slot config\n", __FUNCTION__); |
1163 | goto abort_free_ctlr; | 1090 | goto abort; |
1164 | } | 1091 | } |
1165 | num_slots = tempdword & SLOT_NUM; | 1092 | num_slots = tempdword & SLOT_NUM; |
1166 | dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); | 1093 | dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); |
@@ -1170,7 +1097,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1170 | if (rc) { | 1097 | if (rc) { |
1171 | err("%s: cannot read creg (index = %d)\n", | 1098 | err("%s: cannot read creg (index = %d)\n", |
1172 | __FUNCTION__, i); | 1099 | __FUNCTION__, i); |
1173 | goto abort_free_ctlr; | 1100 | goto abort; |
1174 | } | 1101 | } |
1175 | dbg("%s: offset %d: value %x\n", __FUNCTION__,i, | 1102 | dbg("%s: offset %d: value %x\n", __FUNCTION__,i, |
1176 | tempdword); | 1103 | tempdword); |
@@ -1187,24 +1114,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1187 | rc = pci_enable_device(pdev); | 1114 | rc = pci_enable_device(pdev); |
1188 | if (rc) { | 1115 | if (rc) { |
1189 | err("%s: pci_enable_device failed\n", __FUNCTION__); | 1116 | err("%s: pci_enable_device failed\n", __FUNCTION__); |
1190 | goto abort_free_ctlr; | 1117 | goto abort; |
1191 | } | 1118 | } |
1192 | 1119 | ||
1193 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { | 1120 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { |
1194 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); | 1121 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); |
1195 | rc = -1; | 1122 | rc = -1; |
1196 | goto abort_free_ctlr; | 1123 | goto abort; |
1197 | } | 1124 | } |
1198 | 1125 | ||
1199 | php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); | 1126 | ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); |
1200 | if (!php_ctlr->creg) { | 1127 | if (!ctrl->creg) { |
1201 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, | 1128 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, |
1202 | ctrl->mmio_size, ctrl->mmio_base); | 1129 | ctrl->mmio_size, ctrl->mmio_base); |
1203 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | 1130 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); |
1204 | rc = -1; | 1131 | rc = -1; |
1205 | goto abort_free_ctlr; | 1132 | goto abort; |
1206 | } | 1133 | } |
1207 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); | 1134 | dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg); |
1208 | 1135 | ||
1209 | mutex_init(&ctrl->crit_sect); | 1136 | mutex_init(&ctrl->crit_sect); |
1210 | mutex_init(&ctrl->cmd_lock); | 1137 | mutex_init(&ctrl->cmd_lock); |
@@ -1212,23 +1139,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1212 | /* Setup wait queue */ | 1139 | /* Setup wait queue */ |
1213 | init_waitqueue_head(&ctrl->queue); | 1140 | init_waitqueue_head(&ctrl->queue); |
1214 | 1141 | ||
1215 | /* Find the IRQ */ | ||
1216 | php_ctlr->irq = pdev->irq; | ||
1217 | php_ctlr->attention_button_callback = shpchp_handle_attention_button, | ||
1218 | php_ctlr->switch_change_callback = shpchp_handle_switch_change; | ||
1219 | php_ctlr->presence_change_callback = shpchp_handle_presence_change; | ||
1220 | php_ctlr->power_fault_callback = shpchp_handle_power_fault; | ||
1221 | php_ctlr->callback_instance_id = instance_id; | ||
1222 | |||
1223 | ctrl->hpc_ctlr_handle = php_ctlr; | ||
1224 | ctrl->hpc_ops = &shpchp_hpc_ops; | 1142 | ctrl->hpc_ops = &shpchp_hpc_ops; |
1225 | 1143 | ||
1226 | /* Return PCI Controller Info */ | 1144 | /* Return PCI Controller Info */ |
1227 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); | 1145 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); |
1228 | php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; | 1146 | ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; |
1229 | php_ctlr->num_slots = slot_config & SLOT_NUM; | 1147 | ctrl->num_slots = slot_config & SLOT_NUM; |
1230 | dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); | 1148 | ctrl->first_slot = (slot_config & PSN) >> 16; |
1231 | dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); | 1149 | ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1; |
1232 | 1150 | ||
1233 | /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ | 1151 | /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ |
1234 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); | 1152 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
@@ -1243,7 +1161,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1243 | /* Mask the MRL sensor SERR Mask of individual slot in | 1161 | /* Mask the MRL sensor SERR Mask of individual slot in |
1244 | * Slot SERR-INT Mask & clear all the existing event if any | 1162 | * Slot SERR-INT Mask & clear all the existing event if any |
1245 | */ | 1163 | */ |
1246 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1164 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
1247 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); | 1165 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); |
1248 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, | 1166 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, |
1249 | hp_slot, slot_reg); | 1167 | hp_slot, slot_reg); |
@@ -1255,24 +1173,27 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1255 | shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); | 1173 | shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); |
1256 | } | 1174 | } |
1257 | 1175 | ||
1258 | if (shpchp_poll_mode) {/* Install interrupt polling code */ | 1176 | if (shpchp_poll_mode) { |
1259 | /* Install and start the interrupt polling timer */ | 1177 | /* Install interrupt polling timer. Start with 10 sec delay */ |
1260 | init_timer(&php_ctlr->int_poll_timer); | 1178 | init_timer(&ctrl->poll_timer); |
1261 | start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ | 1179 | start_int_poll_timer(ctrl, 10); |
1262 | } else { | 1180 | } else { |
1263 | /* Installs the interrupt handler */ | 1181 | /* Installs the interrupt handler */ |
1264 | rc = pci_enable_msi(pdev); | 1182 | rc = pci_enable_msi(pdev); |
1265 | if (rc) { | 1183 | if (rc) { |
1266 | info("Can't get msi for the hotplug controller\n"); | 1184 | info("Can't get msi for the hotplug controller\n"); |
1267 | info("Use INTx for the hotplug controller\n"); | 1185 | info("Use INTx for the hotplug controller\n"); |
1268 | } else | 1186 | } |
1269 | php_ctlr->irq = pdev->irq; | ||
1270 | 1187 | ||
1271 | rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl); | 1188 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, |
1272 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); | 1189 | MY_NAME, (void *)ctrl); |
1190 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", | ||
1191 | __FUNCTION__, ctrl->pci_dev->irq, | ||
1192 | atomic_read(&shpchp_num_controllers), rc); | ||
1273 | if (rc) { | 1193 | if (rc) { |
1274 | err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); | 1194 | err("Can't get irq %d for the hotplug controller\n", |
1275 | goto abort_free_ctlr; | 1195 | ctrl->pci_dev->irq); |
1196 | goto abort_iounmap; | ||
1276 | } | 1197 | } |
1277 | } | 1198 | } |
1278 | dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__, | 1199 | dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__, |
@@ -1280,24 +1201,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1280 | PCI_FUNC(pdev->devfn), pdev->irq); | 1201 | PCI_FUNC(pdev->devfn), pdev->irq); |
1281 | get_hp_hw_control_from_firmware(pdev); | 1202 | get_hp_hw_control_from_firmware(pdev); |
1282 | 1203 | ||
1283 | /* Add this HPC instance into the HPC list */ | ||
1284 | spin_lock(&list_lock); | ||
1285 | if (php_ctlr_list_head == 0) { | ||
1286 | php_ctlr_list_head = php_ctlr; | ||
1287 | p = php_ctlr_list_head; | ||
1288 | p->pnext = NULL; | ||
1289 | } else { | ||
1290 | p = php_ctlr_list_head; | ||
1291 | |||
1292 | while (p->pnext) | ||
1293 | p = p->pnext; | ||
1294 | |||
1295 | p->pnext = php_ctlr; | ||
1296 | } | ||
1297 | spin_unlock(&list_lock); | ||
1298 | |||
1299 | ctlr_seq_num++; | ||
1300 | |||
1301 | /* | 1204 | /* |
1302 | * If this is the first controller to be initialized, | 1205 | * If this is the first controller to be initialized, |
1303 | * initialize the shpchpd work queue | 1206 | * initialize the shpchpd work queue |
@@ -1306,14 +1209,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1306 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | 1209 | shpchp_wq = create_singlethread_workqueue("shpchpd"); |
1307 | if (!shpchp_wq) { | 1210 | if (!shpchp_wq) { |
1308 | rc = -ENOMEM; | 1211 | rc = -ENOMEM; |
1309 | goto abort_free_ctlr; | 1212 | goto abort_iounmap; |
1310 | } | 1213 | } |
1311 | } | 1214 | } |
1312 | 1215 | ||
1313 | /* | 1216 | /* |
1314 | * Unmask all event interrupts of all slots | 1217 | * Unmask all event interrupts of all slots |
1315 | */ | 1218 | */ |
1316 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1219 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
1317 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); | 1220 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); |
1318 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, | 1221 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, |
1319 | hp_slot, slot_reg); | 1222 | hp_slot, slot_reg); |
@@ -1336,10 +1239,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1336 | return 0; | 1239 | return 0; |
1337 | 1240 | ||
1338 | /* We end up here for the many possible ways to fail this API. */ | 1241 | /* We end up here for the many possible ways to fail this API. */ |
1339 | abort_free_ctlr: | 1242 | abort_iounmap: |
1340 | if (php_ctlr->creg) | 1243 | iounmap(ctrl->creg); |
1341 | iounmap(php_ctlr->creg); | ||
1342 | kfree(php_ctlr); | ||
1343 | abort: | 1244 | abort: |
1344 | DBG_LEAVE_ROUTINE | 1245 | DBG_LEAVE_ROUTINE |
1345 | return rc; | 1246 | return rc; |
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 0a8d1cce9fa0..279c940a0039 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -99,14 +99,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) | |||
99 | int pos; | 99 | int pos; |
100 | int irq; | 100 | int irq; |
101 | 101 | ||
102 | pos = pci_find_capability(dev, PCI_CAP_ID_HT); | 102 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ); |
103 | while (pos) { | ||
104 | u8 subtype; | ||
105 | pci_read_config_byte(dev, pos + 3, &subtype); | ||
106 | if (subtype == HT_CAPTYPE_IRQ) | ||
107 | break; | ||
108 | pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT); | ||
109 | } | ||
110 | if (!pos) | 103 | if (!pos) |
111 | return -EINVAL; | 104 | return -EINVAL; |
112 | 105 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e5ae3a0c13bb..b8d2385e29bc 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -162,14 +162,9 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, | |||
162 | const struct pci_device_id *pci_match_device(struct pci_driver *drv, | 162 | const struct pci_device_id *pci_match_device(struct pci_driver *drv, |
163 | struct pci_dev *dev) | 163 | struct pci_dev *dev) |
164 | { | 164 | { |
165 | const struct pci_device_id *id; | ||
166 | struct pci_dynid *dynid; | 165 | struct pci_dynid *dynid; |
167 | 166 | ||
168 | id = pci_match_id(drv->id_table, dev); | 167 | /* Look at the dynamic ids first, before the static ones */ |
169 | if (id) | ||
170 | return id; | ||
171 | |||
172 | /* static ids didn't match, lets look at the dynamic ones */ | ||
173 | spin_lock(&drv->dynids.lock); | 168 | spin_lock(&drv->dynids.lock); |
174 | list_for_each_entry(dynid, &drv->dynids.list, node) { | 169 | list_for_each_entry(dynid, &drv->dynids.list, node) { |
175 | if (pci_match_one_device(&dynid->id, dev)) { | 170 | if (pci_match_one_device(&dynid->id, dev)) { |
@@ -178,7 +173,8 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv, | |||
178 | } | 173 | } |
179 | } | 174 | } |
180 | spin_unlock(&drv->dynids.lock); | 175 | spin_unlock(&drv->dynids.lock); |
181 | return NULL; | 176 | |
177 | return pci_match_id(drv->id_table, dev); | ||
182 | } | 178 | } |
183 | 179 | ||
184 | static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | 180 | static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, |
@@ -357,6 +353,8 @@ static int pci_device_resume_early(struct device * dev) | |||
357 | struct pci_dev * pci_dev = to_pci_dev(dev); | 353 | struct pci_dev * pci_dev = to_pci_dev(dev); |
358 | struct pci_driver * drv = pci_dev->driver; | 354 | struct pci_driver * drv = pci_dev->driver; |
359 | 355 | ||
356 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
357 | |||
360 | if (drv && drv->resume_early) | 358 | if (drv && drv->resume_early) |
361 | error = drv->resume_early(pci_dev); | 359 | error = drv->resume_early(pci_dev); |
362 | return error; | 360 | return error; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5a14b73cf3a1..6bfb942428e4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -68,12 +68,14 @@ pci_max_busnr(void) | |||
68 | 68 | ||
69 | #endif /* 0 */ | 69 | #endif /* 0 */ |
70 | 70 | ||
71 | static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap) | 71 | #define PCI_FIND_CAP_TTL 48 |
72 | |||
73 | static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, | ||
74 | u8 pos, int cap, int *ttl) | ||
72 | { | 75 | { |
73 | u8 id; | 76 | u8 id; |
74 | int ttl = 48; | ||
75 | 77 | ||
76 | while (ttl--) { | 78 | while ((*ttl)--) { |
77 | pci_bus_read_config_byte(bus, devfn, pos, &pos); | 79 | pci_bus_read_config_byte(bus, devfn, pos, &pos); |
78 | if (pos < 0x40) | 80 | if (pos < 0x40) |
79 | break; | 81 | break; |
@@ -89,6 +91,14 @@ static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, | |||
89 | return 0; | 91 | return 0; |
90 | } | 92 | } |
91 | 93 | ||
94 | static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, | ||
95 | u8 pos, int cap) | ||
96 | { | ||
97 | int ttl = PCI_FIND_CAP_TTL; | ||
98 | |||
99 | return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl); | ||
100 | } | ||
101 | |||
92 | int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) | 102 | int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) |
93 | { | 103 | { |
94 | return __pci_find_next_cap(dev->bus, dev->devfn, | 104 | return __pci_find_next_cap(dev->bus, dev->devfn, |
@@ -96,10 +106,10 @@ int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) | |||
96 | } | 106 | } |
97 | EXPORT_SYMBOL_GPL(pci_find_next_capability); | 107 | EXPORT_SYMBOL_GPL(pci_find_next_capability); |
98 | 108 | ||
99 | static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap) | 109 | static int __pci_bus_find_cap_start(struct pci_bus *bus, |
110 | unsigned int devfn, u8 hdr_type) | ||
100 | { | 111 | { |
101 | u16 status; | 112 | u16 status; |
102 | u8 pos; | ||
103 | 113 | ||
104 | pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); | 114 | pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); |
105 | if (!(status & PCI_STATUS_CAP_LIST)) | 115 | if (!(status & PCI_STATUS_CAP_LIST)) |
@@ -108,15 +118,14 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty | |||
108 | switch (hdr_type) { | 118 | switch (hdr_type) { |
109 | case PCI_HEADER_TYPE_NORMAL: | 119 | case PCI_HEADER_TYPE_NORMAL: |
110 | case PCI_HEADER_TYPE_BRIDGE: | 120 | case PCI_HEADER_TYPE_BRIDGE: |
111 | pos = PCI_CAPABILITY_LIST; | 121 | return PCI_CAPABILITY_LIST; |
112 | break; | ||
113 | case PCI_HEADER_TYPE_CARDBUS: | 122 | case PCI_HEADER_TYPE_CARDBUS: |
114 | pos = PCI_CB_CAPABILITY_LIST; | 123 | return PCI_CB_CAPABILITY_LIST; |
115 | break; | ||
116 | default: | 124 | default: |
117 | return 0; | 125 | return 0; |
118 | } | 126 | } |
119 | return __pci_find_next_cap(bus, devfn, pos, cap); | 127 | |
128 | return 0; | ||
120 | } | 129 | } |
121 | 130 | ||
122 | /** | 131 | /** |
@@ -140,7 +149,13 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty | |||
140 | */ | 149 | */ |
141 | int pci_find_capability(struct pci_dev *dev, int cap) | 150 | int pci_find_capability(struct pci_dev *dev, int cap) |
142 | { | 151 | { |
143 | return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap); | 152 | int pos; |
153 | |||
154 | pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type); | ||
155 | if (pos) | ||
156 | pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap); | ||
157 | |||
158 | return pos; | ||
144 | } | 159 | } |
145 | 160 | ||
146 | /** | 161 | /** |
@@ -158,11 +173,16 @@ int pci_find_capability(struct pci_dev *dev, int cap) | |||
158 | */ | 173 | */ |
159 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) | 174 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) |
160 | { | 175 | { |
176 | int pos; | ||
161 | u8 hdr_type; | 177 | u8 hdr_type; |
162 | 178 | ||
163 | pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type); | 179 | pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type); |
164 | 180 | ||
165 | return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap); | 181 | pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f); |
182 | if (pos) | ||
183 | pos = __pci_find_next_cap(bus, devfn, pos, cap); | ||
184 | |||
185 | return pos; | ||
166 | } | 186 | } |
167 | 187 | ||
168 | /** | 188 | /** |
@@ -214,6 +234,74 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) | |||
214 | } | 234 | } |
215 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 235 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); |
216 | 236 | ||
237 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | ||
238 | { | ||
239 | int rc, ttl = PCI_FIND_CAP_TTL; | ||
240 | u8 cap, mask; | ||
241 | |||
242 | if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST) | ||
243 | mask = HT_3BIT_CAP_MASK; | ||
244 | else | ||
245 | mask = HT_5BIT_CAP_MASK; | ||
246 | |||
247 | pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, | ||
248 | PCI_CAP_ID_HT, &ttl); | ||
249 | while (pos) { | ||
250 | rc = pci_read_config_byte(dev, pos + 3, &cap); | ||
251 | if (rc != PCIBIOS_SUCCESSFUL) | ||
252 | return 0; | ||
253 | |||
254 | if ((cap & mask) == ht_cap) | ||
255 | return pos; | ||
256 | |||
257 | pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, | ||
258 | PCI_CAP_ID_HT, &ttl); | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | /** | ||
264 | * pci_find_next_ht_capability - query a device's Hypertransport capabilities | ||
265 | * @dev: PCI device to query | ||
266 | * @pos: Position from which to continue searching | ||
267 | * @ht_cap: Hypertransport capability code | ||
268 | * | ||
269 | * To be used in conjunction with pci_find_ht_capability() to search for | ||
270 | * all capabilities matching @ht_cap. @pos should always be a value returned | ||
271 | * from pci_find_ht_capability(). | ||
272 | * | ||
273 | * NB. To be 100% safe against broken PCI devices, the caller should take | ||
274 | * steps to avoid an infinite loop. | ||
275 | */ | ||
276 | int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap) | ||
277 | { | ||
278 | return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap); | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(pci_find_next_ht_capability); | ||
281 | |||
282 | /** | ||
283 | * pci_find_ht_capability - query a device's Hypertransport capabilities | ||
284 | * @dev: PCI device to query | ||
285 | * @ht_cap: Hypertransport capability code | ||
286 | * | ||
287 | * Tell if a device supports a given Hypertransport capability. | ||
288 | * Returns an address within the device's PCI configuration space | ||
289 | * or 0 in case the device does not support the request capability. | ||
290 | * The address points to the PCI capability, of type PCI_CAP_ID_HT, | ||
291 | * which has a Hypertransport capability matching @ht_cap. | ||
292 | */ | ||
293 | int pci_find_ht_capability(struct pci_dev *dev, int ht_cap) | ||
294 | { | ||
295 | int pos; | ||
296 | |||
297 | pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type); | ||
298 | if (pos) | ||
299 | pos = __pci_find_next_ht_cap(dev, pos, ht_cap); | ||
300 | |||
301 | return pos; | ||
302 | } | ||
303 | EXPORT_SYMBOL_GPL(pci_find_ht_capability); | ||
304 | |||
217 | /** | 305 | /** |
218 | * pci_find_parent_resource - return resource region of parent bus of given region | 306 | * pci_find_parent_resource - return resource region of parent bus of given region |
219 | * @dev: PCI device structure contains resources to be searched | 307 | * @dev: PCI device structure contains resources to be searched |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index b4da7954611e..f17e7ed2b2a5 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -90,7 +90,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
90 | return -ENODEV; | 90 | return -ENODEV; |
91 | 91 | ||
92 | pci_set_master(dev); | 92 | pci_set_master(dev); |
93 | if (!dev->irq) { | 93 | if (!dev->irq && dev->pin) { |
94 | printk(KERN_WARNING | 94 | printk(KERN_WARNING |
95 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", | 95 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", |
96 | __FUNCTION__, dev->device, dev->vendor); | 96 | __FUNCTION__, dev->device, dev->vendor); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6a3c1e728900..1ae9c3f50ffa 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -649,6 +649,9 @@ static void pci_read_irq(struct pci_dev *dev) | |||
649 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge | 649 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge |
650 | * or CardBus). | 650 | * or CardBus). |
651 | */ | 651 | */ |
652 | |||
653 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | ||
654 | |||
652 | static int pci_setup_device(struct pci_dev * dev) | 655 | static int pci_setup_device(struct pci_dev * dev) |
653 | { | 656 | { |
654 | u32 class; | 657 | u32 class; |
@@ -692,18 +695,18 @@ static int pci_setup_device(struct pci_dev * dev) | |||
692 | if ((progif & 1) == 0) { | 695 | if ((progif & 1) == 0) { |
693 | dev->resource[0].start = 0x1F0; | 696 | dev->resource[0].start = 0x1F0; |
694 | dev->resource[0].end = 0x1F7; | 697 | dev->resource[0].end = 0x1F7; |
695 | dev->resource[0].flags = IORESOURCE_IO; | 698 | dev->resource[0].flags = LEGACY_IO_RESOURCE; |
696 | dev->resource[1].start = 0x3F6; | 699 | dev->resource[1].start = 0x3F6; |
697 | dev->resource[1].end = 0x3F6; | 700 | dev->resource[1].end = 0x3F6; |
698 | dev->resource[1].flags = IORESOURCE_IO; | 701 | dev->resource[1].flags = LEGACY_IO_RESOURCE; |
699 | } | 702 | } |
700 | if ((progif & 4) == 0) { | 703 | if ((progif & 4) == 0) { |
701 | dev->resource[2].start = 0x170; | 704 | dev->resource[2].start = 0x170; |
702 | dev->resource[2].end = 0x177; | 705 | dev->resource[2].end = 0x177; |
703 | dev->resource[2].flags = IORESOURCE_IO; | 706 | dev->resource[2].flags = LEGACY_IO_RESOURCE; |
704 | dev->resource[3].start = 0x376; | 707 | dev->resource[3].start = 0x376; |
705 | dev->resource[3].end = 0x376; | 708 | dev->resource[3].end = 0x376; |
706 | dev->resource[3].flags = IORESOURCE_IO; | 709 | dev->resource[3].flags = LEGACY_IO_RESOURCE; |
707 | } | 710 | } |
708 | } | 711 | } |
709 | break; | 712 | break; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 9ca9b9bf6160..8f0322d6f3bf 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -36,7 +36,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRID | |||
36 | 36 | ||
37 | /* Deal with broken BIOS'es that neglect to enable passive release, | 37 | /* Deal with broken BIOS'es that neglect to enable passive release, |
38 | which can cause problems in combination with the 82441FX/PPro MTRRs */ | 38 | which can cause problems in combination with the 82441FX/PPro MTRRs */ |
39 | static void __devinit quirk_passive_release(struct pci_dev *dev) | 39 | static void quirk_passive_release(struct pci_dev *dev) |
40 | { | 40 | { |
41 | struct pci_dev *d = NULL; | 41 | struct pci_dev *d = NULL; |
42 | unsigned char dlc; | 42 | unsigned char dlc; |
@@ -53,6 +53,7 @@ static void __devinit quirk_passive_release(struct pci_dev *dev) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); | 55 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); |
56 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); | ||
56 | 57 | ||
57 | /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround | 58 | /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround |
58 | but VIA don't answer queries. If you happen to have good contacts at VIA | 59 | but VIA don't answer queries. If you happen to have good contacts at VIA |
@@ -134,7 +135,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quir | |||
134 | * Updated based on further information from the site and also on | 135 | * Updated based on further information from the site and also on |
135 | * information provided by VIA | 136 | * information provided by VIA |
136 | */ | 137 | */ |
137 | static void __devinit quirk_vialatency(struct pci_dev *dev) | 138 | static void quirk_vialatency(struct pci_dev *dev) |
138 | { | 139 | { |
139 | struct pci_dev *p; | 140 | struct pci_dev *p; |
140 | u8 rev; | 141 | u8 rev; |
@@ -185,6 +186,10 @@ exit: | |||
185 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); | 186 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); |
186 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); | 187 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); |
187 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); | 188 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); |
189 | /* Must restore this on a resume from RAM */ | ||
190 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); | ||
191 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); | ||
192 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); | ||
188 | 193 | ||
189 | /* | 194 | /* |
190 | * VIA Apollo VP3 needs ETBF on BT848/878 | 195 | * VIA Apollo VP3 needs ETBF on BT848/878 |
@@ -532,7 +537,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235 | |||
532 | * TODO: When we have device-specific interrupt routers, | 537 | * TODO: When we have device-specific interrupt routers, |
533 | * this code will go away from quirks. | 538 | * this code will go away from quirks. |
534 | */ | 539 | */ |
535 | static void __devinit quirk_via_ioapic(struct pci_dev *dev) | 540 | static void quirk_via_ioapic(struct pci_dev *dev) |
536 | { | 541 | { |
537 | u8 tmp; | 542 | u8 tmp; |
538 | 543 | ||
@@ -548,6 +553,7 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev) | |||
548 | pci_write_config_byte (dev, 0x58, tmp); | 553 | pci_write_config_byte (dev, 0x58, tmp); |
549 | } | 554 | } |
550 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); | 555 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); |
556 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); | ||
551 | 557 | ||
552 | /* | 558 | /* |
553 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. | 559 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. |
@@ -555,7 +561,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_i | |||
555 | * Set this bit to get rid of cycle wastage. | 561 | * Set this bit to get rid of cycle wastage. |
556 | * Otherwise uncritical. | 562 | * Otherwise uncritical. |
557 | */ | 563 | */ |
558 | static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) | 564 | static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) |
559 | { | 565 | { |
560 | u8 misc_control2; | 566 | u8 misc_control2; |
561 | #define BYPASS_APIC_DEASSERT 8 | 567 | #define BYPASS_APIC_DEASSERT 8 |
@@ -567,6 +573,7 @@ static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) | |||
567 | } | 573 | } |
568 | } | 574 | } |
569 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); | 575 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); |
576 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); | ||
570 | 577 | ||
571 | /* | 578 | /* |
572 | * The AMD io apic can hang the box when an apic irq is masked. | 579 | * The AMD io apic can hang the box when an apic irq is masked. |
@@ -600,7 +607,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw ); | |||
600 | #define AMD8131_revB0 0x11 | 607 | #define AMD8131_revB0 0x11 |
601 | #define AMD8131_MISC 0x40 | 608 | #define AMD8131_MISC 0x40 |
602 | #define AMD8131_NIOAMODE_BIT 0 | 609 | #define AMD8131_NIOAMODE_BIT 0 |
603 | static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) | 610 | static void quirk_amd_8131_ioapic(struct pci_dev *dev) |
604 | { | 611 | { |
605 | unsigned char revid, tmp; | 612 | unsigned char revid, tmp; |
606 | 613 | ||
@@ -616,6 +623,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) | |||
616 | } | 623 | } |
617 | } | 624 | } |
618 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | 625 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); |
626 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | ||
619 | #endif /* CONFIG_X86_IO_APIC */ | 627 | #endif /* CONFIG_X86_IO_APIC */ |
620 | 628 | ||
621 | 629 | ||
@@ -641,65 +649,84 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) | |||
641 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); | 649 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); |
642 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); | 650 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); |
643 | 651 | ||
644 | /* | ||
645 | * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip | ||
646 | * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: | ||
647 | * when written, it makes an internal connection to the PIC. | ||
648 | * For these devices, this register is defined to be 4 bits wide. | ||
649 | * Normally this is fine. However for IO-APIC motherboards, or | ||
650 | * non-x86 architectures (yes Via exists on PPC among other places), | ||
651 | * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get | ||
652 | * interrupts delivered properly. | ||
653 | * | ||
654 | * Some of the on-chip devices are actually '586 devices' so they are | ||
655 | * listed here. | ||
656 | */ | ||
657 | |||
658 | static int via_irq_fixup_needed = -1; | ||
659 | 652 | ||
660 | /* | 653 | /* |
661 | * As some VIA hardware is available in PCI-card form, we need to restrict | 654 | * VIA bridges which have VLink |
662 | * this quirk to VIA PCI hardware built onto VIA-based motherboards only. | ||
663 | * We try to locate a VIA southbridge before deciding whether the quirk | ||
664 | * should be applied. | ||
665 | */ | 655 | */ |
666 | static const struct pci_device_id via_irq_fixup_tbl[] = { | 656 | |
667 | { | 657 | static const struct pci_device_id via_vlink_fixup_tbl[] = { |
668 | .vendor = PCI_VENDOR_ID_VIA, | 658 | /* Internal devices need IRQ line routing, pre VLink */ |
669 | .device = PCI_ANY_ID, | 659 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, |
670 | .subvendor = PCI_ANY_ID, | 660 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, |
671 | .subdevice = PCI_ANY_ID, | 661 | /* Devices with VLink */ |
672 | .class = PCI_CLASS_BRIDGE_ISA << 8, | 662 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, |
673 | .class_mask = 0xffff00, | 663 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, |
674 | }, | 664 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, |
665 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, | ||
666 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, | ||
667 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, | ||
675 | { 0, }, | 668 | { 0, }, |
676 | }; | 669 | }; |
677 | 670 | ||
678 | static void quirk_via_irq(struct pci_dev *dev) | 671 | /** |
672 | * quirk_via_vlink - VIA VLink IRQ number update | ||
673 | * @dev: PCI device | ||
674 | * | ||
675 | * If the device we are dealing with is on a PIC IRQ we need to | ||
676 | * ensure that the IRQ line register which usually is not relevant | ||
677 | * for PCI cards, is actually written so that interrupts get sent | ||
678 | * to the right place | ||
679 | */ | ||
680 | |||
681 | static void quirk_via_vlink(struct pci_dev *dev) | ||
679 | { | 682 | { |
683 | const struct pci_device_id *via_vlink_fixup; | ||
684 | static int dev_lo = -1, dev_hi = 18; | ||
680 | u8 irq, new_irq; | 685 | u8 irq, new_irq; |
681 | 686 | ||
682 | if (via_irq_fixup_needed == -1) | 687 | /* Check if we have VLink and cache the result */ |
683 | via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl); | ||
684 | 688 | ||
685 | if (!via_irq_fixup_needed) | 689 | /* Checked already - no */ |
690 | if (dev_lo == -2) | ||
686 | return; | 691 | return; |
687 | 692 | ||
693 | /* Not checked - see what bridge we have and find the device | ||
694 | ranges */ | ||
695 | |||
696 | if (dev_lo == -1) { | ||
697 | via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); | ||
698 | if (via_vlink_fixup == NULL) { | ||
699 | dev_lo = -2; | ||
700 | return; | ||
701 | } | ||
702 | dev_lo = via_vlink_fixup->driver_data; | ||
703 | /* 82C686 is special - 0/0 */ | ||
704 | if (dev_lo == 0) | ||
705 | dev_hi = 0; | ||
706 | } | ||
688 | new_irq = dev->irq; | 707 | new_irq = dev->irq; |
689 | 708 | ||
690 | /* Don't quirk interrupts outside the legacy IRQ range */ | 709 | /* Don't quirk interrupts outside the legacy IRQ range */ |
691 | if (!new_irq || new_irq > 15) | 710 | if (!new_irq || new_irq > 15) |
692 | return; | 711 | return; |
693 | 712 | ||
713 | /* Internal device ? */ | ||
714 | if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || | ||
715 | PCI_SLOT(dev->devfn) < dev_lo) | ||
716 | return; | ||
717 | |||
718 | /* This is an internal VLink device on a PIC interrupt. The BIOS | ||
719 | ought to have set this but may not have, so we redo it */ | ||
720 | |||
694 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 721 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
695 | if (new_irq != irq) { | 722 | if (new_irq != irq) { |
696 | printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", | 723 | printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n", |
697 | pci_name(dev), irq, new_irq); | 724 | pci_name(dev), irq, new_irq); |
698 | udelay(15); /* unknown if delay really needed */ | 725 | udelay(15); /* unknown if delay really needed */ |
699 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 726 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
700 | } | 727 | } |
701 | } | 728 | } |
702 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); | 729 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink); |
703 | 730 | ||
704 | /* | 731 | /* |
705 | * VIA VT82C598 has its device ID settable and many BIOSes | 732 | * VIA VT82C598 has its device ID settable and many BIOSes |
@@ -720,13 +747,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt | |||
720 | * do this even if the Linux CardBus driver is not loaded, because | 747 | * do this even if the Linux CardBus driver is not loaded, because |
721 | * the Linux i82365 driver does not (and should not) handle CardBus. | 748 | * the Linux i82365 driver does not (and should not) handle CardBus. |
722 | */ | 749 | */ |
723 | static void __devinit quirk_cardbus_legacy(struct pci_dev *dev) | 750 | static void quirk_cardbus_legacy(struct pci_dev *dev) |
724 | { | 751 | { |
725 | if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) | 752 | if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) |
726 | return; | 753 | return; |
727 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); | 754 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); |
728 | } | 755 | } |
729 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 756 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); |
757 | DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | ||
730 | 758 | ||
731 | /* | 759 | /* |
732 | * Following the PCI ordering rules is optional on the AMD762. I'm not | 760 | * Following the PCI ordering rules is optional on the AMD762. I'm not |
@@ -735,7 +763,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | |||
735 | * To be fair to AMD, it follows the spec by default, its BIOS people | 763 | * To be fair to AMD, it follows the spec by default, its BIOS people |
736 | * who turn it off! | 764 | * who turn it off! |
737 | */ | 765 | */ |
738 | static void __devinit quirk_amd_ordering(struct pci_dev *dev) | 766 | static void quirk_amd_ordering(struct pci_dev *dev) |
739 | { | 767 | { |
740 | u32 pcic; | 768 | u32 pcic; |
741 | pci_read_config_dword(dev, 0x4C, &pcic); | 769 | pci_read_config_dword(dev, 0x4C, &pcic); |
@@ -749,6 +777,7 @@ static void __devinit quirk_amd_ordering(struct pci_dev *dev) | |||
749 | } | 777 | } |
750 | } | 778 | } |
751 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); | 779 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); |
780 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); | ||
752 | 781 | ||
753 | /* | 782 | /* |
754 | * DreamWorks provided workaround for Dunord I-3000 problem | 783 | * DreamWorks provided workaround for Dunord I-3000 problem |
@@ -784,7 +813,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge | |||
784 | * datasheets found at http://www.national.com/ds/GX for info on what | 813 | * datasheets found at http://www.national.com/ds/GX for info on what |
785 | * these bits do. <christer@weinigel.se> | 814 | * these bits do. <christer@weinigel.se> |
786 | */ | 815 | */ |
787 | static void __init quirk_mediagx_master(struct pci_dev *dev) | 816 | static void quirk_mediagx_master(struct pci_dev *dev) |
788 | { | 817 | { |
789 | u8 reg; | 818 | u8 reg; |
790 | pci_read_config_byte(dev, 0x41, ®); | 819 | pci_read_config_byte(dev, 0x41, ®); |
@@ -795,13 +824,14 @@ static void __init quirk_mediagx_master(struct pci_dev *dev) | |||
795 | } | 824 | } |
796 | } | 825 | } |
797 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); | 826 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); |
827 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); | ||
798 | 828 | ||
799 | /* | 829 | /* |
800 | * Ensure C0 rev restreaming is off. This is normally done by | 830 | * Ensure C0 rev restreaming is off. This is normally done by |
801 | * the BIOS but in the odd case it is not the results are corruption | 831 | * the BIOS but in the odd case it is not the results are corruption |
802 | * hence the presence of a Linux check | 832 | * hence the presence of a Linux check |
803 | */ | 833 | */ |
804 | static void __init quirk_disable_pxb(struct pci_dev *pdev) | 834 | static void quirk_disable_pxb(struct pci_dev *pdev) |
805 | { | 835 | { |
806 | u16 config; | 836 | u16 config; |
807 | u8 rev; | 837 | u8 rev; |
@@ -817,7 +847,25 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev) | |||
817 | } | 847 | } |
818 | } | 848 | } |
819 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); | 849 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); |
850 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); | ||
851 | |||
852 | |||
853 | static void __devinit quirk_sb600_sata(struct pci_dev *pdev) | ||
854 | { | ||
855 | /* set sb600 sata to ahci mode */ | ||
856 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
857 | u8 tmp; | ||
820 | 858 | ||
859 | pci_read_config_byte(pdev, 0x40, &tmp); | ||
860 | pci_write_config_byte(pdev, 0x40, tmp|1); | ||
861 | pci_write_config_byte(pdev, 0x9, 1); | ||
862 | pci_write_config_byte(pdev, 0xa, 6); | ||
863 | pci_write_config_byte(pdev, 0x40, tmp); | ||
864 | |||
865 | pdev->class = 0x010601; | ||
866 | } | ||
867 | } | ||
868 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); | ||
821 | 869 | ||
822 | /* | 870 | /* |
823 | * Serverworks CSB5 IDE does not fully support native mode | 871 | * Serverworks CSB5 IDE does not fully support native mode |
@@ -874,7 +922,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e | |||
874 | * runs everywhere at present we suppress the printk output in most | 922 | * runs everywhere at present we suppress the printk output in most |
875 | * irrelevant cases. | 923 | * irrelevant cases. |
876 | */ | 924 | */ |
877 | static void __init k8t_sound_hostbridge(struct pci_dev *dev) | 925 | static void k8t_sound_hostbridge(struct pci_dev *dev) |
878 | { | 926 | { |
879 | unsigned char val; | 927 | unsigned char val; |
880 | 928 | ||
@@ -893,8 +941,8 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev) | |||
893 | } | 941 | } |
894 | } | 942 | } |
895 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); | 943 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); |
944 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); | ||
896 | 945 | ||
897 | #ifndef CONFIG_ACPI_SLEEP | ||
898 | /* | 946 | /* |
899 | * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge | 947 | * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge |
900 | * is not activated. The myth is that Asus said that they do not want the | 948 | * is not activated. The myth is that Asus said that they do not want the |
@@ -906,10 +954,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho | |||
906 | * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it | 954 | * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it |
907 | * becomes necessary to do this tweak in two steps -- I've chosen the Host | 955 | * becomes necessary to do this tweak in two steps -- I've chosen the Host |
908 | * bridge as trigger. | 956 | * bridge as trigger. |
909 | * | ||
910 | * Actually, leaving it unhidden and not redoing the quirk over suspend2ram | ||
911 | * will cause thermal management to break down, and causing machine to | ||
912 | * overheat. | ||
913 | */ | 957 | */ |
914 | static int __initdata asus_hides_smbus; | 958 | static int __initdata asus_hides_smbus; |
915 | 959 | ||
@@ -1019,7 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, as | |||
1019 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); | 1063 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); |
1020 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); | 1064 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); |
1021 | 1065 | ||
1022 | static void __init asus_hides_smbus_lpc(struct pci_dev *dev) | 1066 | static void asus_hides_smbus_lpc(struct pci_dev *dev) |
1023 | { | 1067 | { |
1024 | u16 val; | 1068 | u16 val; |
1025 | 1069 | ||
@@ -1042,8 +1086,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu | |||
1042 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1086 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); |
1043 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1087 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); |
1044 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1088 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); |
1089 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); | ||
1090 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); | ||
1091 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); | ||
1092 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | ||
1093 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | ||
1094 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | ||
1045 | 1095 | ||
1046 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | 1096 | static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) |
1047 | { | 1097 | { |
1048 | u32 val, rcba; | 1098 | u32 val, rcba; |
1049 | void __iomem *base; | 1099 | void __iomem *base; |
@@ -1059,13 +1109,12 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | |||
1059 | printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); | 1109 | printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); |
1060 | } | 1110 | } |
1061 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | 1111 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); |
1062 | 1112 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | |
1063 | #endif | ||
1064 | 1113 | ||
1065 | /* | 1114 | /* |
1066 | * SiS 96x south bridge: BIOS typically hides SMBus device... | 1115 | * SiS 96x south bridge: BIOS typically hides SMBus device... |
1067 | */ | 1116 | */ |
1068 | static void __init quirk_sis_96x_smbus(struct pci_dev *dev) | 1117 | static void quirk_sis_96x_smbus(struct pci_dev *dev) |
1069 | { | 1118 | { |
1070 | u8 val = 0; | 1119 | u8 val = 0; |
1071 | printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); | 1120 | printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); |
@@ -1086,7 +1135,7 @@ static int __devinitdata sis_96x_compatible = 0; | |||
1086 | 1135 | ||
1087 | #define SIS_DETECT_REGISTER 0x40 | 1136 | #define SIS_DETECT_REGISTER 0x40 |
1088 | 1137 | ||
1089 | static void __init quirk_sis_503(struct pci_dev *dev) | 1138 | static void quirk_sis_503(struct pci_dev *dev) |
1090 | { | 1139 | { |
1091 | u8 reg; | 1140 | u8 reg; |
1092 | u16 devid; | 1141 | u16 devid; |
@@ -1122,13 +1171,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_ | |||
1122 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); | 1171 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); |
1123 | 1172 | ||
1124 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); | 1173 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); |
1174 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); | ||
1125 | /* | 1175 | /* |
1126 | * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller | 1176 | * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller |
1127 | * and MC97 modem controller are disabled when a second PCI soundcard is | 1177 | * and MC97 modem controller are disabled when a second PCI soundcard is |
1128 | * present. This patch, tweaking the VT8237 ISA bridge, enables them. | 1178 | * present. This patch, tweaking the VT8237 ISA bridge, enables them. |
1129 | * -- bjd | 1179 | * -- bjd |
1130 | */ | 1180 | */ |
1131 | static void __init asus_hides_ac97_lpc(struct pci_dev *dev) | 1181 | static void asus_hides_ac97_lpc(struct pci_dev *dev) |
1132 | { | 1182 | { |
1133 | u8 val; | 1183 | u8 val; |
1134 | int asus_hides_ac97 = 0; | 1184 | int asus_hides_ac97 = 0; |
@@ -1159,6 +1209,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_ | |||
1159 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); | 1209 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); |
1160 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); | 1210 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); |
1161 | 1211 | ||
1212 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); | ||
1213 | |||
1214 | |||
1215 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); | ||
1216 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); | ||
1217 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); | ||
1218 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); | ||
1219 | |||
1162 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) | 1220 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) |
1163 | 1221 | ||
1164 | /* | 1222 | /* |
@@ -1167,7 +1225,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_ | |||
1167 | * the PCI scanning. | 1225 | * the PCI scanning. |
1168 | */ | 1226 | */ |
1169 | 1227 | ||
1170 | static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev) | 1228 | static void quirk_jmicron_dualfn(struct pci_dev *pdev) |
1171 | { | 1229 | { |
1172 | u32 conf; | 1230 | u32 conf; |
1173 | u8 hdr; | 1231 | u8 hdr; |
@@ -1205,6 +1263,7 @@ static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev) | |||
1205 | } | 1263 | } |
1206 | 1264 | ||
1207 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); | 1265 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); |
1266 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); | ||
1208 | 1267 | ||
1209 | #endif | 1268 | #endif |
1210 | 1269 | ||
@@ -1532,6 +1591,8 @@ extern struct pci_fixup __start_pci_fixups_final[]; | |||
1532 | extern struct pci_fixup __end_pci_fixups_final[]; | 1591 | extern struct pci_fixup __end_pci_fixups_final[]; |
1533 | extern struct pci_fixup __start_pci_fixups_enable[]; | 1592 | extern struct pci_fixup __start_pci_fixups_enable[]; |
1534 | extern struct pci_fixup __end_pci_fixups_enable[]; | 1593 | extern struct pci_fixup __end_pci_fixups_enable[]; |
1594 | extern struct pci_fixup __start_pci_fixups_resume[]; | ||
1595 | extern struct pci_fixup __end_pci_fixups_resume[]; | ||
1535 | 1596 | ||
1536 | 1597 | ||
1537 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | 1598 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) |
@@ -1559,6 +1620,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
1559 | end = __end_pci_fixups_enable; | 1620 | end = __end_pci_fixups_enable; |
1560 | break; | 1621 | break; |
1561 | 1622 | ||
1623 | case pci_fixup_resume: | ||
1624 | start = __start_pci_fixups_resume; | ||
1625 | end = __end_pci_fixups_resume; | ||
1626 | break; | ||
1627 | |||
1562 | default: | 1628 | default: |
1563 | /* stupid compiler warning, you would think with an enum... */ | 1629 | /* stupid compiler warning, you would think with an enum... */ |
1564 | return; | 1630 | return; |
@@ -1596,7 +1662,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); | |||
1596 | * Force it to be linked by setting the corresponding control bit in the | 1662 | * Force it to be linked by setting the corresponding control bit in the |
1597 | * config space. | 1663 | * config space. |
1598 | */ | 1664 | */ |
1599 | static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) | 1665 | static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) |
1600 | { | 1666 | { |
1601 | uint8_t b; | 1667 | uint8_t b; |
1602 | if (pci_read_config_byte(dev, 0xf41, &b) == 0) { | 1668 | if (pci_read_config_byte(dev, 0xf41, &b) == 0) { |
@@ -1610,6 +1676,8 @@ static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) | |||
1610 | } | 1676 | } |
1611 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1677 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1612 | quirk_nvidia_ck804_pcie_aer_ext_cap); | 1678 | quirk_nvidia_ck804_pcie_aer_ext_cap); |
1679 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | ||
1680 | quirk_nvidia_ck804_pcie_aer_ext_cap); | ||
1613 | 1681 | ||
1614 | #ifdef CONFIG_PCI_MSI | 1682 | #ifdef CONFIG_PCI_MSI |
1615 | /* To disable MSI globally */ | 1683 | /* To disable MSI globally */ |
@@ -1644,19 +1712,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_ | |||
1644 | * return 1 if a HT MSI capability is found and enabled */ | 1712 | * return 1 if a HT MSI capability is found and enabled */ |
1645 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | 1713 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) |
1646 | { | 1714 | { |
1647 | u8 pos; | 1715 | int pos, ttl = 48; |
1648 | int ttl; | 1716 | |
1649 | for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48; | 1717 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); |
1650 | pos && ttl; | 1718 | while (pos && ttl--) { |
1651 | pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) { | 1719 | u8 flags; |
1652 | u32 cap_hdr; | 1720 | |
1653 | /* MSI mapping section according to Hypertransport spec */ | 1721 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, |
1654 | if (pci_read_config_dword(dev, pos, &cap_hdr) == 0 | 1722 | &flags) == 0) |
1655 | && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) { | 1723 | { |
1656 | printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n", | 1724 | printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n", |
1657 | pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled"); | 1725 | flags & HT_MSI_FLAGS_ENABLE ? |
1658 | return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */ | 1726 | "enabled" : "disabled", pci_name(dev)); |
1727 | return (flags & HT_MSI_FLAGS_ENABLE) != 0; | ||
1659 | } | 1728 | } |
1729 | |||
1730 | pos = pci_find_next_ht_capability(dev, pos, | ||
1731 | HT_CAPTYPE_MSI_MAPPING); | ||
1660 | } | 1732 | } |
1661 | return 0; | 1733 | return 0; |
1662 | } | 1734 | } |
@@ -1688,8 +1760,9 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1688 | * a single one having MSI is enough to be sure that MSI are supported. | 1760 | * a single one having MSI is enough to be sure that MSI are supported. |
1689 | */ | 1761 | */ |
1690 | pdev = pci_get_slot(dev->bus, 0); | 1762 | pdev = pci_get_slot(dev->bus, 0); |
1691 | if (dev->subordinate && !msi_ht_cap_enabled(dev) | 1763 | if (!pdev) |
1692 | && !msi_ht_cap_enabled(pdev)) { | 1764 | return; |
1765 | if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { | ||
1693 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1766 | printk(KERN_WARNING "PCI: MSI quirk detected. " |
1694 | "MSI disabled on chipset %s.\n", | 1767 | "MSI disabled on chipset %s.\n", |
1695 | pci_name(dev)); | 1768 | pci_name(dev)); |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 2f13eba5d5ae..45f2b20ef513 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -413,6 +413,24 @@ exit: | |||
413 | return dev; | 413 | return dev; |
414 | } | 414 | } |
415 | 415 | ||
416 | const struct pci_device_id *pci_find_present(const struct pci_device_id *ids) | ||
417 | { | ||
418 | struct pci_dev *dev; | ||
419 | const struct pci_device_id *found = NULL; | ||
420 | |||
421 | WARN_ON(in_interrupt()); | ||
422 | down_read(&pci_bus_sem); | ||
423 | while (ids->vendor || ids->subvendor || ids->class_mask) { | ||
424 | list_for_each_entry(dev, &pci_devices, global_list) { | ||
425 | if ((found = pci_match_one_device(ids, dev)) != NULL) | ||
426 | break; | ||
427 | } | ||
428 | ids++; | ||
429 | } | ||
430 | up_read(&pci_bus_sem); | ||
431 | return found; | ||
432 | } | ||
433 | |||
416 | /** | 434 | /** |
417 | * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. | 435 | * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. |
418 | * @ids: A pointer to a null terminated list of struct pci_device_id structures | 436 | * @ids: A pointer to a null terminated list of struct pci_device_id structures |
@@ -426,25 +444,11 @@ exit: | |||
426 | */ | 444 | */ |
427 | int pci_dev_present(const struct pci_device_id *ids) | 445 | int pci_dev_present(const struct pci_device_id *ids) |
428 | { | 446 | { |
429 | struct pci_dev *dev; | 447 | return pci_find_present(ids) == NULL ? 0 : 1; |
430 | int found = 0; | ||
431 | |||
432 | WARN_ON(in_interrupt()); | ||
433 | down_read(&pci_bus_sem); | ||
434 | while (ids->vendor || ids->subvendor || ids->class_mask) { | ||
435 | list_for_each_entry(dev, &pci_devices, global_list) { | ||
436 | if (pci_match_one_device(ids, dev)) { | ||
437 | found = 1; | ||
438 | goto exit; | ||
439 | } | ||
440 | } | ||
441 | ids++; | ||
442 | } | ||
443 | exit: | ||
444 | up_read(&pci_bus_sem); | ||
445 | return found; | ||
446 | } | 448 | } |
449 | |||
447 | EXPORT_SYMBOL(pci_dev_present); | 450 | EXPORT_SYMBOL(pci_dev_present); |
451 | EXPORT_SYMBOL(pci_find_present); | ||
448 | 452 | ||
449 | EXPORT_SYMBOL(pci_find_device); | 453 | EXPORT_SYMBOL(pci_find_device); |
450 | EXPORT_SYMBOL(pci_find_device_reverse); | 454 | EXPORT_SYMBOL(pci_find_device_reverse); |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index ab78e4bbdd83..cb4ced3560e9 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -33,11 +33,22 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
33 | u32 new, check, mask; | 33 | u32 new, check, mask; |
34 | int reg; | 34 | int reg; |
35 | 35 | ||
36 | /* Ignore resources for unimplemented BARs and unused resource slots | 36 | /* |
37 | for 64 bit BARs. */ | 37 | * Ignore resources for unimplemented BARs and unused resource slots |
38 | * for 64 bit BARs. | ||
39 | */ | ||
38 | if (!res->flags) | 40 | if (!res->flags) |
39 | return; | 41 | return; |
40 | 42 | ||
43 | /* | ||
44 | * Ignore non-moveable resources. This might be legacy resources for | ||
45 | * which no functional BAR register exists or another important | ||
46 | * system resource we should better not move around in system address | ||
47 | * space. | ||
48 | */ | ||
49 | if (res->flags & IORESOURCE_PCI_FIXED) | ||
50 | return; | ||
51 | |||
41 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
42 | 53 | ||
43 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " | 54 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " |
@@ -212,6 +223,10 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
212 | resource_size_t r_align; | 223 | resource_size_t r_align; |
213 | 224 | ||
214 | r = &dev->resource[i]; | 225 | r = &dev->resource[i]; |
226 | |||
227 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
228 | continue; | ||
229 | |||
215 | r_align = r->end - r->start; | 230 | r_align = r->end - r->start; |
216 | 231 | ||
217 | if (!(r->flags) || r->parent) | 232 | if (!(r->flags) || r->parent) |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 6303970e93c1..24ee8be359f5 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -130,7 +130,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H | |||
130 | 130 | ||
131 | struct usblp { | 131 | struct usblp { |
132 | struct usb_device *dev; /* USB device */ | 132 | struct usb_device *dev; /* USB device */ |
133 | struct semaphore sem; /* locks this struct, especially "dev" */ | 133 | struct mutex mut; /* locks this struct, especially "dev" */ |
134 | char *writebuf; /* write transfer_buffer */ | 134 | char *writebuf; /* write transfer_buffer */ |
135 | char *readbuf; /* read transfer_buffer */ | 135 | char *readbuf; /* read transfer_buffer */ |
136 | char *statusbuf; /* status transfer_buffer */ | 136 | char *statusbuf; /* status transfer_buffer */ |
@@ -465,7 +465,7 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
465 | int twoints[2]; | 465 | int twoints[2]; |
466 | int retval = 0; | 466 | int retval = 0; |
467 | 467 | ||
468 | down (&usblp->sem); | 468 | mutex_lock (&usblp->mut); |
469 | if (!usblp->present) { | 469 | if (!usblp->present) { |
470 | retval = -ENODEV; | 470 | retval = -ENODEV; |
471 | goto done; | 471 | goto done; |
@@ -644,14 +644,14 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
644 | } | 644 | } |
645 | 645 | ||
646 | done: | 646 | done: |
647 | up (&usblp->sem); | 647 | mutex_unlock (&usblp->mut); |
648 | return retval; | 648 | return retval; |
649 | } | 649 | } |
650 | 650 | ||
651 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 651 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
652 | { | 652 | { |
653 | struct usblp *usblp = file->private_data; | 653 | struct usblp *usblp = file->private_data; |
654 | int timeout, rv, err = 0, transfer_length = 0; | 654 | int timeout, intr, rv, err = 0, transfer_length = 0; |
655 | size_t writecount = 0; | 655 | size_t writecount = 0; |
656 | 656 | ||
657 | while (writecount < count) { | 657 | while (writecount < count) { |
@@ -668,14 +668,16 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
668 | if (rv < 0) | 668 | if (rv < 0) |
669 | return writecount ? writecount : -EINTR; | 669 | return writecount ? writecount : -EINTR; |
670 | } | 670 | } |
671 | down (&usblp->sem); | 671 | intr = mutex_lock_interruptible (&usblp->mut); |
672 | if (intr) | ||
673 | return writecount ? writecount : -EINTR; | ||
672 | if (!usblp->present) { | 674 | if (!usblp->present) { |
673 | up (&usblp->sem); | 675 | mutex_unlock (&usblp->mut); |
674 | return -ENODEV; | 676 | return -ENODEV; |
675 | } | 677 | } |
676 | 678 | ||
677 | if (usblp->sleeping) { | 679 | if (usblp->sleeping) { |
678 | up (&usblp->sem); | 680 | mutex_unlock (&usblp->mut); |
679 | return writecount ? writecount : -ENODEV; | 681 | return writecount ? writecount : -ENODEV; |
680 | } | 682 | } |
681 | 683 | ||
@@ -687,10 +689,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
687 | err = usblp->writeurb->status; | 689 | err = usblp->writeurb->status; |
688 | } else | 690 | } else |
689 | err = usblp_check_status(usblp, err); | 691 | err = usblp_check_status(usblp, err); |
690 | up (&usblp->sem); | 692 | mutex_unlock (&usblp->mut); |
691 | 693 | ||
692 | /* if the fault was due to disconnect, let khubd's | 694 | /* if the fault was due to disconnect, let khubd's |
693 | * call to usblp_disconnect() grab usblp->sem ... | 695 | * call to usblp_disconnect() grab usblp->mut ... |
694 | */ | 696 | */ |
695 | schedule (); | 697 | schedule (); |
696 | continue; | 698 | continue; |
@@ -702,7 +704,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
702 | */ | 704 | */ |
703 | writecount += transfer_length; | 705 | writecount += transfer_length; |
704 | if (writecount == count) { | 706 | if (writecount == count) { |
705 | up(&usblp->sem); | 707 | mutex_unlock(&usblp->mut); |
706 | break; | 708 | break; |
707 | } | 709 | } |
708 | 710 | ||
@@ -714,7 +716,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
714 | 716 | ||
715 | if (copy_from_user(usblp->writeurb->transfer_buffer, | 717 | if (copy_from_user(usblp->writeurb->transfer_buffer, |
716 | buffer + writecount, transfer_length)) { | 718 | buffer + writecount, transfer_length)) { |
717 | up(&usblp->sem); | 719 | mutex_unlock(&usblp->mut); |
718 | return writecount ? writecount : -EFAULT; | 720 | return writecount ? writecount : -EFAULT; |
719 | } | 721 | } |
720 | 722 | ||
@@ -727,10 +729,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
727 | count = -EIO; | 729 | count = -EIO; |
728 | else | 730 | else |
729 | count = writecount ? writecount : -ENOMEM; | 731 | count = writecount ? writecount : -ENOMEM; |
730 | up (&usblp->sem); | 732 | mutex_unlock (&usblp->mut); |
731 | break; | 733 | break; |
732 | } | 734 | } |
733 | up (&usblp->sem); | 735 | mutex_unlock (&usblp->mut); |
734 | } | 736 | } |
735 | 737 | ||
736 | return count; | 738 | return count; |
@@ -739,12 +741,14 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
739 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 741 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
740 | { | 742 | { |
741 | struct usblp *usblp = file->private_data; | 743 | struct usblp *usblp = file->private_data; |
742 | int rv; | 744 | int rv, intr; |
743 | 745 | ||
744 | if (!usblp->bidir) | 746 | if (!usblp->bidir) |
745 | return -EINVAL; | 747 | return -EINVAL; |
746 | 748 | ||
747 | down (&usblp->sem); | 749 | intr = mutex_lock_interruptible (&usblp->mut); |
750 | if (intr) | ||
751 | return -EINTR; | ||
748 | if (!usblp->present) { | 752 | if (!usblp->present) { |
749 | count = -ENODEV; | 753 | count = -ENODEV; |
750 | goto done; | 754 | goto done; |
@@ -757,9 +761,9 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, | |||
757 | count = -EAGAIN; | 761 | count = -EAGAIN; |
758 | goto done; | 762 | goto done; |
759 | } | 763 | } |
760 | up(&usblp->sem); | 764 | mutex_unlock(&usblp->mut); |
761 | rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); | 765 | rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); |
762 | down(&usblp->sem); | 766 | mutex_lock(&usblp->mut); |
763 | if (rv < 0) { | 767 | if (rv < 0) { |
764 | count = -EINTR; | 768 | count = -EINTR; |
765 | goto done; | 769 | goto done; |
@@ -807,7 +811,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, | |||
807 | } | 811 | } |
808 | 812 | ||
809 | done: | 813 | done: |
810 | up (&usblp->sem); | 814 | mutex_unlock (&usblp->mut); |
811 | return count; | 815 | return count; |
812 | } | 816 | } |
813 | 817 | ||
@@ -886,7 +890,7 @@ static int usblp_probe(struct usb_interface *intf, | |||
886 | goto abort; | 890 | goto abort; |
887 | } | 891 | } |
888 | usblp->dev = dev; | 892 | usblp->dev = dev; |
889 | init_MUTEX (&usblp->sem); | 893 | mutex_init (&usblp->mut); |
890 | init_waitqueue_head(&usblp->wait); | 894 | init_waitqueue_head(&usblp->wait); |
891 | usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 895 | usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; |
892 | usblp->intf = intf; | 896 | usblp->intf = intf; |
@@ -1178,7 +1182,7 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1178 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | 1182 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); |
1179 | 1183 | ||
1180 | mutex_lock (&usblp_mutex); | 1184 | mutex_lock (&usblp_mutex); |
1181 | down (&usblp->sem); | 1185 | mutex_lock (&usblp->mut); |
1182 | usblp->present = 0; | 1186 | usblp->present = 0; |
1183 | usb_set_intfdata (intf, NULL); | 1187 | usb_set_intfdata (intf, NULL); |
1184 | 1188 | ||
@@ -1187,7 +1191,7 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1187 | usblp->writebuf, usblp->writeurb->transfer_dma); | 1191 | usblp->writebuf, usblp->writeurb->transfer_dma); |
1188 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, | 1192 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, |
1189 | usblp->readbuf, usblp->readurb->transfer_dma); | 1193 | usblp->readbuf, usblp->readurb->transfer_dma); |
1190 | up (&usblp->sem); | 1194 | mutex_unlock (&usblp->mut); |
1191 | 1195 | ||
1192 | if (!usblp->used) | 1196 | if (!usblp->used) |
1193 | usblp_cleanup (usblp); | 1197 | usblp_cleanup (usblp); |
@@ -1200,11 +1204,11 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | |||
1200 | 1204 | ||
1201 | /* this races against normal access and open */ | 1205 | /* this races against normal access and open */ |
1202 | mutex_lock (&usblp_mutex); | 1206 | mutex_lock (&usblp_mutex); |
1203 | down (&usblp->sem); | 1207 | mutex_lock (&usblp->mut); |
1204 | /* we take no more IO */ | 1208 | /* we take no more IO */ |
1205 | usblp->sleeping = 1; | 1209 | usblp->sleeping = 1; |
1206 | usblp_unlink_urbs(usblp); | 1210 | usblp_unlink_urbs(usblp); |
1207 | up (&usblp->sem); | 1211 | mutex_unlock (&usblp->mut); |
1208 | mutex_unlock (&usblp_mutex); | 1212 | mutex_unlock (&usblp_mutex); |
1209 | 1213 | ||
1210 | return 0; | 1214 | return 0; |
@@ -1216,12 +1220,12 @@ static int usblp_resume (struct usb_interface *intf) | |||
1216 | int r; | 1220 | int r; |
1217 | 1221 | ||
1218 | mutex_lock (&usblp_mutex); | 1222 | mutex_lock (&usblp_mutex); |
1219 | down (&usblp->sem); | 1223 | mutex_lock (&usblp->mut); |
1220 | 1224 | ||
1221 | usblp->sleeping = 0; | 1225 | usblp->sleeping = 0; |
1222 | r = handle_bidir (usblp); | 1226 | r = handle_bidir (usblp); |
1223 | 1227 | ||
1224 | up (&usblp->sem); | 1228 | mutex_unlock (&usblp->mut); |
1225 | mutex_unlock (&usblp_mutex); | 1229 | mutex_unlock (&usblp_mutex); |
1226 | 1230 | ||
1227 | return r; | 1231 | return r; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 3ed4cb2d56d9..4b3a6ab29bd3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -962,7 +962,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
962 | kfree(dr); | 962 | kfree(dr); |
963 | return -EFAULT; | 963 | return -EFAULT; |
964 | } | 964 | } |
965 | snoop(&ps->dev->dev, "control urb\n"); | 965 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
966 | "bRrequestType=%02x wValue=%04x " | ||
967 | "wIndex=%04x wLength=%04x\n", | ||
968 | dr->bRequest, dr->bRequestType, dr->wValue, | ||
969 | dr->wIndex, dr->wLength); | ||
966 | break; | 970 | break; |
967 | 971 | ||
968 | case USBDEVFS_URB_TYPE_BULK: | 972 | case USBDEVFS_URB_TYPE_BULK: |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 3e0abbb49fe1..812c733ba8ce 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -43,14 +43,16 @@ | |||
43 | #include <linux/usb_gadget.h> | 43 | #include <linux/usb_gadget.h> |
44 | 44 | ||
45 | #include <asm/byteorder.h> | 45 | #include <asm/byteorder.h> |
46 | #include <asm/hardware.h> | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
48 | #include <asm/system.h> | 49 | #include <asm/system.h> |
49 | #include <asm/mach-types.h> | 50 | #include <asm/mach-types.h> |
50 | 51 | ||
51 | #include <asm/arch/hardware.h> | ||
52 | #include <asm/arch/gpio.h> | 52 | #include <asm/arch/gpio.h> |
53 | #include <asm/arch/board.h> | 53 | #include <asm/arch/board.h> |
54 | #include <asm/arch/cpu.h> | ||
55 | #include <asm/arch/at91sam9261_matrix.h> | ||
54 | 56 | ||
55 | #include "at91_udc.h" | 57 | #include "at91_udc.h" |
56 | 58 | ||
@@ -78,27 +80,11 @@ | |||
78 | static const char driver_name [] = "at91_udc"; | 80 | static const char driver_name [] = "at91_udc"; |
79 | static const char ep0name[] = "ep0"; | 81 | static const char ep0name[] = "ep0"; |
80 | 82 | ||
81 | /*-------------------------------------------------------------------------*/ | ||
82 | 83 | ||
83 | /* | 84 | #define at91_udp_read(dev, reg) \ |
84 | * Read from a UDP register. | 85 | __raw_readl((dev)->udp_baseaddr + (reg)) |
85 | */ | 86 | #define at91_udp_write(dev, reg, val) \ |
86 | static inline unsigned long at91_udp_read(unsigned int reg) | 87 | __raw_writel((val), (dev)->udp_baseaddr + (reg)) |
87 | { | ||
88 | void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; | ||
89 | |||
90 | return __raw_readl(udp_base + reg); | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Write to a UDP register. | ||
95 | */ | ||
96 | static inline void at91_udp_write(unsigned int reg, unsigned long value) | ||
97 | { | ||
98 | void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; | ||
99 | |||
100 | __raw_writel(value, udp_base + reg); | ||
101 | } | ||
102 | 88 | ||
103 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
104 | 90 | ||
@@ -210,13 +196,13 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
210 | return 0; | 196 | return 0; |
211 | } | 197 | } |
212 | 198 | ||
213 | tmp = at91_udp_read(AT91_UDP_FRM_NUM); | 199 | tmp = at91_udp_read(udc, AT91_UDP_FRM_NUM); |
214 | seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, | 200 | seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, |
215 | (tmp & AT91_UDP_FRM_OK) ? " ok" : "", | 201 | (tmp & AT91_UDP_FRM_OK) ? " ok" : "", |
216 | (tmp & AT91_UDP_FRM_ERR) ? " err" : "", | 202 | (tmp & AT91_UDP_FRM_ERR) ? " err" : "", |
217 | (tmp & AT91_UDP_NUM)); | 203 | (tmp & AT91_UDP_NUM)); |
218 | 204 | ||
219 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 205 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
220 | seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, | 206 | seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, |
221 | (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", | 207 | (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", |
222 | (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", | 208 | (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", |
@@ -224,13 +210,13 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
224 | (tmp & AT91_UDP_CONFG) ? " confg" : "", | 210 | (tmp & AT91_UDP_CONFG) ? " confg" : "", |
225 | (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); | 211 | (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); |
226 | 212 | ||
227 | tmp = at91_udp_read(AT91_UDP_FADDR); | 213 | tmp = at91_udp_read(udc, AT91_UDP_FADDR); |
228 | seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, | 214 | seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, |
229 | (tmp & AT91_UDP_FEN) ? " fen" : "", | 215 | (tmp & AT91_UDP_FEN) ? " fen" : "", |
230 | (tmp & AT91_UDP_FADD)); | 216 | (tmp & AT91_UDP_FADD)); |
231 | 217 | ||
232 | proc_irq_show(s, "imr ", at91_udp_read(AT91_UDP_IMR)); | 218 | proc_irq_show(s, "imr ", at91_udp_read(udc, AT91_UDP_IMR)); |
233 | proc_irq_show(s, "isr ", at91_udp_read(AT91_UDP_ISR)); | 219 | proc_irq_show(s, "isr ", at91_udp_read(udc, AT91_UDP_ISR)); |
234 | 220 | ||
235 | if (udc->enabled && udc->vbus) { | 221 | if (udc->enabled && udc->vbus) { |
236 | proc_ep_show(s, &udc->ep[0]); | 222 | proc_ep_show(s, &udc->ep[0]); |
@@ -286,6 +272,7 @@ static inline void remove_debug_file(struct at91_udc *udc) {} | |||
286 | static void done(struct at91_ep *ep, struct at91_request *req, int status) | 272 | static void done(struct at91_ep *ep, struct at91_request *req, int status) |
287 | { | 273 | { |
288 | unsigned stopped = ep->stopped; | 274 | unsigned stopped = ep->stopped; |
275 | struct at91_udc *udc = ep->udc; | ||
289 | 276 | ||
290 | list_del_init(&req->queue); | 277 | list_del_init(&req->queue); |
291 | if (req->req.status == -EINPROGRESS) | 278 | if (req->req.status == -EINPROGRESS) |
@@ -301,7 +288,7 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status) | |||
301 | 288 | ||
302 | /* ep0 is always ready; other endpoints need a non-empty queue */ | 289 | /* ep0 is always ready; other endpoints need a non-empty queue */ |
303 | if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) | 290 | if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) |
304 | at91_udp_write(AT91_UDP_IDR, ep->int_mask); | 291 | at91_udp_write(udc, AT91_UDP_IDR, ep->int_mask); |
305 | } | 292 | } |
306 | 293 | ||
307 | /*-------------------------------------------------------------------------*/ | 294 | /*-------------------------------------------------------------------------*/ |
@@ -554,8 +541,8 @@ ok: | |||
554 | * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, | 541 | * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, |
555 | * since endpoint resets don't reset hw pingpong state. | 542 | * since endpoint resets don't reset hw pingpong state. |
556 | */ | 543 | */ |
557 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 544 | at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask); |
558 | at91_udp_write(AT91_UDP_RST_EP, 0); | 545 | at91_udp_write(dev, AT91_UDP_RST_EP, 0); |
559 | 546 | ||
560 | local_irq_restore(flags); | 547 | local_irq_restore(flags); |
561 | return 0; | 548 | return 0; |
@@ -564,6 +551,7 @@ ok: | |||
564 | static int at91_ep_disable (struct usb_ep * _ep) | 551 | static int at91_ep_disable (struct usb_ep * _ep) |
565 | { | 552 | { |
566 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 553 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
554 | struct at91_udc *udc = ep->udc; | ||
567 | unsigned long flags; | 555 | unsigned long flags; |
568 | 556 | ||
569 | if (ep == &ep->udc->ep[0]) | 557 | if (ep == &ep->udc->ep[0]) |
@@ -579,8 +567,8 @@ static int at91_ep_disable (struct usb_ep * _ep) | |||
579 | 567 | ||
580 | /* reset fifos and endpoint */ | 568 | /* reset fifos and endpoint */ |
581 | if (ep->udc->clocked) { | 569 | if (ep->udc->clocked) { |
582 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 570 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
583 | at91_udp_write(AT91_UDP_RST_EP, 0); | 571 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
584 | __raw_writel(0, ep->creg); | 572 | __raw_writel(0, ep->creg); |
585 | } | 573 | } |
586 | 574 | ||
@@ -695,10 +683,10 @@ static int at91_ep_queue(struct usb_ep *_ep, | |||
695 | * reconfigures the endpoints. | 683 | * reconfigures the endpoints. |
696 | */ | 684 | */ |
697 | if (dev->wait_for_config_ack) { | 685 | if (dev->wait_for_config_ack) { |
698 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 686 | tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT); |
699 | tmp ^= AT91_UDP_CONFG; | 687 | tmp ^= AT91_UDP_CONFG; |
700 | VDBG("toggle config\n"); | 688 | VDBG("toggle config\n"); |
701 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 689 | at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp); |
702 | } | 690 | } |
703 | if (req->req.length == 0) { | 691 | if (req->req.length == 0) { |
704 | ep0_in_status: | 692 | ep0_in_status: |
@@ -727,7 +715,7 @@ ep0_in_status: | |||
727 | 715 | ||
728 | if (req && !status) { | 716 | if (req && !status) { |
729 | list_add_tail (&req->queue, &ep->queue); | 717 | list_add_tail (&req->queue, &ep->queue); |
730 | at91_udp_write(AT91_UDP_IER, ep->int_mask); | 718 | at91_udp_write(dev, AT91_UDP_IER, ep->int_mask); |
731 | } | 719 | } |
732 | done: | 720 | done: |
733 | local_irq_restore(flags); | 721 | local_irq_restore(flags); |
@@ -758,6 +746,7 @@ static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
758 | static int at91_ep_set_halt(struct usb_ep *_ep, int value) | 746 | static int at91_ep_set_halt(struct usb_ep *_ep, int value) |
759 | { | 747 | { |
760 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 748 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
749 | struct at91_udc *udc = ep->udc; | ||
761 | u32 __iomem *creg; | 750 | u32 __iomem *creg; |
762 | u32 csr; | 751 | u32 csr; |
763 | unsigned long flags; | 752 | unsigned long flags; |
@@ -785,8 +774,8 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value) | |||
785 | csr |= AT91_UDP_FORCESTALL; | 774 | csr |= AT91_UDP_FORCESTALL; |
786 | VDBG("halt %s\n", ep->ep.name); | 775 | VDBG("halt %s\n", ep->ep.name); |
787 | } else { | 776 | } else { |
788 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 777 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
789 | at91_udp_write(AT91_UDP_RST_EP, 0); | 778 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
790 | csr &= ~AT91_UDP_FORCESTALL; | 779 | csr &= ~AT91_UDP_FORCESTALL; |
791 | } | 780 | } |
792 | __raw_writel(csr, creg); | 781 | __raw_writel(csr, creg); |
@@ -813,9 +802,11 @@ static struct usb_ep_ops at91_ep_ops = { | |||
813 | 802 | ||
814 | static int at91_get_frame(struct usb_gadget *gadget) | 803 | static int at91_get_frame(struct usb_gadget *gadget) |
815 | { | 804 | { |
805 | struct at91_udc *udc = to_udc(gadget); | ||
806 | |||
816 | if (!to_udc(gadget)->clocked) | 807 | if (!to_udc(gadget)->clocked) |
817 | return -EINVAL; | 808 | return -EINVAL; |
818 | return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM; | 809 | return at91_udp_read(udc, AT91_UDP_FRM_NUM) & AT91_UDP_NUM; |
819 | } | 810 | } |
820 | 811 | ||
821 | static int at91_wakeup(struct usb_gadget *gadget) | 812 | static int at91_wakeup(struct usb_gadget *gadget) |
@@ -833,11 +824,11 @@ static int at91_wakeup(struct usb_gadget *gadget) | |||
833 | 824 | ||
834 | /* NOTE: some "early versions" handle ESR differently ... */ | 825 | /* NOTE: some "early versions" handle ESR differently ... */ |
835 | 826 | ||
836 | glbstate = at91_udp_read(AT91_UDP_GLB_STAT); | 827 | glbstate = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
837 | if (!(glbstate & AT91_UDP_ESR)) | 828 | if (!(glbstate & AT91_UDP_ESR)) |
838 | goto done; | 829 | goto done; |
839 | glbstate |= AT91_UDP_ESR; | 830 | glbstate |= AT91_UDP_ESR; |
840 | at91_udp_write(AT91_UDP_GLB_STAT, glbstate); | 831 | at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate); |
841 | 832 | ||
842 | done: | 833 | done: |
843 | local_irq_restore(flags); | 834 | local_irq_restore(flags); |
@@ -861,6 +852,7 @@ static void udc_reinit(struct at91_udc *udc) | |||
861 | ep->stopped = 0; | 852 | ep->stopped = 0; |
862 | ep->fifo_bank = 0; | 853 | ep->fifo_bank = 0; |
863 | ep->ep.maxpacket = ep->maxpacket; | 854 | ep->ep.maxpacket = ep->maxpacket; |
855 | ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i); | ||
864 | // initialiser une queue par endpoint | 856 | // initialiser une queue par endpoint |
865 | INIT_LIST_HEAD(&ep->queue); | 857 | INIT_LIST_HEAD(&ep->queue); |
866 | } | 858 | } |
@@ -915,14 +907,41 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
915 | if (!udc->enabled || !udc->vbus) | 907 | if (!udc->enabled || !udc->vbus) |
916 | is_on = 0; | 908 | is_on = 0; |
917 | DBG("%sactive\n", is_on ? "" : "in"); | 909 | DBG("%sactive\n", is_on ? "" : "in"); |
910 | |||
918 | if (is_on) { | 911 | if (is_on) { |
919 | clk_on(udc); | 912 | clk_on(udc); |
920 | at91_udp_write(AT91_UDP_TXVC, 0); | 913 | at91_udp_write(udc, AT91_UDP_TXVC, 0); |
921 | at91_set_gpio_value(udc->board.pullup_pin, 1); | 914 | if (cpu_is_at91rm9200()) |
922 | } else { | 915 | at91_set_gpio_value(udc->board.pullup_pin, 1); |
916 | else if (cpu_is_at91sam9260()) { | ||
917 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
918 | |||
919 | txvc |= AT91_UDP_TXVC_PUON; | ||
920 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
921 | } else if (cpu_is_at91sam9261()) { | ||
922 | u32 usbpucr; | ||
923 | |||
924 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
925 | usbpucr |= AT91_MATRIX_USBPUCR_PUON; | ||
926 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
927 | } | ||
928 | } else { | ||
923 | stop_activity(udc); | 929 | stop_activity(udc); |
924 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 930 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
925 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 931 | if (cpu_is_at91rm9200()) |
932 | at91_set_gpio_value(udc->board.pullup_pin, 0); | ||
933 | else if (cpu_is_at91sam9260()) { | ||
934 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
935 | |||
936 | txvc &= ~AT91_UDP_TXVC_PUON; | ||
937 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
938 | } else if (cpu_is_at91sam9261()) { | ||
939 | u32 usbpucr; | ||
940 | |||
941 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
942 | usbpucr &= ~AT91_MATRIX_USBPUCR_PUON; | ||
943 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
944 | } | ||
926 | clk_off(udc); | 945 | clk_off(udc); |
927 | } | 946 | } |
928 | } | 947 | } |
@@ -936,7 +955,10 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active) | |||
936 | // VDBG("vbus %s\n", is_active ? "on" : "off"); | 955 | // VDBG("vbus %s\n", is_active ? "on" : "off"); |
937 | local_irq_save(flags); | 956 | local_irq_save(flags); |
938 | udc->vbus = (is_active != 0); | 957 | udc->vbus = (is_active != 0); |
939 | pullup(udc, is_active); | 958 | if (udc->driver) |
959 | pullup(udc, is_active); | ||
960 | else | ||
961 | pullup(udc, 0); | ||
940 | local_irq_restore(flags); | 962 | local_irq_restore(flags); |
941 | return 0; | 963 | return 0; |
942 | } | 964 | } |
@@ -1086,7 +1108,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1086 | 1108 | ||
1087 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1109 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1088 | | USB_REQ_SET_CONFIGURATION: | 1110 | | USB_REQ_SET_CONFIGURATION: |
1089 | tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; | 1111 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; |
1090 | if (pkt.r.wValue) | 1112 | if (pkt.r.wValue) |
1091 | udc->wait_for_config_ack = (tmp == 0); | 1113 | udc->wait_for_config_ack = (tmp == 0); |
1092 | else | 1114 | else |
@@ -1103,7 +1125,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1103 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1125 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1104 | | USB_REQ_GET_STATUS: | 1126 | | USB_REQ_GET_STATUS: |
1105 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); | 1127 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); |
1106 | if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR) | 1128 | if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR) |
1107 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); | 1129 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); |
1108 | PACKET("get device status\n"); | 1130 | PACKET("get device status\n"); |
1109 | __raw_writeb(tmp, dreg); | 1131 | __raw_writeb(tmp, dreg); |
@@ -1114,17 +1136,17 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1114 | | USB_REQ_SET_FEATURE: | 1136 | | USB_REQ_SET_FEATURE: |
1115 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) | 1137 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) |
1116 | goto stall; | 1138 | goto stall; |
1117 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1139 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1118 | tmp |= AT91_UDP_ESR; | 1140 | tmp |= AT91_UDP_ESR; |
1119 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1141 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1120 | goto succeed; | 1142 | goto succeed; |
1121 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1143 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1122 | | USB_REQ_CLEAR_FEATURE: | 1144 | | USB_REQ_CLEAR_FEATURE: |
1123 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) | 1145 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) |
1124 | goto stall; | 1146 | goto stall; |
1125 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1147 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1126 | tmp &= ~AT91_UDP_ESR; | 1148 | tmp &= ~AT91_UDP_ESR; |
1127 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1149 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1128 | goto succeed; | 1150 | goto succeed; |
1129 | 1151 | ||
1130 | /* | 1152 | /* |
@@ -1206,8 +1228,8 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1206 | } else if (ep->is_in) | 1228 | } else if (ep->is_in) |
1207 | goto stall; | 1229 | goto stall; |
1208 | 1230 | ||
1209 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 1231 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
1210 | at91_udp_write(AT91_UDP_RST_EP, 0); | 1232 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
1211 | tmp = __raw_readl(ep->creg); | 1233 | tmp = __raw_readl(ep->creg); |
1212 | tmp |= CLR_FX; | 1234 | tmp |= CLR_FX; |
1213 | tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); | 1235 | tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); |
@@ -1222,7 +1244,10 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1222 | #undef w_length | 1244 | #undef w_length |
1223 | 1245 | ||
1224 | /* pass request up to the gadget driver */ | 1246 | /* pass request up to the gadget driver */ |
1225 | status = udc->driver->setup(&udc->gadget, &pkt.r); | 1247 | if (udc->driver) |
1248 | status = udc->driver->setup(&udc->gadget, &pkt.r); | ||
1249 | else | ||
1250 | status = -ENODEV; | ||
1226 | if (status < 0) { | 1251 | if (status < 0) { |
1227 | stall: | 1252 | stall: |
1228 | VDBG("req %02x.%02x protocol STALL; stat %d\n", | 1253 | VDBG("req %02x.%02x protocol STALL; stat %d\n", |
@@ -1300,13 +1325,13 @@ static void handle_ep0(struct at91_udc *udc) | |||
1300 | if (udc->wait_for_addr_ack) { | 1325 | if (udc->wait_for_addr_ack) { |
1301 | u32 tmp; | 1326 | u32 tmp; |
1302 | 1327 | ||
1303 | at91_udp_write(AT91_UDP_FADDR, | 1328 | at91_udp_write(udc, AT91_UDP_FADDR, |
1304 | AT91_UDP_FEN | udc->addr); | 1329 | AT91_UDP_FEN | udc->addr); |
1305 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1330 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1306 | tmp &= ~AT91_UDP_FADDEN; | 1331 | tmp &= ~AT91_UDP_FADDEN; |
1307 | if (udc->addr) | 1332 | if (udc->addr) |
1308 | tmp |= AT91_UDP_FADDEN; | 1333 | tmp |= AT91_UDP_FADDEN; |
1309 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1334 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1310 | 1335 | ||
1311 | udc->wait_for_addr_ack = 0; | 1336 | udc->wait_for_addr_ack = 0; |
1312 | VDBG("address %d\n", udc->addr); | 1337 | VDBG("address %d\n", udc->addr); |
@@ -1374,28 +1399,28 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1374 | while (rescans--) { | 1399 | while (rescans--) { |
1375 | u32 status; | 1400 | u32 status; |
1376 | 1401 | ||
1377 | status = at91_udp_read(AT91_UDP_ISR) | 1402 | status = at91_udp_read(udc, AT91_UDP_ISR) |
1378 | & at91_udp_read(AT91_UDP_IMR); | 1403 | & at91_udp_read(udc, AT91_UDP_IMR); |
1379 | if (!status) | 1404 | if (!status) |
1380 | break; | 1405 | break; |
1381 | 1406 | ||
1382 | /* USB reset irq: not maskable */ | 1407 | /* USB reset irq: not maskable */ |
1383 | if (status & AT91_UDP_ENDBUSRES) { | 1408 | if (status & AT91_UDP_ENDBUSRES) { |
1384 | at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); | 1409 | at91_udp_write(udc, AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); |
1385 | at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS); | 1410 | at91_udp_write(udc, AT91_UDP_IER, MINIMUS_INTERRUPTUS); |
1386 | /* Atmel code clears this irq twice */ | 1411 | /* Atmel code clears this irq twice */ |
1387 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1412 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1388 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1413 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1389 | VDBG("end bus reset\n"); | 1414 | VDBG("end bus reset\n"); |
1390 | udc->addr = 0; | 1415 | udc->addr = 0; |
1391 | stop_activity(udc); | 1416 | stop_activity(udc); |
1392 | 1417 | ||
1393 | /* enable ep0 */ | 1418 | /* enable ep0 */ |
1394 | at91_udp_write(AT91_UDP_CSR(0), | 1419 | at91_udp_write(udc, AT91_UDP_CSR(0), |
1395 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); | 1420 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); |
1396 | udc->gadget.speed = USB_SPEED_FULL; | 1421 | udc->gadget.speed = USB_SPEED_FULL; |
1397 | udc->suspended = 0; | 1422 | udc->suspended = 0; |
1398 | at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); | 1423 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_EP(0)); |
1399 | 1424 | ||
1400 | /* | 1425 | /* |
1401 | * NOTE: this driver keeps clocks off unless the | 1426 | * NOTE: this driver keeps clocks off unless the |
@@ -1406,9 +1431,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1406 | 1431 | ||
1407 | /* host initiated suspend (3+ms bus idle) */ | 1432 | /* host initiated suspend (3+ms bus idle) */ |
1408 | } else if (status & AT91_UDP_RXSUSP) { | 1433 | } else if (status & AT91_UDP_RXSUSP) { |
1409 | at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP); | 1434 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP); |
1410 | at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM); | 1435 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM); |
1411 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP); | 1436 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP); |
1412 | // VDBG("bus suspend\n"); | 1437 | // VDBG("bus suspend\n"); |
1413 | if (udc->suspended) | 1438 | if (udc->suspended) |
1414 | continue; | 1439 | continue; |
@@ -1425,9 +1450,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1425 | 1450 | ||
1426 | /* host initiated resume */ | 1451 | /* host initiated resume */ |
1427 | } else if (status & AT91_UDP_RXRSM) { | 1452 | } else if (status & AT91_UDP_RXRSM) { |
1428 | at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM); | 1453 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); |
1429 | at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP); | 1454 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP); |
1430 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM); | 1455 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); |
1431 | // VDBG("bus resume\n"); | 1456 | // VDBG("bus resume\n"); |
1432 | if (!udc->suspended) | 1457 | if (!udc->suspended) |
1433 | continue; | 1458 | continue; |
@@ -1485,8 +1510,6 @@ static struct at91_udc controller = { | |||
1485 | }, | 1510 | }, |
1486 | .udc = &controller, | 1511 | .udc = &controller, |
1487 | .maxpacket = 8, | 1512 | .maxpacket = 8, |
1488 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1489 | + AT91_UDP_CSR(0)), | ||
1490 | .int_mask = 1 << 0, | 1513 | .int_mask = 1 << 0, |
1491 | }, | 1514 | }, |
1492 | .ep[1] = { | 1515 | .ep[1] = { |
@@ -1497,8 +1520,6 @@ static struct at91_udc controller = { | |||
1497 | .udc = &controller, | 1520 | .udc = &controller, |
1498 | .is_pingpong = 1, | 1521 | .is_pingpong = 1, |
1499 | .maxpacket = 64, | 1522 | .maxpacket = 64, |
1500 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1501 | + AT91_UDP_CSR(1)), | ||
1502 | .int_mask = 1 << 1, | 1523 | .int_mask = 1 << 1, |
1503 | }, | 1524 | }, |
1504 | .ep[2] = { | 1525 | .ep[2] = { |
@@ -1509,8 +1530,6 @@ static struct at91_udc controller = { | |||
1509 | .udc = &controller, | 1530 | .udc = &controller, |
1510 | .is_pingpong = 1, | 1531 | .is_pingpong = 1, |
1511 | .maxpacket = 64, | 1532 | .maxpacket = 64, |
1512 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1513 | + AT91_UDP_CSR(2)), | ||
1514 | .int_mask = 1 << 2, | 1533 | .int_mask = 1 << 2, |
1515 | }, | 1534 | }, |
1516 | .ep[3] = { | 1535 | .ep[3] = { |
@@ -1521,8 +1540,6 @@ static struct at91_udc controller = { | |||
1521 | }, | 1540 | }, |
1522 | .udc = &controller, | 1541 | .udc = &controller, |
1523 | .maxpacket = 8, | 1542 | .maxpacket = 8, |
1524 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1525 | + AT91_UDP_CSR(3)), | ||
1526 | .int_mask = 1 << 3, | 1543 | .int_mask = 1 << 3, |
1527 | }, | 1544 | }, |
1528 | .ep[4] = { | 1545 | .ep[4] = { |
@@ -1533,8 +1550,6 @@ static struct at91_udc controller = { | |||
1533 | .udc = &controller, | 1550 | .udc = &controller, |
1534 | .is_pingpong = 1, | 1551 | .is_pingpong = 1, |
1535 | .maxpacket = 256, | 1552 | .maxpacket = 256, |
1536 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1537 | + AT91_UDP_CSR(4)), | ||
1538 | .int_mask = 1 << 4, | 1553 | .int_mask = 1 << 4, |
1539 | }, | 1554 | }, |
1540 | .ep[5] = { | 1555 | .ep[5] = { |
@@ -1545,8 +1560,6 @@ static struct at91_udc controller = { | |||
1545 | .udc = &controller, | 1560 | .udc = &controller, |
1546 | .is_pingpong = 1, | 1561 | .is_pingpong = 1, |
1547 | .maxpacket = 256, | 1562 | .maxpacket = 256, |
1548 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1549 | + AT91_UDP_CSR(5)), | ||
1550 | .int_mask = 1 << 5, | 1563 | .int_mask = 1 << 5, |
1551 | }, | 1564 | }, |
1552 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ | 1565 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ |
@@ -1572,9 +1585,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
1572 | int retval; | 1585 | int retval; |
1573 | 1586 | ||
1574 | if (!driver | 1587 | if (!driver |
1575 | || driver->speed != USB_SPEED_FULL | 1588 | || driver->speed < USB_SPEED_FULL |
1576 | || !driver->bind | 1589 | || !driver->bind |
1577 | || !driver->unbind | ||
1578 | || !driver->setup) { | 1590 | || !driver->setup) { |
1579 | DBG("bad parameter.\n"); | 1591 | DBG("bad parameter.\n"); |
1580 | return -EINVAL; | 1592 | return -EINVAL; |
@@ -1595,6 +1607,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
1595 | if (retval) { | 1607 | if (retval) { |
1596 | DBG("driver->bind() returned %d\n", retval); | 1608 | DBG("driver->bind() returned %d\n", retval); |
1597 | udc->driver = NULL; | 1609 | udc->driver = NULL; |
1610 | udc->gadget.dev.driver = NULL; | ||
1611 | udc->gadget.dev.driver_data = NULL; | ||
1612 | udc->enabled = 0; | ||
1613 | udc->selfpowered = 0; | ||
1598 | return retval; | 1614 | return retval; |
1599 | } | 1615 | } |
1600 | 1616 | ||
@@ -1611,12 +1627,12 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
1611 | { | 1627 | { |
1612 | struct at91_udc *udc = &controller; | 1628 | struct at91_udc *udc = &controller; |
1613 | 1629 | ||
1614 | if (!driver || driver != udc->driver) | 1630 | if (!driver || driver != udc->driver || !driver->unbind) |
1615 | return -EINVAL; | 1631 | return -EINVAL; |
1616 | 1632 | ||
1617 | local_irq_disable(); | 1633 | local_irq_disable(); |
1618 | udc->enabled = 0; | 1634 | udc->enabled = 0; |
1619 | at91_udp_write(AT91_UDP_IDR, ~0); | 1635 | at91_udp_write(udc, AT91_UDP_IDR, ~0); |
1620 | pullup(udc, 0); | 1636 | pullup(udc, 0); |
1621 | local_irq_enable(); | 1637 | local_irq_enable(); |
1622 | 1638 | ||
@@ -1641,6 +1657,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1641 | struct device *dev = &pdev->dev; | 1657 | struct device *dev = &pdev->dev; |
1642 | struct at91_udc *udc; | 1658 | struct at91_udc *udc; |
1643 | int retval; | 1659 | int retval; |
1660 | struct resource *res; | ||
1644 | 1661 | ||
1645 | if (!dev->platform_data) { | 1662 | if (!dev->platform_data) { |
1646 | /* small (so we copy it) but critical! */ | 1663 | /* small (so we copy it) but critical! */ |
@@ -1658,7 +1675,13 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1658 | return -ENODEV; | 1675 | return -ENODEV; |
1659 | } | 1676 | } |
1660 | 1677 | ||
1661 | if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) { | 1678 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1679 | if (!res) | ||
1680 | return -ENXIO; | ||
1681 | |||
1682 | if (!request_mem_region(res->start, | ||
1683 | res->end - res->start + 1, | ||
1684 | driver_name)) { | ||
1662 | DBG("someone's using UDC memory\n"); | 1685 | DBG("someone's using UDC memory\n"); |
1663 | return -EBUSY; | 1686 | return -EBUSY; |
1664 | } | 1687 | } |
@@ -1668,15 +1691,23 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1668 | udc->gadget.dev.parent = dev; | 1691 | udc->gadget.dev.parent = dev; |
1669 | udc->board = *(struct at91_udc_data *) dev->platform_data; | 1692 | udc->board = *(struct at91_udc_data *) dev->platform_data; |
1670 | udc->pdev = pdev; | 1693 | udc->pdev = pdev; |
1671 | udc_reinit(udc); | ||
1672 | udc->enabled = 0; | 1694 | udc->enabled = 0; |
1673 | 1695 | ||
1696 | udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); | ||
1697 | if (!udc->udp_baseaddr) { | ||
1698 | release_mem_region(res->start, res->end - res->start + 1); | ||
1699 | return -ENOMEM; | ||
1700 | } | ||
1701 | |||
1702 | udc_reinit(udc); | ||
1703 | |||
1674 | /* get interface and function clocks */ | 1704 | /* get interface and function clocks */ |
1675 | udc->iclk = clk_get(dev, "udc_clk"); | 1705 | udc->iclk = clk_get(dev, "udc_clk"); |
1676 | udc->fclk = clk_get(dev, "udpck"); | 1706 | udc->fclk = clk_get(dev, "udpck"); |
1677 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { | 1707 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { |
1678 | DBG("clocks missing\n"); | 1708 | DBG("clocks missing\n"); |
1679 | return -ENODEV; | 1709 | retval = -ENODEV; |
1710 | goto fail0; | ||
1680 | } | 1711 | } |
1681 | 1712 | ||
1682 | retval = device_register(&udc->gadget.dev); | 1713 | retval = device_register(&udc->gadget.dev); |
@@ -1685,8 +1716,10 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1685 | 1716 | ||
1686 | /* don't do anything until we have both gadget driver and VBUS */ | 1717 | /* don't do anything until we have both gadget driver and VBUS */ |
1687 | clk_enable(udc->iclk); | 1718 | clk_enable(udc->iclk); |
1688 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 1719 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
1689 | at91_udp_write(AT91_UDP_IDR, 0xffffffff); | 1720 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); |
1721 | /* Clear all pending interrupts - UDP may be used by bootloader. */ | ||
1722 | at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); | ||
1690 | clk_disable(udc->iclk); | 1723 | clk_disable(udc->iclk); |
1691 | 1724 | ||
1692 | /* request UDC and maybe VBUS irqs */ | 1725 | /* request UDC and maybe VBUS irqs */ |
@@ -1698,6 +1731,11 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1698 | goto fail1; | 1731 | goto fail1; |
1699 | } | 1732 | } |
1700 | if (udc->board.vbus_pin > 0) { | 1733 | if (udc->board.vbus_pin > 0) { |
1734 | /* | ||
1735 | * Get the initial state of VBUS - we cannot expect | ||
1736 | * a pending interrupt. | ||
1737 | */ | ||
1738 | udc->vbus = at91_get_gpio_value(udc->board.vbus_pin); | ||
1701 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, | 1739 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
1702 | IRQF_DISABLED, driver_name, udc)) { | 1740 | IRQF_DISABLED, driver_name, udc)) { |
1703 | DBG("request vbus irq %d failed\n", | 1741 | DBG("request vbus irq %d failed\n", |
@@ -1720,7 +1758,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1720 | fail1: | 1758 | fail1: |
1721 | device_unregister(&udc->gadget.dev); | 1759 | device_unregister(&udc->gadget.dev); |
1722 | fail0: | 1760 | fail0: |
1723 | release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); | 1761 | release_mem_region(res->start, res->end - res->start + 1); |
1724 | DBG("%s probe failed, %d\n", driver_name, retval); | 1762 | DBG("%s probe failed, %d\n", driver_name, retval); |
1725 | return retval; | 1763 | return retval; |
1726 | } | 1764 | } |
@@ -1728,13 +1766,14 @@ fail0: | |||
1728 | static int __devexit at91udc_remove(struct platform_device *pdev) | 1766 | static int __devexit at91udc_remove(struct platform_device *pdev) |
1729 | { | 1767 | { |
1730 | struct at91_udc *udc = platform_get_drvdata(pdev); | 1768 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1769 | struct resource *res; | ||
1731 | 1770 | ||
1732 | DBG("remove\n"); | 1771 | DBG("remove\n"); |
1733 | 1772 | ||
1734 | pullup(udc, 0); | 1773 | if (udc->driver) |
1774 | return -EBUSY; | ||
1735 | 1775 | ||
1736 | if (udc->driver != 0) | 1776 | pullup(udc, 0); |
1737 | usb_gadget_unregister_driver(udc->driver); | ||
1738 | 1777 | ||
1739 | device_init_wakeup(&pdev->dev, 0); | 1778 | device_init_wakeup(&pdev->dev, 0); |
1740 | remove_debug_file(udc); | 1779 | remove_debug_file(udc); |
@@ -1742,7 +1781,10 @@ static int __devexit at91udc_remove(struct platform_device *pdev) | |||
1742 | free_irq(udc->board.vbus_pin, udc); | 1781 | free_irq(udc->board.vbus_pin, udc); |
1743 | free_irq(udc->udp_irq, udc); | 1782 | free_irq(udc->udp_irq, udc); |
1744 | device_unregister(&udc->gadget.dev); | 1783 | device_unregister(&udc->gadget.dev); |
1745 | release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); | 1784 | |
1785 | iounmap(udc->udp_baseaddr); | ||
1786 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1787 | release_mem_region(res->start, res->end - res->start + 1); | ||
1746 | 1788 | ||
1747 | clk_put(udc->iclk); | 1789 | clk_put(udc->iclk); |
1748 | clk_put(udc->fclk); | 1790 | clk_put(udc->fclk); |
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 882af42e86cc..677089baa59d 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -51,10 +51,10 @@ | |||
51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ | 51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ |
52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ | 52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ |
53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ | 53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ |
54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */ | 54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ |
55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ | 55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ |
56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ | 56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ |
57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */ | 57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ |
58 | 58 | ||
59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ | 59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ |
60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ | 60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ |
@@ -84,7 +84,7 @@ | |||
84 | 84 | ||
85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ | 85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ |
86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ | 86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ |
87 | 87 | #define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ | |
88 | 88 | ||
89 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
90 | 90 | ||
@@ -141,6 +141,7 @@ struct at91_udc { | |||
141 | struct clk *iclk, *fclk; | 141 | struct clk *iclk, *fclk; |
142 | struct platform_device *pdev; | 142 | struct platform_device *pdev; |
143 | struct proc_dir_entry *pde; | 143 | struct proc_dir_entry *pde; |
144 | void __iomem *udp_baseaddr; | ||
144 | int udp_irq; | 145 | int udp_irq; |
145 | }; | 146 | }; |
146 | 147 | ||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f1f32d7be5f9..3c2bc075ef4f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -779,7 +779,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
779 | return -EINVAL; | 779 | return -EINVAL; |
780 | if (dum->driver) | 780 | if (dum->driver) |
781 | return -EBUSY; | 781 | return -EBUSY; |
782 | if (!driver->bind || !driver->unbind || !driver->setup | 782 | if (!driver->bind || !driver->setup |
783 | || driver->speed == USB_SPEED_UNKNOWN) | 783 | || driver->speed == USB_SPEED_UNKNOWN) |
784 | return -EINVAL; | 784 | return -EINVAL; |
785 | 785 | ||
@@ -837,7 +837,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
837 | err_bind_driver: | 837 | err_bind_driver: |
838 | driver_unregister (&driver->driver); | 838 | driver_unregister (&driver->driver); |
839 | err_register: | 839 | err_register: |
840 | driver->unbind (&dum->gadget); | 840 | if (driver->unbind) |
841 | driver->unbind (&dum->gadget); | ||
841 | spin_lock_irq (&dum->lock); | 842 | spin_lock_irq (&dum->lock); |
842 | dum->pullup = 0; | 843 | dum->pullup = 0; |
843 | set_link_state (dum); | 844 | set_link_state (dum); |
@@ -857,7 +858,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
857 | 858 | ||
858 | if (!dum) | 859 | if (!dum) |
859 | return -ENODEV; | 860 | return -ENODEV; |
860 | if (!driver || driver != dum->driver) | 861 | if (!driver || driver != dum->driver || !driver->unbind) |
861 | return -EINVAL; | 862 | return -EINVAL; |
862 | 863 | ||
863 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", | 864 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a265e262a2ee..72f2ae96fbf3 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -4100,7 +4100,7 @@ static struct usb_gadget_driver fsg_driver = { | |||
4100 | #endif | 4100 | #endif |
4101 | .function = (char *) longname, | 4101 | .function = (char *) longname, |
4102 | .bind = fsg_bind, | 4102 | .bind = fsg_bind, |
4103 | .unbind = __exit_p(fsg_unbind), | 4103 | .unbind = fsg_unbind, |
4104 | .disconnect = fsg_disconnect, | 4104 | .disconnect = fsg_disconnect, |
4105 | .setup = fsg_setup, | 4105 | .setup = fsg_setup, |
4106 | .suspend = fsg_suspend, | 4106 | .suspend = fsg_suspend, |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 31351826f2ba..f1a679656c96 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -123,7 +123,7 @@ struct gmidi_device { | |||
123 | struct usb_request *req; /* for control responses */ | 123 | struct usb_request *req; /* for control responses */ |
124 | u8 config; | 124 | u8 config; |
125 | struct usb_ep *in_ep, *out_ep; | 125 | struct usb_ep *in_ep, *out_ep; |
126 | struct snd_card *card; | 126 | struct snd_card *card; |
127 | struct snd_rawmidi *rmidi; | 127 | struct snd_rawmidi *rmidi; |
128 | struct snd_rawmidi_substream *in_substream; | 128 | struct snd_rawmidi_substream *in_substream; |
129 | struct snd_rawmidi_substream *out_substream; | 129 | struct snd_rawmidi_substream *out_substream; |
@@ -490,7 +490,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | |||
490 | int status = req->status; | 490 | int status = req->status; |
491 | 491 | ||
492 | switch (status) { | 492 | switch (status) { |
493 | case 0: /* normal completion */ | 493 | case 0: /* normal completion */ |
494 | if (ep == dev->out_ep) { | 494 | if (ep == dev->out_ep) { |
495 | /* we received stuff. | 495 | /* we received stuff. |
496 | req is queued again, below */ | 496 | req is queued again, below */ |
@@ -505,7 +505,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | |||
505 | break; | 505 | break; |
506 | 506 | ||
507 | /* this endpoint is normally active while we're configured */ | 507 | /* this endpoint is normally active while we're configured */ |
508 | case -ECONNABORTED: /* hardware forced ep reset */ | 508 | case -ECONNABORTED: /* hardware forced ep reset */ |
509 | case -ECONNRESET: /* request dequeued */ | 509 | case -ECONNRESET: /* request dequeued */ |
510 | case -ESHUTDOWN: /* disconnect from host */ | 510 | case -ESHUTDOWN: /* disconnect from host */ |
511 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, | 511 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, |
@@ -656,7 +656,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | |||
656 | case USB_SPEED_LOW: speed = "low"; break; | 656 | case USB_SPEED_LOW: speed = "low"; break; |
657 | case USB_SPEED_FULL: speed = "full"; break; | 657 | case USB_SPEED_FULL: speed = "full"; break; |
658 | case USB_SPEED_HIGH: speed = "high"; break; | 658 | case USB_SPEED_HIGH: speed = "high"; break; |
659 | default: speed = "?"; break; | 659 | default: speed = "?"; break; |
660 | } | 660 | } |
661 | 661 | ||
662 | dev->config = number; | 662 | dev->config = number; |
@@ -1308,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = { | |||
1308 | .speed = USB_SPEED_FULL, | 1308 | .speed = USB_SPEED_FULL, |
1309 | .function = (char *)longname, | 1309 | .function = (char *)longname, |
1310 | .bind = gmidi_bind, | 1310 | .bind = gmidi_bind, |
1311 | .unbind = __exit_p(gmidi_unbind), | 1311 | .unbind = gmidi_unbind, |
1312 | 1312 | ||
1313 | .setup = gmidi_setup, | 1313 | .setup = gmidi_setup, |
1314 | .disconnect = gmidi_disconnect, | 1314 | .disconnect = gmidi_disconnect, |
@@ -1316,7 +1316,7 @@ static struct usb_gadget_driver gmidi_driver = { | |||
1316 | .suspend = gmidi_suspend, | 1316 | .suspend = gmidi_suspend, |
1317 | .resume = gmidi_resume, | 1317 | .resume = gmidi_resume, |
1318 | 1318 | ||
1319 | .driver = { | 1319 | .driver = { |
1320 | .name = (char *)shortname, | 1320 | .name = (char *)shortname, |
1321 | .owner = THIS_MODULE, | 1321 | .owner = THIS_MODULE, |
1322 | }, | 1322 | }, |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 805a9826842d..d0ef1d6b3fac 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1432,7 +1432,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1432 | if (!driver | 1432 | if (!driver |
1433 | || driver->speed != USB_SPEED_FULL | 1433 | || driver->speed != USB_SPEED_FULL |
1434 | || !driver->bind | 1434 | || !driver->bind |
1435 | || !driver->unbind | ||
1436 | || !driver->disconnect | 1435 | || !driver->disconnect |
1437 | || !driver->setup) | 1436 | || !driver->setup) |
1438 | return -EINVAL; | 1437 | return -EINVAL; |
@@ -1495,7 +1494,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1495 | 1494 | ||
1496 | if (!dev) | 1495 | if (!dev) |
1497 | return -ENODEV; | 1496 | return -ENODEV; |
1498 | if (!driver || driver != dev->driver) | 1497 | if (!driver || driver != dev->driver || !driver->unbind) |
1499 | return -EINVAL; | 1498 | return -EINVAL; |
1500 | 1499 | ||
1501 | spin_lock_irqsave(&dev->lock, flags); | 1500 | spin_lock_irqsave(&dev->lock, flags); |
@@ -1808,13 +1807,8 @@ static void goku_remove(struct pci_dev *pdev) | |||
1808 | struct goku_udc *dev = pci_get_drvdata(pdev); | 1807 | struct goku_udc *dev = pci_get_drvdata(pdev); |
1809 | 1808 | ||
1810 | DBG(dev, "%s\n", __FUNCTION__); | 1809 | DBG(dev, "%s\n", __FUNCTION__); |
1811 | /* start with the driver above us */ | 1810 | |
1812 | if (dev->driver) { | 1811 | BUG_ON(dev->driver); |
1813 | /* should have been done already by driver model core */ | ||
1814 | WARN(dev, "pci remove, driver '%s' is still registered\n", | ||
1815 | dev->driver->driver.name); | ||
1816 | usb_gadget_unregister_driver(dev->driver); | ||
1817 | } | ||
1818 | 1812 | ||
1819 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 1813 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
1820 | remove_proc_entry(proc_node_name, NULL); | 1814 | remove_proc_entry(proc_node_name, NULL); |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 4a991564a03e..a0a73c08a344 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -422,9 +422,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
422 | DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); | 422 | DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); |
423 | 423 | ||
424 | if (!driver | 424 | if (!driver |
425 | || driver->speed != USB_SPEED_FULL | 425 | || driver->speed != USB_SPEED_FULL |
426 | || !driver->bind | 426 | || !driver->bind |
427 | || !driver->unbind || !driver->disconnect || !driver->setup) | 427 | || !driver->disconnect |
428 | || !driver->setup) | ||
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | if (!dev) | 430 | if (!dev) |
430 | return -ENODEV; | 431 | return -ENODEV; |
@@ -471,7 +472,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
471 | 472 | ||
472 | if (!dev) | 473 | if (!dev) |
473 | return -ENODEV; | 474 | return -ENODEV; |
474 | if (!driver || driver != dev->driver) | 475 | if (!driver || driver != dev->driver || !driver->unbind) |
475 | return -EINVAL; | 476 | return -EINVAL; |
476 | 477 | ||
477 | spin_lock_irqsave(&dev->lock, flags); | 478 | spin_lock_irqsave(&dev->lock, flags); |
@@ -2125,9 +2126,11 @@ static int lh7a40x_udc_remove(struct platform_device *pdev) | |||
2125 | 2126 | ||
2126 | DEBUG("%s: %p\n", __FUNCTION__, pdev); | 2127 | DEBUG("%s: %p\n", __FUNCTION__, pdev); |
2127 | 2128 | ||
2129 | if (dev->driver) | ||
2130 | return -EBUSY; | ||
2131 | |||
2128 | udc_disable(dev); | 2132 | udc_disable(dev); |
2129 | remove_proc_files(); | 2133 | remove_proc_files(); |
2130 | usb_gadget_unregister_driver(dev->driver); | ||
2131 | 2134 | ||
2132 | free_irq(IRQ_USBINTR, dev); | 2135 | free_irq(IRQ_USBINTR, dev); |
2133 | 2136 | ||
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 3024c679e38e..569eb8ccf232 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -2020,7 +2020,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2020 | if (!driver | 2020 | if (!driver |
2021 | || driver->speed != USB_SPEED_HIGH | 2021 | || driver->speed != USB_SPEED_HIGH |
2022 | || !driver->bind | 2022 | || !driver->bind |
2023 | || !driver->unbind | ||
2024 | || !driver->setup) | 2023 | || !driver->setup) |
2025 | return -EINVAL; | 2024 | return -EINVAL; |
2026 | if (!dev) | 2025 | if (!dev) |
@@ -2107,7 +2106,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2107 | 2106 | ||
2108 | if (!dev) | 2107 | if (!dev) |
2109 | return -ENODEV; | 2108 | return -ENODEV; |
2110 | if (!driver || driver != dev->driver) | 2109 | if (!driver || driver != dev->driver || !driver->unbind) |
2111 | return -EINVAL; | 2110 | return -EINVAL; |
2112 | 2111 | ||
2113 | spin_lock_irqsave (&dev->lock, flags); | 2112 | spin_lock_irqsave (&dev->lock, flags); |
@@ -2803,13 +2802,7 @@ static void net2280_remove (struct pci_dev *pdev) | |||
2803 | { | 2802 | { |
2804 | struct net2280 *dev = pci_get_drvdata (pdev); | 2803 | struct net2280 *dev = pci_get_drvdata (pdev); |
2805 | 2804 | ||
2806 | /* start with the driver above us */ | 2805 | BUG_ON(dev->driver); |
2807 | if (dev->driver) { | ||
2808 | /* should have been done already by driver model core */ | ||
2809 | WARN (dev, "pci remove, driver '%s' is still registered\n", | ||
2810 | dev->driver->driver.name); | ||
2811 | usb_gadget_unregister_driver (dev->driver); | ||
2812 | } | ||
2813 | 2806 | ||
2814 | /* then clean up the resources we allocated during probe() */ | 2807 | /* then clean up the resources we allocated during probe() */ |
2815 | net2280_led_shutdown (dev); | 2808 | net2280_led_shutdown (dev); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 030d87c28c2f..15d77c307930 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -2043,7 +2043,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2043 | // FIXME if otg, check: driver->is_otg | 2043 | // FIXME if otg, check: driver->is_otg |
2044 | || driver->speed < USB_SPEED_FULL | 2044 | || driver->speed < USB_SPEED_FULL |
2045 | || !driver->bind | 2045 | || !driver->bind |
2046 | || !driver->unbind | ||
2047 | || !driver->setup) | 2046 | || !driver->setup) |
2048 | return -EINVAL; | 2047 | return -EINVAL; |
2049 | 2048 | ||
@@ -2087,9 +2086,11 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2087 | status = otg_set_peripheral(udc->transceiver, &udc->gadget); | 2086 | status = otg_set_peripheral(udc->transceiver, &udc->gadget); |
2088 | if (status < 0) { | 2087 | if (status < 0) { |
2089 | ERR("can't bind to transceiver\n"); | 2088 | ERR("can't bind to transceiver\n"); |
2090 | driver->unbind (&udc->gadget); | 2089 | if (driver->unbind) { |
2091 | udc->gadget.dev.driver = NULL; | 2090 | driver->unbind (&udc->gadget); |
2092 | udc->driver = NULL; | 2091 | udc->gadget.dev.driver = NULL; |
2092 | udc->driver = NULL; | ||
2093 | } | ||
2093 | goto done; | 2094 | goto done; |
2094 | } | 2095 | } |
2095 | } else { | 2096 | } else { |
@@ -2117,7 +2118,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2117 | 2118 | ||
2118 | if (!udc) | 2119 | if (!udc) |
2119 | return -ENODEV; | 2120 | return -ENODEV; |
2120 | if (!driver || driver != udc->driver) | 2121 | if (!driver || driver != udc->driver || !driver->unbind) |
2121 | return -EINVAL; | 2122 | return -EINVAL; |
2122 | 2123 | ||
2123 | if (machine_is_omap_innovator() || machine_is_omap_osk()) | 2124 | if (machine_is_omap_innovator() || machine_is_omap_osk()) |
@@ -2870,6 +2871,8 @@ static int __exit omap_udc_remove(struct platform_device *pdev) | |||
2870 | 2871 | ||
2871 | if (!udc) | 2872 | if (!udc) |
2872 | return -ENODEV; | 2873 | return -ENODEV; |
2874 | if (udc->driver) | ||
2875 | return -EBUSY; | ||
2873 | 2876 | ||
2874 | udc->done = &done; | 2877 | udc->done = &done; |
2875 | 2878 | ||
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 1ed506e95985..b78de9694665 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -1623,7 +1623,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1623 | if (!driver | 1623 | if (!driver |
1624 | || driver->speed < USB_SPEED_FULL | 1624 | || driver->speed < USB_SPEED_FULL |
1625 | || !driver->bind | 1625 | || !driver->bind |
1626 | || !driver->unbind | ||
1627 | || !driver->disconnect | 1626 | || !driver->disconnect |
1628 | || !driver->setup) | 1627 | || !driver->setup) |
1629 | return -EINVAL; | 1628 | return -EINVAL; |
@@ -1694,7 +1693,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1694 | 1693 | ||
1695 | if (!dev) | 1694 | if (!dev) |
1696 | return -ENODEV; | 1695 | return -ENODEV; |
1697 | if (!driver || driver != dev->driver) | 1696 | if (!driver || driver != dev->driver || !driver->unbind) |
1698 | return -EINVAL; | 1697 | return -EINVAL; |
1699 | 1698 | ||
1700 | local_irq_disable(); | 1699 | local_irq_disable(); |
@@ -2638,9 +2637,11 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
2638 | { | 2637 | { |
2639 | struct pxa2xx_udc *dev = platform_get_drvdata(pdev); | 2638 | struct pxa2xx_udc *dev = platform_get_drvdata(pdev); |
2640 | 2639 | ||
2640 | if (dev->driver) | ||
2641 | return -EBUSY; | ||
2642 | |||
2641 | udc_disable(dev); | 2643 | udc_disable(dev); |
2642 | remove_proc_files(); | 2644 | remove_proc_files(); |
2643 | usb_gadget_unregister_driver(dev->driver); | ||
2644 | 2645 | ||
2645 | if (dev->got_irq) { | 2646 | if (dev->got_irq) { |
2646 | free_irq(IRQ_USB, dev); | 2647 | free_irq(IRQ_USB, dev); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 2d12bf9f19d6..f8a3ec64635d 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -296,7 +296,7 @@ static struct usb_gadget_driver gs_gadget_driver = { | |||
296 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 296 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
297 | .function = GS_LONG_NAME, | 297 | .function = GS_LONG_NAME, |
298 | .bind = gs_bind, | 298 | .bind = gs_bind, |
299 | .unbind = __exit_p(gs_unbind), | 299 | .unbind = gs_unbind, |
300 | .setup = gs_setup, | 300 | .setup = gs_setup, |
301 | .disconnect = gs_disconnect, | 301 | .disconnect = gs_disconnect, |
302 | .driver = { | 302 | .driver = { |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index b466581beb4a..cc405512fa1c 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -187,7 +187,6 @@ ohci_at91_start (struct usb_hcd *hcd) | |||
187 | { | 187 | { |
188 | struct at91_usbh_data *board = hcd->self.controller->platform_data; | 188 | struct at91_usbh_data *board = hcd->self.controller->platform_data; |
189 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 189 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
190 | struct usb_device *root = hcd->self.root_hub; | ||
191 | int ret; | 190 | int ret; |
192 | 191 | ||
193 | if ((ret = ohci_init(ohci)) < 0) | 192 | if ((ret = ohci_init(ohci)) < 0) |
@@ -221,7 +220,7 @@ static const struct hc_driver ohci_at91_hc_driver = { | |||
221 | */ | 220 | */ |
222 | .start = ohci_at91_start, | 221 | .start = ohci_at91_start, |
223 | .stop = ohci_stop, | 222 | .stop = ohci_stop, |
224 | .shutdown = ohci_shutdown, | 223 | .shutdown = ohci_shutdown, |
225 | 224 | ||
226 | /* | 225 | /* |
227 | * managing i/o requests and associated device resources | 226 | * managing i/o requests and associated device resources |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 24e23c5783d8..e70b2430e2a9 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -269,7 +269,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
269 | */ | 269 | */ |
270 | .start = ohci_au1xxx_start, | 270 | .start = ohci_au1xxx_start, |
271 | .stop = ohci_stop, | 271 | .stop = ohci_stop, |
272 | .shutdown = ohci_shutdown, | 272 | .shutdown = ohci_shutdown, |
273 | 273 | ||
274 | /* | 274 | /* |
275 | * managing i/o requests and associated device resources | 275 | * managing i/o requests and associated device resources |
@@ -336,7 +336,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct platform_device *dev) | |||
336 | static struct platform_driver ohci_hcd_au1xxx_driver = { | 336 | static struct platform_driver ohci_hcd_au1xxx_driver = { |
337 | .probe = ohci_hcd_au1xxx_drv_probe, | 337 | .probe = ohci_hcd_au1xxx_drv_probe, |
338 | .remove = ohci_hcd_au1xxx_drv_remove, | 338 | .remove = ohci_hcd_au1xxx_drv_remove, |
339 | .shutdown = usb_hcd_platform_shutdown, | 339 | .shutdown = usb_hcd_platform_shutdown, |
340 | /*.suspend = ohci_hcd_au1xxx_drv_suspend, */ | 340 | /*.suspend = ohci_hcd_au1xxx_drv_suspend, */ |
341 | /*.resume = ohci_hcd_au1xxx_drv_resume, */ | 341 | /*.resume = ohci_hcd_au1xxx_drv_resume, */ |
342 | .driver = { | 342 | .driver = { |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 0f47a57dac28..273d5ddb72be 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -16,7 +16,7 @@ | |||
16 | case PIPE_CONTROL: temp = "ctrl"; break; \ | 16 | case PIPE_CONTROL: temp = "ctrl"; break; \ |
17 | case PIPE_BULK: temp = "bulk"; break; \ | 17 | case PIPE_BULK: temp = "bulk"; break; \ |
18 | case PIPE_INTERRUPT: temp = "intr"; break; \ | 18 | case PIPE_INTERRUPT: temp = "intr"; break; \ |
19 | default: temp = "isoc"; break; \ | 19 | default: temp = "isoc"; break; \ |
20 | }; temp;}) | 20 | }; temp;}) |
21 | #define pipestring(pipe) edstring(usb_pipetype(pipe)) | 21 | #define pipestring(pipe) edstring(usb_pipetype(pipe)) |
22 | 22 | ||
@@ -205,13 +205,13 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | |||
205 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ | 205 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ |
206 | (temp & RH_PS_PESC) ? " PESC" : "", \ | 206 | (temp & RH_PS_PESC) ? " PESC" : "", \ |
207 | (temp & RH_PS_CSC) ? " CSC" : "", \ | 207 | (temp & RH_PS_CSC) ? " CSC" : "", \ |
208 | \ | 208 | \ |
209 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ | 209 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ |
210 | (temp & RH_PS_PPS) ? " PPS" : "", \ | 210 | (temp & RH_PS_PPS) ? " PPS" : "", \ |
211 | (temp & RH_PS_PRS) ? " PRS" : "", \ | 211 | (temp & RH_PS_PRS) ? " PRS" : "", \ |
212 | (temp & RH_PS_POCI) ? " POCI" : "", \ | 212 | (temp & RH_PS_POCI) ? " POCI" : "", \ |
213 | (temp & RH_PS_PSS) ? " PSS" : "", \ | 213 | (temp & RH_PS_PSS) ? " PSS" : "", \ |
214 | \ | 214 | \ |
215 | (temp & RH_PS_PES) ? " PES" : "", \ | 215 | (temp & RH_PS_PES) ? " PES" : "", \ |
216 | (temp & RH_PS_CCS) ? " CCS" : "" \ | 216 | (temp & RH_PS_CCS) ? " CCS" : "" \ |
217 | ); | 217 | ); |
@@ -563,7 +563,7 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
563 | (info & ED_SKIP) ? " K" : "", | 563 | (info & ED_SKIP) ? " K" : "", |
564 | (ed->hwHeadP & | 564 | (ed->hwHeadP & |
565 | cpu_to_hc32(ohci, ED_H)) ? | 565 | cpu_to_hc32(ohci, ED_H)) ? |
566 | " H" : ""); | 566 | " H" : ""); |
567 | size -= temp; | 567 | size -= temp; |
568 | next += temp; | 568 | next += temp; |
569 | 569 | ||
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 1bf5e7a4e735..43ae696b2ec2 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -204,7 +204,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) | |||
204 | static struct platform_driver ohci_hcd_ep93xx_driver = { | 204 | static struct platform_driver ohci_hcd_ep93xx_driver = { |
205 | .probe = ohci_hcd_ep93xx_drv_probe, | 205 | .probe = ohci_hcd_ep93xx_drv_probe, |
206 | .remove = ohci_hcd_ep93xx_drv_remove, | 206 | .remove = ohci_hcd_ep93xx_drv_remove, |
207 | .shutdown = usb_hcd_platform_shutdown, | 207 | .shutdown = usb_hcd_platform_shutdown, |
208 | #ifdef CONFIG_PM | 208 | #ifdef CONFIG_PM |
209 | .suspend = ohci_hcd_ep93xx_drv_suspend, | 209 | .suspend = ohci_hcd_ep93xx_drv_suspend, |
210 | .resume = ohci_hcd_ep93xx_drv_resume, | 210 | .resume = ohci_hcd_ep93xx_drv_resume, |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b28a9b602066..c1c1d871aba4 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -3,77 +3,21 @@ | |||
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * [ Initialisation is based on Linus' ] | 7 | * [ Initialisation is based on Linus' ] |
8 | * [ uhci code and gregs ohci fragments ] | 8 | * [ uhci code and gregs ohci fragments ] |
9 | * [ (C) Copyright 1999 Linus Torvalds ] | 9 | * [ (C) Copyright 1999 Linus Torvalds ] |
10 | * [ (C) Copyright 1999 Gregory P. Smith] | 10 | * [ (C) Copyright 1999 Gregory P. Smith] |
11 | * | 11 | * |
12 | * | 12 | * |
13 | * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller | 13 | * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller |
14 | * interfaces (though some non-x86 Intel chips use it). It supports | 14 | * interfaces (though some non-x86 Intel chips use it). It supports |
15 | * smarter hardware than UHCI. A download link for the spec available | 15 | * smarter hardware than UHCI. A download link for the spec available |
16 | * through the http://www.usb.org website. | 16 | * through the http://www.usb.org website. |
17 | * | 17 | * |
18 | * History: | ||
19 | * | ||
20 | * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer) | ||
21 | * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net) | ||
22 | * 2003/02/24 show registers in sysfs (Kevin Brosius) | ||
23 | * | ||
24 | * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and | ||
25 | * bandwidth accounting; if debugging, show schedules in driverfs | ||
26 | * 2002/07/19 fixes to management of ED and schedule state. | ||
27 | * 2002/06/09 SA-1111 support (Christopher Hoover) | ||
28 | * 2002/06/01 remember frame when HC won't see EDs any more; use that info | ||
29 | * to fix urb unlink races caused by interrupt latency assumptions; | ||
30 | * minor ED field and function naming updates | ||
31 | * 2002/01/18 package as a patch for 2.5.3; this should match the | ||
32 | * 2.4.17 kernel modulo some bugs being fixed. | ||
33 | * | ||
34 | * 2001/10/18 merge pmac cleanup (Benjamin Herrenschmidt) and bugfixes | ||
35 | * from post-2.4.5 patches. | ||
36 | * 2001/09/20 URB_ZERO_PACKET support; hcca_dma portability, OPTi warning | ||
37 | * 2001/09/07 match PCI PM changes, errnos from Linus' tree | ||
38 | * 2001/05/05 fork 2.4.5 version into "hcd" framework, cleanup, simplify; | ||
39 | * pbook pci quirks gone (please fix pbook pci sw!) (db) | ||
40 | * | ||
41 | * 2001/04/08 Identify version on module load (gb) | ||
42 | * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam); | ||
43 | pci_map_single (db) | ||
44 | * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db) | ||
45 | * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam) | ||
46 | * | ||
47 | * 2000/09/26 fixed races in removing the private portion of the urb | ||
48 | * 2000/09/07 disable bulk and control lists when unlinking the last | ||
49 | * endpoint descriptor in order to avoid unrecoverable errors on | ||
50 | * the Lucent chips. (rwc@sgi) | ||
51 | * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some | ||
52 | * urb unlink probs, indentation fixes | ||
53 | * 2000/08/11 various oops fixes mostly affecting iso and cleanup from | ||
54 | * device unplugs. | ||
55 | * 2000/06/28 use PCI hotplug framework, for better power management | ||
56 | * and for Cardbus support (David Brownell) | ||
57 | * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling | ||
58 | * when the controller loses power; handle UE; cleanup; ... | ||
59 | * | ||
60 | * v5.2 1999/12/07 URB 3rd preview, | ||
61 | * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi) | ||
62 | * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume | ||
63 | * i386: HUB, Keyboard, Mouse, Printer | ||
64 | * | ||
65 | * v4.3 1999/10/27 multiple HCs, bulk_request | ||
66 | * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes | ||
67 | * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. | ||
68 | * v4.0 1999/08/18 | ||
69 | * v3.0 1999/06/25 | ||
70 | * v2.1 1999/05/09 code clean up | ||
71 | * v2.0 1999/05/04 | ||
72 | * v1.0 1999/04/27 initial release | ||
73 | * | ||
74 | * This file is licenced under the GPL. | 18 | * This file is licenced under the GPL. |
75 | */ | 19 | */ |
76 | 20 | ||
77 | #include <linux/module.h> | 21 | #include <linux/module.h> |
78 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
79 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
@@ -89,7 +33,7 @@ | |||
89 | #include <linux/list.h> | 33 | #include <linux/list.h> |
90 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
91 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
92 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
93 | #include <linux/dmapool.h> | 37 | #include <linux/dmapool.h> |
94 | #include <linux/reboot.h> | 38 | #include <linux/reboot.h> |
95 | 39 | ||
@@ -183,11 +127,11 @@ static int ohci_urb_enqueue ( | |||
183 | int i, size = 0; | 127 | int i, size = 0; |
184 | unsigned long flags; | 128 | unsigned long flags; |
185 | int retval = 0; | 129 | int retval = 0; |
186 | 130 | ||
187 | #ifdef OHCI_VERBOSE_DEBUG | 131 | #ifdef OHCI_VERBOSE_DEBUG |
188 | urb_print (urb, "SUB", usb_pipein (pipe)); | 132 | urb_print (urb, "SUB", usb_pipein (pipe)); |
189 | #endif | 133 | #endif |
190 | 134 | ||
191 | /* every endpoint has a ed, locate and maybe (re)initialize it */ | 135 | /* every endpoint has a ed, locate and maybe (re)initialize it */ |
192 | if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) | 136 | if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) |
193 | return -ENOMEM; | 137 | return -ENOMEM; |
@@ -232,7 +176,7 @@ static int ohci_urb_enqueue ( | |||
232 | memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); | 176 | memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); |
233 | INIT_LIST_HEAD (&urb_priv->pending); | 177 | INIT_LIST_HEAD (&urb_priv->pending); |
234 | urb_priv->length = size; | 178 | urb_priv->length = size; |
235 | urb_priv->ed = ed; | 179 | urb_priv->ed = ed; |
236 | 180 | ||
237 | /* allocate the TDs (deferring hash chain updates) */ | 181 | /* allocate the TDs (deferring hash chain updates) */ |
238 | for (i = 0; i < size; i++) { | 182 | for (i = 0; i < size; i++) { |
@@ -242,7 +186,7 @@ static int ohci_urb_enqueue ( | |||
242 | urb_free_priv (ohci, urb_priv); | 186 | urb_free_priv (ohci, urb_priv); |
243 | return -ENOMEM; | 187 | return -ENOMEM; |
244 | } | 188 | } |
245 | } | 189 | } |
246 | 190 | ||
247 | spin_lock_irqsave (&ohci->lock, flags); | 191 | spin_lock_irqsave (&ohci->lock, flags); |
248 | 192 | ||
@@ -313,13 +257,13 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
313 | { | 257 | { |
314 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 258 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
315 | unsigned long flags; | 259 | unsigned long flags; |
316 | 260 | ||
317 | #ifdef OHCI_VERBOSE_DEBUG | 261 | #ifdef OHCI_VERBOSE_DEBUG |
318 | urb_print (urb, "UNLINK", 1); | 262 | urb_print (urb, "UNLINK", 1); |
319 | #endif | 263 | #endif |
320 | 264 | ||
321 | spin_lock_irqsave (&ohci->lock, flags); | 265 | spin_lock_irqsave (&ohci->lock, flags); |
322 | if (HC_IS_RUNNING(hcd->state)) { | 266 | if (HC_IS_RUNNING(hcd->state)) { |
323 | urb_priv_t *urb_priv; | 267 | urb_priv_t *urb_priv; |
324 | 268 | ||
325 | /* Unless an IRQ completed the unlink while it was being | 269 | /* Unless an IRQ completed the unlink while it was being |
@@ -512,11 +456,11 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
512 | 456 | ||
513 | /* Start an OHCI controller, set the BUS operational | 457 | /* Start an OHCI controller, set the BUS operational |
514 | * resets USB and controller | 458 | * resets USB and controller |
515 | * enable interrupts | 459 | * enable interrupts |
516 | */ | 460 | */ |
517 | static int ohci_run (struct ohci_hcd *ohci) | 461 | static int ohci_run (struct ohci_hcd *ohci) |
518 | { | 462 | { |
519 | u32 mask, temp; | 463 | u32 mask, temp; |
520 | int first = ohci->fminterval == 0; | 464 | int first = ohci->fminterval == 0; |
521 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | 465 | struct usb_hcd *hcd = ohci_to_hcd(ohci); |
522 | 466 | ||
@@ -534,7 +478,7 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
534 | /* also: power/overcurrent flags in roothub.a */ | 478 | /* also: power/overcurrent flags in roothub.a */ |
535 | } | 479 | } |
536 | 480 | ||
537 | /* Reset USB nearly "by the book". RemoteWakeupConnected was | 481 | /* Reset USB nearly "by the book". RemoteWakeupConnected was |
538 | * saved if boot firmware (BIOS/SMM/...) told us it's connected, | 482 | * saved if boot firmware (BIOS/SMM/...) told us it's connected, |
539 | * or if bus glue did the same (e.g. for PCI add-in cards with | 483 | * or if bus glue did the same (e.g. for PCI add-in cards with |
540 | * PCI PM support). | 484 | * PCI PM support). |
@@ -765,9 +709,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
765 | dl_done_list (ohci); | 709 | dl_done_list (ohci); |
766 | spin_unlock (&ohci->lock); | 710 | spin_unlock (&ohci->lock); |
767 | if (HC_IS_RUNNING(hcd->state)) | 711 | if (HC_IS_RUNNING(hcd->state)) |
768 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); | 712 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); |
769 | } | 713 | } |
770 | 714 | ||
771 | /* could track INTR_SO to reduce available PCI/... bandwidth */ | 715 | /* could track INTR_SO to reduce available PCI/... bandwidth */ |
772 | 716 | ||
773 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled | 717 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled |
@@ -778,12 +722,12 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
778 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 722 | finish_unlinks (ohci, ohci_frame_no(ohci)); |
779 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list | 723 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list |
780 | && HC_IS_RUNNING(hcd->state)) | 724 | && HC_IS_RUNNING(hcd->state)) |
781 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 725 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
782 | spin_unlock (&ohci->lock); | 726 | spin_unlock (&ohci->lock); |
783 | 727 | ||
784 | if (HC_IS_RUNNING(hcd->state)) { | 728 | if (HC_IS_RUNNING(hcd->state)) { |
785 | ohci_writel (ohci, ints, ®s->intrstatus); | 729 | ohci_writel (ohci, ints, ®s->intrstatus); |
786 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); | 730 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); |
787 | // flush those writes | 731 | // flush those writes |
788 | (void) ohci_readl (ohci, &ohci->regs->control); | 732 | (void) ohci_readl (ohci, &ohci->regs->control); |
789 | } | 733 | } |
@@ -794,7 +738,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
794 | /*-------------------------------------------------------------------------*/ | 738 | /*-------------------------------------------------------------------------*/ |
795 | 739 | ||
796 | static void ohci_stop (struct usb_hcd *hcd) | 740 | static void ohci_stop (struct usb_hcd *hcd) |
797 | { | 741 | { |
798 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 742 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
799 | 743 | ||
800 | ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n", | 744 | ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n", |
@@ -812,8 +756,8 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
812 | remove_debug_files (ohci); | 756 | remove_debug_files (ohci); |
813 | ohci_mem_cleanup (ohci); | 757 | ohci_mem_cleanup (ohci); |
814 | if (ohci->hcca) { | 758 | if (ohci->hcca) { |
815 | dma_free_coherent (hcd->self.controller, | 759 | dma_free_coherent (hcd->self.controller, |
816 | sizeof *ohci->hcca, | 760 | sizeof *ohci->hcca, |
817 | ohci->hcca, ohci->hcca_dma); | 761 | ohci->hcca, ohci->hcca_dma); |
818 | ohci->hcca = NULL; | 762 | ohci->hcca = NULL; |
819 | ohci->hcca_dma = 0; | 763 | ohci->hcca_dma = 0; |
@@ -836,7 +780,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
836 | * recycle any "live" eds/tds (and urbs) right away. | 780 | * recycle any "live" eds/tds (and urbs) right away. |
837 | * later, khubd disconnect processing will recycle the other state, | 781 | * later, khubd disconnect processing will recycle the other state, |
838 | * (either as disconnect/reconnect, or maybe someday as a reset). | 782 | * (either as disconnect/reconnect, or maybe someday as a reset). |
839 | */ | 783 | */ |
840 | spin_lock_irq(&ohci->lock); | 784 | spin_lock_irq(&ohci->lock); |
841 | disable (ohci); | 785 | disable (ohci); |
842 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); | 786 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); |
@@ -875,11 +819,11 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
875 | /* empty the interrupt branches */ | 819 | /* empty the interrupt branches */ |
876 | for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0; | 820 | for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0; |
877 | for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0; | 821 | for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0; |
878 | 822 | ||
879 | /* no EDs to remove */ | 823 | /* no EDs to remove */ |
880 | ohci->ed_rm_list = NULL; | 824 | ohci->ed_rm_list = NULL; |
881 | 825 | ||
882 | /* empty control and bulk lists */ | 826 | /* empty control and bulk lists */ |
883 | ohci->ed_controltail = NULL; | 827 | ohci->ed_controltail = NULL; |
884 | ohci->ed_bulktail = NULL; | 828 | ohci->ed_bulktail = NULL; |
885 | 829 | ||
@@ -941,6 +885,10 @@ MODULE_LICENSE ("GPL"); | |||
941 | #include "ohci-au1xxx.c" | 885 | #include "ohci-au1xxx.c" |
942 | #endif | 886 | #endif |
943 | 887 | ||
888 | #ifdef CONFIG_PNX8550 | ||
889 | #include "ohci-pnx8550.c" | ||
890 | #endif | ||
891 | |||
944 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC | 892 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC |
945 | #include "ohci-ppc-soc.c" | 893 | #include "ohci-ppc-soc.c" |
946 | #endif | 894 | #endif |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2441642cb7b4..216c9c9d4d6d 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under GPL | 7 | * This file is licenced under GPL |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -23,13 +23,13 @@ | |||
23 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ | 23 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ |
24 | (temp & RH_PS_PESC) ? " PESC" : "", \ | 24 | (temp & RH_PS_PESC) ? " PESC" : "", \ |
25 | (temp & RH_PS_CSC) ? " CSC" : "", \ | 25 | (temp & RH_PS_CSC) ? " CSC" : "", \ |
26 | \ | 26 | \ |
27 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ | 27 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ |
28 | (temp & RH_PS_PPS) ? " PPS" : "", \ | 28 | (temp & RH_PS_PPS) ? " PPS" : "", \ |
29 | (temp & RH_PS_PRS) ? " PRS" : "", \ | 29 | (temp & RH_PS_PRS) ? " PRS" : "", \ |
30 | (temp & RH_PS_POCI) ? " POCI" : "", \ | 30 | (temp & RH_PS_POCI) ? " POCI" : "", \ |
31 | (temp & RH_PS_PSS) ? " PSS" : "", \ | 31 | (temp & RH_PS_PSS) ? " PSS" : "", \ |
32 | \ | 32 | \ |
33 | (temp & RH_PS_PES) ? " PES" : "", \ | 33 | (temp & RH_PS_PES) ? " PES" : "", \ |
34 | (temp & RH_PS_CCS) ? " CCS" : "" \ | 34 | (temp & RH_PS_CCS) ? " CCS" : "" \ |
35 | ); | 35 | ); |
@@ -484,7 +484,7 @@ ohci_hub_descriptor ( | |||
484 | temp = 0; | 484 | temp = 0; |
485 | if (rh & RH_A_NPS) /* no power switching? */ | 485 | if (rh & RH_A_NPS) /* no power switching? */ |
486 | temp |= 0x0002; | 486 | temp |= 0x0002; |
487 | if (rh & RH_A_PSM) /* per-port power switching? */ | 487 | if (rh & RH_A_PSM) /* per-port power switching? */ |
488 | temp |= 0x0001; | 488 | temp |= 0x0001; |
489 | if (rh & RH_A_NOCP) /* no overcurrent reporting? */ | 489 | if (rh & RH_A_NOCP) /* no overcurrent reporting? */ |
490 | temp |= 0x0010; | 490 | temp |= 0x0010; |
@@ -555,7 +555,7 @@ static void start_hnp(struct ohci_hcd *ohci); | |||
555 | #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0) | 555 | #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0) |
556 | 556 | ||
557 | /* called from some task, normally khubd */ | 557 | /* called from some task, normally khubd */ |
558 | static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) | 558 | static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) |
559 | { | 559 | { |
560 | __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; | 560 | __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; |
561 | u32 temp; | 561 | u32 temp; |
@@ -570,10 +570,13 @@ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) | |||
570 | /* spin until any current reset finishes */ | 570 | /* spin until any current reset finishes */ |
571 | for (;;) { | 571 | for (;;) { |
572 | temp = ohci_readl (ohci, portstat); | 572 | temp = ohci_readl (ohci, portstat); |
573 | /* handle e.g. CardBus eject */ | ||
574 | if (temp == ~(u32)0) | ||
575 | return -ESHUTDOWN; | ||
573 | if (!(temp & RH_PS_PRS)) | 576 | if (!(temp & RH_PS_PRS)) |
574 | break; | 577 | break; |
575 | udelay (500); | 578 | udelay (500); |
576 | } | 579 | } |
577 | 580 | ||
578 | if (!(temp & RH_PS_CCS)) | 581 | if (!(temp & RH_PS_CCS)) |
579 | break; | 582 | break; |
@@ -586,6 +589,8 @@ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) | |||
586 | now = ohci_readl(ohci, &ohci->regs->fmnumber); | 589 | now = ohci_readl(ohci, &ohci->regs->fmnumber); |
587 | } while (tick_before(now, reset_done)); | 590 | } while (tick_before(now, reset_done)); |
588 | /* caller synchronizes using PRSC */ | 591 | /* caller synchronizes using PRSC */ |
592 | |||
593 | return 0; | ||
589 | } | 594 | } |
590 | 595 | ||
591 | static int ohci_hub_control ( | 596 | static int ohci_hub_control ( |
@@ -702,7 +707,7 @@ static int ohci_hub_control ( | |||
702 | &ohci->regs->roothub.portstatus [wIndex]); | 707 | &ohci->regs->roothub.portstatus [wIndex]); |
703 | break; | 708 | break; |
704 | case USB_PORT_FEAT_RESET: | 709 | case USB_PORT_FEAT_RESET: |
705 | root_port_reset (ohci, wIndex); | 710 | retval = root_port_reset (ohci, wIndex); |
706 | break; | 711 | break; |
707 | default: | 712 | default: |
708 | goto error; | 713 | goto error; |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index e121d97ed91c..e9807cf73a2f 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -38,7 +38,7 @@ static void lh7a404_start_hc(struct platform_device *dev) | |||
38 | CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */ | 38 | CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */ |
39 | udelay(1000); | 39 | udelay(1000); |
40 | USBH_CMDSTATUS = OHCI_HCR; | 40 | USBH_CMDSTATUS = OHCI_HCR; |
41 | 41 | ||
42 | printk(KERN_DEBUG __FILE__ | 42 | printk(KERN_DEBUG __FILE__ |
43 | ": Clock to USB host has been enabled \n"); | 43 | ": Clock to USB host has been enabled \n"); |
44 | } | 44 | } |
@@ -89,7 +89,7 @@ int usb_hcd_lh7a404_probe (const struct hc_driver *driver, | |||
89 | retval = -EBUSY; | 89 | retval = -EBUSY; |
90 | goto err1; | 90 | goto err1; |
91 | } | 91 | } |
92 | 92 | ||
93 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 93 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); |
94 | if (!hcd->regs) { | 94 | if (!hcd->regs) { |
95 | pr_debug("ioremap failed"); | 95 | pr_debug("ioremap failed"); |
@@ -174,7 +174,7 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { | |||
174 | */ | 174 | */ |
175 | .start = ohci_lh7a404_start, | 175 | .start = ohci_lh7a404_start, |
176 | .stop = ohci_stop, | 176 | .stop = ohci_stop, |
177 | .shutdown = ohci_shutdown, | 177 | .shutdown = ohci_shutdown, |
178 | 178 | ||
179 | /* | 179 | /* |
180 | * managing i/o requests and associated device resources | 180 | * managing i/o requests and associated device resources |
@@ -242,7 +242,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev) | |||
242 | static struct platform_driver ohci_hcd_lh7a404_driver = { | 242 | static struct platform_driver ohci_hcd_lh7a404_driver = { |
243 | .probe = ohci_hcd_lh7a404_drv_probe, | 243 | .probe = ohci_hcd_lh7a404_drv_probe, |
244 | .remove = ohci_hcd_lh7a404_drv_remove, | 244 | .remove = ohci_hcd_lh7a404_drv_remove, |
245 | .shutdown = usb_hcd_platform_shutdown, | 245 | .shutdown = usb_hcd_platform_shutdown, |
246 | /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ | 246 | /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ |
247 | /*.resume = ohci_hcd_lh7a404_drv_resume, */ | 247 | /*.resume = ohci_hcd_lh7a404_drv_resume, */ |
248 | .driver = { | 248 | .driver = { |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index d976614eebd3..2f20d3dc895b 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -1,24 +1,24 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under the GPL. | 7 | * This file is licenced under the GPL. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /*-------------------------------------------------------------------------*/ | 10 | /*-------------------------------------------------------------------------*/ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * There's basically three types of memory: | 13 | * OHCI deals with three types of memory: |
14 | * - data used only by the HCD ... kmalloc is fine | 14 | * - data used only by the HCD ... kmalloc is fine |
15 | * - async and periodic schedules, shared by HC and HCD ... these | 15 | * - async and periodic schedules, shared by HC and HCD ... these |
16 | * need to use dma_pool or dma_alloc_coherent | 16 | * need to use dma_pool or dma_alloc_coherent |
17 | * - driver buffers, read/written by HC ... the hcd glue or the | 17 | * - driver buffers, read/written by HC ... the hcd glue or the |
18 | * device driver provides us with dma addresses | 18 | * device driver provides us with dma addresses |
19 | * | 19 | * |
20 | * There's also PCI "register" data, which is memory mapped. | 20 | * There's also "register" data, which is memory mapped. |
21 | * No memory seen by this driver is pagable. | 21 | * No memory seen by this driver (or any HCD) may be paged out. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /*-------------------------------------------------------------------------*/ | 24 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 9c02177de50a..27be1f936885 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -447,7 +447,7 @@ static const struct hc_driver ohci_omap_hc_driver = { | |||
447 | .reset = ohci_omap_init, | 447 | .reset = ohci_omap_init, |
448 | .start = ohci_omap_start, | 448 | .start = ohci_omap_start, |
449 | .stop = ohci_omap_stop, | 449 | .stop = ohci_omap_stop, |
450 | .shutdown = ohci_shutdown, | 450 | .shutdown = ohci_shutdown, |
451 | 451 | ||
452 | /* | 452 | /* |
453 | * managing i/o requests and associated device resources | 453 | * managing i/o requests and associated device resources |
@@ -533,7 +533,7 @@ static int ohci_omap_resume(struct platform_device *dev) | |||
533 | static struct platform_driver ohci_hcd_omap_driver = { | 533 | static struct platform_driver ohci_hcd_omap_driver = { |
534 | .probe = ohci_hcd_omap_drv_probe, | 534 | .probe = ohci_hcd_omap_drv_probe, |
535 | .remove = ohci_hcd_omap_drv_remove, | 535 | .remove = ohci_hcd_omap_drv_remove, |
536 | .shutdown = usb_hcd_platform_shutdown, | 536 | .shutdown = usb_hcd_platform_shutdown, |
537 | #ifdef CONFIG_PM | 537 | #ifdef CONFIG_PM |
538 | .suspend = ohci_omap_suspend, | 538 | .suspend = ohci_omap_suspend, |
539 | .resume = ohci_omap_resume, | 539 | .resume = ohci_omap_resume, |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 874418552789..596e0b41e606 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -3,17 +3,17 @@ | |||
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * [ Initialisation is based on Linus' ] | 7 | * [ Initialisation is based on Linus' ] |
8 | * [ uhci code and gregs ohci fragments ] | 8 | * [ uhci code and gregs ohci fragments ] |
9 | * [ (C) Copyright 1999 Linus Torvalds ] | 9 | * [ (C) Copyright 1999 Linus Torvalds ] |
10 | * [ (C) Copyright 1999 Gregory P. Smith] | 10 | * [ (C) Copyright 1999 Gregory P. Smith] |
11 | * | 11 | * |
12 | * PCI Bus Glue | 12 | * PCI Bus Glue |
13 | * | 13 | * |
14 | * This file is licenced under the GPL. | 14 | * This file is licenced under the GPL. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifndef CONFIG_PCI | 17 | #ifndef CONFIG_PCI |
18 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | 18 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." |
19 | #endif | 19 | #endif |
@@ -83,7 +83,7 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
83 | pci_dev_put(b); | 83 | pci_dev_put(b); |
84 | } | 84 | } |
85 | 85 | ||
86 | /* Check for Compaq's ZFMicro chipset, which needs short | 86 | /* Check for Compaq's ZFMicro chipset, which needs short |
87 | * delays before control or bulk queues get re-activated | 87 | * delays before control or bulk queues get re-activated |
88 | * in finish_unlinks() | 88 | * in finish_unlinks() |
89 | */ | 89 | */ |
@@ -238,8 +238,8 @@ static struct pci_driver ohci_pci_driver = { | |||
238 | .shutdown = usb_hcd_pci_shutdown, | 238 | .shutdown = usb_hcd_pci_shutdown, |
239 | }; | 239 | }; |
240 | 240 | ||
241 | 241 | ||
242 | static int __init ohci_hcd_pci_init (void) | 242 | static int __init ohci_hcd_pci_init (void) |
243 | { | 243 | { |
244 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); | 244 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); |
245 | if (usb_disabled()) | 245 | if (usb_disabled()) |
@@ -253,8 +253,8 @@ module_init (ohci_hcd_pci_init); | |||
253 | 253 | ||
254 | /*-------------------------------------------------------------------------*/ | 254 | /*-------------------------------------------------------------------------*/ |
255 | 255 | ||
256 | static void __exit ohci_hcd_pci_cleanup (void) | 256 | static void __exit ohci_hcd_pci_cleanup (void) |
257 | { | 257 | { |
258 | pci_unregister_driver (&ohci_pci_driver); | 258 | pci_unregister_driver (&ohci_pci_driver); |
259 | } | 259 | } |
260 | module_exit (ohci_hcd_pci_cleanup); | 260 | module_exit (ohci_hcd_pci_cleanup); |
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 7f26f9bdbaf1..3a8cbfb69054 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * driver for Philips PNX4008 USB Host | 4 | * driver for Philips PNX4008 USB Host |
5 | * | 5 | * |
6 | * Authors: Dmitry Chigirev <source@mvista.com> | 6 | * Authors: Dmitry Chigirev <source@mvista.com> |
7 | * Vitaly Wool <vitalywool@gmail.com> | 7 | * Vitaly Wool <vitalywool@gmail.com> |
8 | * | 8 | * |
9 | * register initialization is based on code examples provided by Philips | 9 | * register initialization is based on code examples provided by Philips |
10 | * Copyright (c) 2005 Koninklijke Philips Electronics N.V. | 10 | * Copyright (c) 2005 Koninklijke Philips Electronics N.V. |
@@ -29,7 +29,7 @@ | |||
29 | #include <asm/arch/irqs.h> | 29 | #include <asm/arch/irqs.h> |
30 | #include <asm/arch/gpio.h> | 30 | #include <asm/arch/gpio.h> |
31 | 31 | ||
32 | #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) | 32 | #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) |
33 | 33 | ||
34 | /* USB_CTRL bit defines */ | 34 | /* USB_CTRL bit defines */ |
35 | #define USB_SLAVE_HCLK_EN (1 << 24) | 35 | #define USB_SLAVE_HCLK_EN (1 << 24) |
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c new file mode 100644 index 000000000000..6922b91b1704 --- /dev/null +++ b/drivers/usb/host/ohci-pnx8550.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2005 Embedded Alley Solutions, Inc. | ||
8 | * | ||
9 | * Bus Glue for PNX8550 | ||
10 | * | ||
11 | * Written by Christopher Hoover <ch@hpl.hp.com> | ||
12 | * Based on fragments of previous driver by Russell King et al. | ||
13 | * | ||
14 | * Modified for LH7A404 from ohci-sa1111.c | ||
15 | * by Durgesh Pattamatta <pattamattad@sharpsec.com> | ||
16 | * | ||
17 | * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c | ||
18 | * by Vitaly Wool <vitalywool@gmail.com> | ||
19 | * | ||
20 | * This file is licenced under the GPL. | ||
21 | */ | ||
22 | |||
23 | #include <linux/device.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <asm/mach-pnx8550/usb.h> | ||
26 | #include <asm/mach-pnx8550/int.h> | ||
27 | #include <asm/mach-pnx8550/pci.h> | ||
28 | |||
29 | #ifndef CONFIG_PNX8550 | ||
30 | #error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined." | ||
31 | #endif | ||
32 | |||
33 | extern int usb_disabled(void); | ||
34 | |||
35 | /*-------------------------------------------------------------------------*/ | ||
36 | |||
37 | static void pnx8550_start_hc(struct platform_device *dev) | ||
38 | { | ||
39 | /* | ||
40 | * Set register CLK48CTL to enable and 48MHz | ||
41 | */ | ||
42 | outl(0x00000003, PCI_BASE | 0x0004770c); | ||
43 | |||
44 | /* | ||
45 | * Set register CLK12CTL to enable and 48MHz | ||
46 | */ | ||
47 | outl(0x00000003, PCI_BASE | 0x00047710); | ||
48 | |||
49 | udelay(100); | ||
50 | } | ||
51 | |||
52 | static void pnx8550_stop_hc(struct platform_device *dev) | ||
53 | { | ||
54 | udelay(10); | ||
55 | } | ||
56 | |||
57 | |||
58 | /*-------------------------------------------------------------------------*/ | ||
59 | |||
60 | /* configure so an HC device and id are always provided */ | ||
61 | /* always called with process context; sleeping is OK */ | ||
62 | |||
63 | |||
64 | /** | ||
65 | * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs | ||
66 | * Context: !in_interrupt() | ||
67 | * | ||
68 | * Allocates basic resources for this USB host controller, and | ||
69 | * then invokes the start() method for the HCD associated with it | ||
70 | * through the hotplug entry's driver_data. | ||
71 | * | ||
72 | */ | ||
73 | int usb_hcd_pnx8550_probe (const struct hc_driver *driver, | ||
74 | struct platform_device *dev) | ||
75 | { | ||
76 | int retval; | ||
77 | struct usb_hcd *hcd; | ||
78 | |||
79 | if (dev->resource[0].flags != IORESOURCE_MEM || | ||
80 | dev->resource[1].flags != IORESOURCE_IRQ) { | ||
81 | dev_err (&dev->dev,"invalid resource type\n"); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | hcd = usb_create_hcd (driver, &dev->dev, "pnx8550"); | ||
86 | if (!hcd) | ||
87 | return -ENOMEM; | ||
88 | hcd->rsrc_start = dev->resource[0].start; | ||
89 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | ||
90 | |||
91 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
92 | dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] " | ||
93 | "failed\n", hcd->rsrc_start, hcd->rsrc_len); | ||
94 | retval = -EBUSY; | ||
95 | goto err1; | ||
96 | } | ||
97 | |||
98 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
99 | if (!hcd->regs) { | ||
100 | dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n", | ||
101 | hcd->rsrc_start, hcd->rsrc_len); | ||
102 | retval = -ENOMEM; | ||
103 | goto err2; | ||
104 | } | ||
105 | |||
106 | pnx8550_start_hc(dev); | ||
107 | |||
108 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
109 | |||
110 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | ||
111 | if (retval == 0) | ||
112 | return retval; | ||
113 | |||
114 | pnx8550_stop_hc(dev); | ||
115 | iounmap(hcd->regs); | ||
116 | err2: | ||
117 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
118 | err1: | ||
119 | usb_put_hcd(hcd); | ||
120 | return retval; | ||
121 | } | ||
122 | |||
123 | |||
124 | /* may be called without controller electrically present */ | ||
125 | /* may be called with controller, bus, and devices active */ | ||
126 | |||
127 | /** | ||
128 | * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs | ||
129 | * @dev: USB Host Controller being removed | ||
130 | * Context: !in_interrupt() | ||
131 | * | ||
132 | * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking | ||
133 | * the HCD's stop() method. It is always called from a thread | ||
134 | * context, normally "rmmod", "apmd", or something similar. | ||
135 | * | ||
136 | */ | ||
137 | void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev) | ||
138 | { | ||
139 | usb_remove_hcd(hcd); | ||
140 | pnx8550_stop_hc(dev); | ||
141 | iounmap(hcd->regs); | ||
142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
143 | usb_put_hcd(hcd); | ||
144 | } | ||
145 | |||
146 | /*-------------------------------------------------------------------------*/ | ||
147 | |||
148 | static int __devinit | ||
149 | ohci_pnx8550_start (struct usb_hcd *hcd) | ||
150 | { | ||
151 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
152 | int ret; | ||
153 | |||
154 | ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci); | ||
155 | |||
156 | if ((ret = ohci_init(ohci)) < 0) | ||
157 | return ret; | ||
158 | |||
159 | if ((ret = ohci_run (ohci)) < 0) { | ||
160 | err ("can't start %s", hcd->self.bus_name); | ||
161 | ohci_stop (hcd); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /*-------------------------------------------------------------------------*/ | ||
169 | |||
170 | static const struct hc_driver ohci_pnx8550_hc_driver = { | ||
171 | .description = hcd_name, | ||
172 | .product_desc = "PNX8550 OHCI", | ||
173 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
174 | |||
175 | /* | ||
176 | * generic hardware linkage | ||
177 | */ | ||
178 | .irq = ohci_irq, | ||
179 | .flags = HCD_USB11 | HCD_MEMORY, | ||
180 | |||
181 | /* | ||
182 | * basic lifecycle operations | ||
183 | */ | ||
184 | .start = ohci_pnx8550_start, | ||
185 | .stop = ohci_stop, | ||
186 | |||
187 | /* | ||
188 | * managing i/o requests and associated device resources | ||
189 | */ | ||
190 | .urb_enqueue = ohci_urb_enqueue, | ||
191 | .urb_dequeue = ohci_urb_dequeue, | ||
192 | .endpoint_disable = ohci_endpoint_disable, | ||
193 | |||
194 | /* | ||
195 | * scheduling support | ||
196 | */ | ||
197 | .get_frame_number = ohci_get_frame, | ||
198 | |||
199 | /* | ||
200 | * root hub support | ||
201 | */ | ||
202 | .hub_status_data = ohci_hub_status_data, | ||
203 | .hub_control = ohci_hub_control, | ||
204 | .hub_irq_enable = ohci_rhsc_enable, | ||
205 | #ifdef CONFIG_PM | ||
206 | .bus_suspend = ohci_bus_suspend, | ||
207 | .bus_resume = ohci_bus_resume, | ||
208 | #endif | ||
209 | .start_port_reset = ohci_start_port_reset, | ||
210 | }; | ||
211 | |||
212 | /*-------------------------------------------------------------------------*/ | ||
213 | |||
214 | static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev) | ||
215 | { | ||
216 | int ret; | ||
217 | |||
218 | if (usb_disabled()) | ||
219 | return -ENODEV; | ||
220 | |||
221 | ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev) | ||
226 | { | ||
227 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
228 | |||
229 | usb_hcd_pnx8550_remove(hcd, pdev); | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | MODULE_ALIAS("pnx8550-ohci"); | ||
234 | |||
235 | static struct platform_driver ohci_hcd_pnx8550_driver = { | ||
236 | .driver = { | ||
237 | .name = "pnx8550-ohci", | ||
238 | }, | ||
239 | .probe = ohci_hcd_pnx8550_drv_probe, | ||
240 | .remove = ohci_hcd_pnx8550_drv_remove, | ||
241 | }; | ||
242 | |||
243 | static int __init ohci_hcd_pnx8550_init (void) | ||
244 | { | ||
245 | pr_debug (DRIVER_INFO " (pnx8550)"); | ||
246 | pr_debug ("block sizes: ed %d td %d\n", | ||
247 | sizeof (struct ed), sizeof (struct td)); | ||
248 | |||
249 | return platform_driver_register(&ohci_hcd_pnx8550_driver); | ||
250 | } | ||
251 | |||
252 | static void __exit ohci_hcd_pnx8550_cleanup (void) | ||
253 | { | ||
254 | platform_driver_unregister(&ohci_hcd_pnx8550_driver); | ||
255 | } | ||
256 | |||
257 | module_init (ohci_hcd_pnx8550_init); | ||
258 | module_exit (ohci_hcd_pnx8550_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index d9d1ae236bd5..e1a7eb817313 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * (C) Copyright 2002 Hewlett-Packard Company | 6 | * (C) Copyright 2002 Hewlett-Packard Company |
7 | * (C) Copyright 2003-2005 MontaVista Software Inc. | 7 | * (C) Copyright 2003-2005 MontaVista Software Inc. |
8 | * | 8 | * |
9 | * Bus Glue for PPC On-Chip OHCI driver | 9 | * Bus Glue for PPC On-Chip OHCI driver |
10 | * Tested on Freescale MPC5200 and IBM STB04xxx | 10 | * Tested on Freescale MPC5200 and IBM STB04xxx |
11 | * | 11 | * |
@@ -85,7 +85,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
85 | err2: | 85 | err2: |
86 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 86 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
87 | err1: | 87 | err1: |
88 | usb_put_hcd(hcd); | 88 | usb_put_hcd(hcd); |
89 | return retval; | 89 | return retval; |
90 | } | 90 | } |
91 | 91 | ||
@@ -148,7 +148,7 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { | |||
148 | */ | 148 | */ |
149 | .start = ohci_ppc_soc_start, | 149 | .start = ohci_ppc_soc_start, |
150 | .stop = ohci_stop, | 150 | .stop = ohci_stop, |
151 | .shutdown = ohci_shutdown, | 151 | .shutdown = ohci_shutdown, |
152 | 152 | ||
153 | /* | 153 | /* |
154 | * managing i/o requests and associated device resources | 154 | * managing i/o requests and associated device resources |
@@ -197,7 +197,7 @@ static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) | |||
197 | static struct platform_driver ohci_hcd_ppc_soc_driver = { | 197 | static struct platform_driver ohci_hcd_ppc_soc_driver = { |
198 | .probe = ohci_hcd_ppc_soc_drv_probe, | 198 | .probe = ohci_hcd_ppc_soc_drv_probe, |
199 | .remove = ohci_hcd_ppc_soc_drv_remove, | 199 | .remove = ohci_hcd_ppc_soc_drv_remove, |
200 | .shutdown = usb_hcd_platform_shutdown, | 200 | .shutdown = usb_hcd_platform_shutdown, |
201 | #ifdef CONFIG_PM | 201 | #ifdef CONFIG_PM |
202 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | 202 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ |
203 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | 203 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e176b04d7aeb..3bbea844a9e3 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -47,7 +47,7 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
47 | switch ( mode ) { | 47 | switch ( mode ) { |
48 | case PMM_NPS_MODE: | 48 | case PMM_NPS_MODE: |
49 | UHCRHDA |= RH_A_NPS; | 49 | UHCRHDA |= RH_A_NPS; |
50 | break; | 50 | break; |
51 | case PMM_GLOBAL_MODE: | 51 | case PMM_GLOBAL_MODE: |
52 | UHCRHDA &= ~(RH_A_NPS & RH_A_PSM); | 52 | UHCRHDA &= ~(RH_A_NPS & RH_A_PSM); |
53 | break; | 53 | break; |
@@ -60,7 +60,7 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
60 | break; | 60 | break; |
61 | default: | 61 | default: |
62 | printk( KERN_ERR | 62 | printk( KERN_ERR |
63 | "Invalid mode %d, set to non-power switch mode.\n", | 63 | "Invalid mode %d, set to non-power switch mode.\n", |
64 | mode ); | 64 | mode ); |
65 | 65 | ||
66 | UHCRHDA |= RH_A_NPS; | 66 | UHCRHDA |= RH_A_NPS; |
@@ -270,7 +270,7 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
270 | */ | 270 | */ |
271 | .start = ohci_pxa27x_start, | 271 | .start = ohci_pxa27x_start, |
272 | .stop = ohci_stop, | 272 | .stop = ohci_stop, |
273 | .shutdown = ohci_shutdown, | 273 | .shutdown = ohci_shutdown, |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * managing i/o requests and associated device resources | 276 | * managing i/o requests and associated device resources |
@@ -359,9 +359,9 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) | |||
359 | static struct platform_driver ohci_hcd_pxa27x_driver = { | 359 | static struct platform_driver ohci_hcd_pxa27x_driver = { |
360 | .probe = ohci_hcd_pxa27x_drv_probe, | 360 | .probe = ohci_hcd_pxa27x_drv_probe, |
361 | .remove = ohci_hcd_pxa27x_drv_remove, | 361 | .remove = ohci_hcd_pxa27x_drv_remove, |
362 | .shutdown = usb_hcd_platform_shutdown, | 362 | .shutdown = usb_hcd_platform_shutdown, |
363 | #ifdef CONFIG_PM | 363 | #ifdef CONFIG_PM |
364 | .suspend = ohci_hcd_pxa27x_drv_suspend, | 364 | .suspend = ohci_hcd_pxa27x_drv_suspend, |
365 | .resume = ohci_hcd_pxa27x_drv_resume, | 365 | .resume = ohci_hcd_pxa27x_drv_resume, |
366 | #endif | 366 | #endif |
367 | .driver = { | 367 | .driver = { |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index fe1fe2f97cb5..830a3fe8615e 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under the GPL. | 7 | * This file is licenced under the GPL. |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -89,7 +89,7 @@ __acquires(ohci->lock) | |||
89 | 89 | ||
90 | /*-------------------------------------------------------------------------* | 90 | /*-------------------------------------------------------------------------* |
91 | * ED handling functions | 91 | * ED handling functions |
92 | *-------------------------------------------------------------------------*/ | 92 | *-------------------------------------------------------------------------*/ |
93 | 93 | ||
94 | /* search for the right schedule branch to use for a periodic ed. | 94 | /* search for the right schedule branch to use for a periodic ed. |
95 | * does some load balancing; returns the branch, or negative errno. | 95 | * does some load balancing; returns the branch, or negative errno. |
@@ -107,7 +107,6 @@ static int balance (struct ohci_hcd *ohci, int interval, int load) | |||
107 | */ | 107 | */ |
108 | for (i = 0; i < interval ; i++) { | 108 | for (i = 0; i < interval ; i++) { |
109 | if (branch < 0 || ohci->load [branch] > ohci->load [i]) { | 109 | if (branch < 0 || ohci->load [branch] > ohci->load [i]) { |
110 | #if 1 /* CONFIG_USB_BANDWIDTH */ | ||
111 | int j; | 110 | int j; |
112 | 111 | ||
113 | /* usb 1.1 says 90% of one frame */ | 112 | /* usb 1.1 says 90% of one frame */ |
@@ -117,8 +116,7 @@ static int balance (struct ohci_hcd *ohci, int interval, int load) | |||
117 | } | 116 | } |
118 | if (j < NUM_INTS) | 117 | if (j < NUM_INTS) |
119 | continue; | 118 | continue; |
120 | #endif | 119 | branch = i; |
121 | branch = i; | ||
122 | } | 120 | } |
123 | } | 121 | } |
124 | return branch; | 122 | return branch; |
@@ -171,7 +169,7 @@ static void periodic_link (struct ohci_hcd *ohci, struct ed *ed) | |||
171 | /* link an ed into one of the HC chains */ | 169 | /* link an ed into one of the HC chains */ |
172 | 170 | ||
173 | static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | 171 | static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) |
174 | { | 172 | { |
175 | int branch; | 173 | int branch; |
176 | 174 | ||
177 | if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING) | 175 | if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING) |
@@ -248,7 +246,7 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
248 | } | 246 | } |
249 | ed->branch = branch; | 247 | ed->branch = branch; |
250 | periodic_link (ohci, ed); | 248 | periodic_link (ohci, ed); |
251 | } | 249 | } |
252 | 250 | ||
253 | /* the HC may not see the schedule updates yet, but if it does | 251 | /* the HC may not see the schedule updates yet, but if it does |
254 | * then they'll be properly ordered. | 252 | * then they'll be properly ordered. |
@@ -277,7 +275,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
277 | *prev = ed->ed_next; | 275 | *prev = ed->ed_next; |
278 | } | 276 | } |
279 | ohci->load [i] -= ed->load; | 277 | ohci->load [i] -= ed->load; |
280 | } | 278 | } |
281 | ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval; | 279 | ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval; |
282 | 280 | ||
283 | ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n", | 281 | ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n", |
@@ -285,7 +283,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
285 | ed, ed->branch, ed->load, ed->interval); | 283 | ed, ed->branch, ed->load, ed->interval); |
286 | } | 284 | } |
287 | 285 | ||
288 | /* unlink an ed from one of the HC chains. | 286 | /* unlink an ed from one of the HC chains. |
289 | * just the link to the ed is unlinked. | 287 | * just the link to the ed is unlinked. |
290 | * the link from the ed still points to another operational ed or 0 | 288 | * the link from the ed still points to another operational ed or 0 |
291 | * so the HC can eventually finish the processing of the unlinked ed | 289 | * so the HC can eventually finish the processing of the unlinked ed |
@@ -307,7 +305,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
307 | * When finish_unlinks() runs later, after SOF interrupt, it will often | 305 | * When finish_unlinks() runs later, after SOF interrupt, it will often |
308 | * complete one or more URB unlinks before making that state change. | 306 | * complete one or more URB unlinks before making that state change. |
309 | */ | 307 | */ |
310 | static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) | 308 | static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) |
311 | { | 309 | { |
312 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); | 310 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); |
313 | wmb (); | 311 | wmb (); |
@@ -397,7 +395,7 @@ static struct ed *ed_get ( | |||
397 | unsigned int pipe, | 395 | unsigned int pipe, |
398 | int interval | 396 | int interval |
399 | ) { | 397 | ) { |
400 | struct ed *ed; | 398 | struct ed *ed; |
401 | unsigned long flags; | 399 | unsigned long flags; |
402 | 400 | ||
403 | spin_lock_irqsave (&ohci->lock, flags); | 401 | spin_lock_irqsave (&ohci->lock, flags); |
@@ -413,9 +411,9 @@ static struct ed *ed_get ( | |||
413 | goto done; | 411 | goto done; |
414 | } | 412 | } |
415 | 413 | ||
416 | /* dummy td; end of td list for ed */ | 414 | /* dummy td; end of td list for ed */ |
417 | td = td_alloc (ohci, GFP_ATOMIC); | 415 | td = td_alloc (ohci, GFP_ATOMIC); |
418 | if (!td) { | 416 | if (!td) { |
419 | /* out of memory */ | 417 | /* out of memory */ |
420 | ed_free (ohci, ed); | 418 | ed_free (ohci, ed); |
421 | ed = NULL; | 419 | ed = NULL; |
@@ -462,7 +460,7 @@ static struct ed *ed_get ( | |||
462 | 460 | ||
463 | done: | 461 | done: |
464 | spin_unlock_irqrestore (&ohci->lock, flags); | 462 | spin_unlock_irqrestore (&ohci->lock, flags); |
465 | return ed; | 463 | return ed; |
466 | } | 464 | } |
467 | 465 | ||
468 | /*-------------------------------------------------------------------------*/ | 466 | /*-------------------------------------------------------------------------*/ |
@@ -474,7 +472,7 @@ done: | |||
474 | * and that ed->state is ED_OPER | 472 | * and that ed->state is ED_OPER |
475 | */ | 473 | */ |
476 | static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed) | 474 | static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed) |
477 | { | 475 | { |
478 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE); | 476 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE); |
479 | ed_deschedule (ohci, ed); | 477 | ed_deschedule (ohci, ed); |
480 | 478 | ||
@@ -541,7 +539,7 @@ td_fill (struct ohci_hcd *ohci, u32 info, | |||
541 | td->ed = urb_priv->ed; | 539 | td->ed = urb_priv->ed; |
542 | td->next_dl_td = NULL; | 540 | td->next_dl_td = NULL; |
543 | td->index = index; | 541 | td->index = index; |
544 | td->urb = urb; | 542 | td->urb = urb; |
545 | td->data_dma = data; | 543 | td->data_dma = data; |
546 | if (!len) | 544 | if (!len) |
547 | data = 0; | 545 | data = 0; |
@@ -553,8 +551,8 @@ td_fill (struct ohci_hcd *ohci, u32 info, | |||
553 | (data & 0x0FFF) | 0xE000); | 551 | (data & 0x0FFF) | 0xE000); |
554 | td->ed->last_iso = info & 0xffff; | 552 | td->ed->last_iso = info & 0xffff; |
555 | } else { | 553 | } else { |
556 | td->hwCBP = cpu_to_hc32 (ohci, data); | 554 | td->hwCBP = cpu_to_hc32 (ohci, data); |
557 | } | 555 | } |
558 | if (data) | 556 | if (data) |
559 | td->hwBE = cpu_to_hc32 (ohci, data + len - 1); | 557 | td->hwBE = cpu_to_hc32 (ohci, data + len - 1); |
560 | else | 558 | else |
@@ -597,7 +595,7 @@ static void td_submit_urb ( | |||
597 | * use the device toggle bits for resetting, and rely on the fact | 595 | * use the device toggle bits for resetting, and rely on the fact |
598 | * that resetting toggle is meaningless if the endpoint is active. | 596 | * that resetting toggle is meaningless if the endpoint is active. |
599 | */ | 597 | */ |
600 | if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { | 598 | if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { |
601 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), | 599 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), |
602 | is_out, 1); | 600 | is_out, 1); |
603 | urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C); | 601 | urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C); |
@@ -721,16 +719,16 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
721 | list_del (&td->td_list); | 719 | list_del (&td->td_list); |
722 | 720 | ||
723 | /* ISO ... drivers see per-TD length/status */ | 721 | /* ISO ... drivers see per-TD length/status */ |
724 | if (tdINFO & TD_ISO) { | 722 | if (tdINFO & TD_ISO) { |
725 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); | 723 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); |
726 | int dlen = 0; | 724 | int dlen = 0; |
727 | 725 | ||
728 | /* NOTE: assumes FC in tdINFO == 0, and that | 726 | /* NOTE: assumes FC in tdINFO == 0, and that |
729 | * only the first of 0..MAXPSW psws is used. | 727 | * only the first of 0..MAXPSW psws is used. |
730 | */ | 728 | */ |
731 | 729 | ||
732 | cc = (tdPSW >> 12) & 0xF; | 730 | cc = (tdPSW >> 12) & 0xF; |
733 | if (tdINFO & TD_CC) /* hc didn't touch? */ | 731 | if (tdINFO & TD_CC) /* hc didn't touch? */ |
734 | return; | 732 | return; |
735 | 733 | ||
736 | if (usb_pipeout (urb->pipe)) | 734 | if (usb_pipeout (urb->pipe)) |
@@ -758,7 +756,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
758 | int type = usb_pipetype (urb->pipe); | 756 | int type = usb_pipetype (urb->pipe); |
759 | u32 tdBE = hc32_to_cpup (ohci, &td->hwBE); | 757 | u32 tdBE = hc32_to_cpup (ohci, &td->hwBE); |
760 | 758 | ||
761 | cc = TD_CC_GET (tdINFO); | 759 | cc = TD_CC_GET (tdINFO); |
762 | 760 | ||
763 | /* update packet status if needed (short is normally ok) */ | 761 | /* update packet status if needed (short is normally ok) */ |
764 | if (cc == TD_DATAUNDERRUN | 762 | if (cc == TD_DATAUNDERRUN |
@@ -787,7 +785,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
787 | urb, td, 1 + td->index, cc, | 785 | urb, td, 1 + td->index, cc, |
788 | urb->actual_length, | 786 | urb->actual_length, |
789 | urb->transfer_buffer_length); | 787 | urb->transfer_buffer_length); |
790 | } | 788 | } |
791 | } | 789 | } |
792 | 790 | ||
793 | /*-------------------------------------------------------------------------*/ | 791 | /*-------------------------------------------------------------------------*/ |
@@ -795,7 +793,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
795 | static inline struct td * | 793 | static inline struct td * |
796 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | 794 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) |
797 | { | 795 | { |
798 | struct urb *urb = td->urb; | 796 | struct urb *urb = td->urb; |
799 | struct ed *ed = td->ed; | 797 | struct ed *ed = td->ed; |
800 | struct list_head *tmp = td->td_list.next; | 798 | struct list_head *tmp = td->td_list.next; |
801 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); | 799 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); |
@@ -805,7 +803,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
805 | */ | 803 | */ |
806 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); | 804 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); |
807 | wmb (); | 805 | wmb (); |
808 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); | 806 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); |
809 | 807 | ||
810 | /* put any later tds from this urb onto the donelist, after 'td', | 808 | /* put any later tds from this urb onto the donelist, after 'td', |
811 | * order won't matter here: no errors, and nothing was transferred. | 809 | * order won't matter here: no errors, and nothing was transferred. |
@@ -833,7 +831,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
833 | info &= ~cpu_to_hc32 (ohci, TD_CC); | 831 | info &= ~cpu_to_hc32 (ohci, TD_CC); |
834 | next->hwINFO = info; | 832 | next->hwINFO = info; |
835 | 833 | ||
836 | next->next_dl_td = rev; | 834 | next->next_dl_td = rev; |
837 | rev = next; | 835 | rev = next; |
838 | 836 | ||
839 | ed->hwHeadP = next->hwNextTD | toggle; | 837 | ed->hwHeadP = next->hwNextTD | toggle; |
@@ -881,8 +879,8 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
881 | /* get TD from hc's singly linked list, and | 879 | /* get TD from hc's singly linked list, and |
882 | * prepend to ours. ed->td_list changes later. | 880 | * prepend to ours. ed->td_list changes later. |
883 | */ | 881 | */ |
884 | while (td_dma) { | 882 | while (td_dma) { |
885 | int cc; | 883 | int cc; |
886 | 884 | ||
887 | td = dma_to_td (ohci, td_dma); | 885 | td = dma_to_td (ohci, td_dma); |
888 | if (!td) { | 886 | if (!td) { |
@@ -901,10 +899,10 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
901 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) | 899 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) |
902 | td_rev = ed_halted (ohci, td, cc, td_rev); | 900 | td_rev = ed_halted (ohci, td, cc, td_rev); |
903 | 901 | ||
904 | td->next_dl_td = td_rev; | 902 | td->next_dl_td = td_rev; |
905 | td_rev = td; | 903 | td_rev = td; |
906 | td_dma = hc32_to_cpup (ohci, &td->hwNextTD); | 904 | td_dma = hc32_to_cpup (ohci, &td->hwNextTD); |
907 | } | 905 | } |
908 | return td_rev; | 906 | return td_rev; |
909 | } | 907 | } |
910 | 908 | ||
@@ -1013,9 +1011,9 @@ rescan_this: | |||
1013 | 1011 | ||
1014 | if (modified) | 1012 | if (modified) |
1015 | goto rescan_all; | 1013 | goto rescan_all; |
1016 | } | 1014 | } |
1017 | 1015 | ||
1018 | /* maybe reenable control and bulk lists */ | 1016 | /* maybe reenable control and bulk lists */ |
1019 | if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state) | 1017 | if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state) |
1020 | && ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING | 1018 | && ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING |
1021 | && !ohci->ed_rm_list) { | 1019 | && !ohci->ed_rm_list) { |
@@ -1041,20 +1039,20 @@ rescan_this: | |||
1041 | &ohci->regs->ed_bulkcurrent); | 1039 | &ohci->regs->ed_bulkcurrent); |
1042 | } | 1040 | } |
1043 | } | 1041 | } |
1044 | 1042 | ||
1045 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ | 1043 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ |
1046 | if (control) { | 1044 | if (control) { |
1047 | ohci->hc_control |= control; | 1045 | ohci->hc_control |= control; |
1048 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1046 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) |
1049 | mdelay(1); | 1047 | mdelay(1); |
1050 | ohci_writel (ohci, ohci->hc_control, | 1048 | ohci_writel (ohci, ohci->hc_control, |
1051 | &ohci->regs->control); | 1049 | &ohci->regs->control); |
1052 | } | 1050 | } |
1053 | if (command) { | 1051 | if (command) { |
1054 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1052 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) |
1055 | mdelay(1); | 1053 | mdelay(1); |
1056 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); | 1054 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); |
1057 | } | 1055 | } |
1058 | } | 1056 | } |
1059 | } | 1057 | } |
1060 | 1058 | ||
@@ -1074,19 +1072,19 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1074 | { | 1072 | { |
1075 | struct td *td = dl_reverse_done_list (ohci); | 1073 | struct td *td = dl_reverse_done_list (ohci); |
1076 | 1074 | ||
1077 | while (td) { | 1075 | while (td) { |
1078 | struct td *td_next = td->next_dl_td; | 1076 | struct td *td_next = td->next_dl_td; |
1079 | struct urb *urb = td->urb; | 1077 | struct urb *urb = td->urb; |
1080 | urb_priv_t *urb_priv = urb->hcpriv; | 1078 | urb_priv_t *urb_priv = urb->hcpriv; |
1081 | struct ed *ed = td->ed; | 1079 | struct ed *ed = td->ed; |
1082 | 1080 | ||
1083 | /* update URB's length and status from TD */ | 1081 | /* update URB's length and status from TD */ |
1084 | td_done (ohci, urb, td); | 1082 | td_done (ohci, urb, td); |
1085 | urb_priv->td_cnt++; | 1083 | urb_priv->td_cnt++; |
1086 | 1084 | ||
1087 | /* If all this urb's TDs are done, call complete() */ | 1085 | /* If all this urb's TDs are done, call complete() */ |
1088 | if (urb_priv->td_cnt == urb_priv->length) | 1086 | if (urb_priv->td_cnt == urb_priv->length) |
1089 | finish_urb (ohci, urb); | 1087 | finish_urb (ohci, urb); |
1090 | 1088 | ||
1091 | /* clean schedule: unlink EDs that are no longer busy */ | 1089 | /* clean schedule: unlink EDs that are no longer busy */ |
1092 | if (list_empty (&ed->td_list)) { | 1090 | if (list_empty (&ed->td_list)) { |
@@ -1094,25 +1092,26 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1094 | start_ed_unlink (ohci, ed); | 1092 | start_ed_unlink (ohci, ed); |
1095 | 1093 | ||
1096 | /* ... reenabling halted EDs only after fault cleanup */ | 1094 | /* ... reenabling halted EDs only after fault cleanup */ |
1097 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE)) | 1095 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, |
1096 | ED_SKIP | ED_DEQUEUE)) | ||
1098 | == cpu_to_hc32 (ohci, ED_SKIP)) { | 1097 | == cpu_to_hc32 (ohci, ED_SKIP)) { |
1099 | td = list_entry (ed->td_list.next, struct td, td_list); | 1098 | td = list_entry (ed->td_list.next, struct td, td_list); |
1100 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { | 1099 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { |
1101 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); | 1100 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); |
1102 | /* ... hc may need waking-up */ | 1101 | /* ... hc may need waking-up */ |
1103 | switch (ed->type) { | 1102 | switch (ed->type) { |
1104 | case PIPE_CONTROL: | 1103 | case PIPE_CONTROL: |
1105 | ohci_writel (ohci, OHCI_CLF, | 1104 | ohci_writel (ohci, OHCI_CLF, |
1106 | &ohci->regs->cmdstatus); | 1105 | &ohci->regs->cmdstatus); |
1107 | break; | 1106 | break; |
1108 | case PIPE_BULK: | 1107 | case PIPE_BULK: |
1109 | ohci_writel (ohci, OHCI_BLF, | 1108 | ohci_writel (ohci, OHCI_BLF, |
1110 | &ohci->regs->cmdstatus); | 1109 | &ohci->regs->cmdstatus); |
1111 | break; | 1110 | break; |
1112 | } | 1111 | } |
1113 | } | 1112 | } |
1114 | } | 1113 | } |
1115 | 1114 | ||
1116 | td = td_next; | 1115 | td = td_next; |
1117 | } | 1116 | } |
1118 | } | 1117 | } |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 59e436424d41..b350d45033e7 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -447,7 +447,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { | |||
447 | */ | 447 | */ |
448 | .start = ohci_s3c2410_start, | 448 | .start = ohci_s3c2410_start, |
449 | .stop = ohci_stop, | 449 | .stop = ohci_stop, |
450 | .shutdown = ohci_shutdown, | 450 | .shutdown = ohci_shutdown, |
451 | 451 | ||
452 | /* | 452 | /* |
453 | * managing i/o requests and associated device resources | 453 | * managing i/o requests and associated device resources |
@@ -492,7 +492,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev) | |||
492 | static struct platform_driver ohci_hcd_s3c2410_driver = { | 492 | static struct platform_driver ohci_hcd_s3c2410_driver = { |
493 | .probe = ohci_hcd_s3c2410_drv_probe, | 493 | .probe = ohci_hcd_s3c2410_drv_probe, |
494 | .remove = ohci_hcd_s3c2410_drv_remove, | 494 | .remove = ohci_hcd_s3c2410_drv_remove, |
495 | .shutdown = usb_hcd_platform_shutdown, | 495 | .shutdown = usb_hcd_platform_shutdown, |
496 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ | 496 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ |
497 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ | 497 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ |
498 | .driver = { | 498 | .driver = { |
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 71371de32ada..fe0090e33675 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * (C) Copyright 2002 Hewlett-Packard Company | 6 | * (C) Copyright 2002 Hewlett-Packard Company |
7 | * | 7 | * |
8 | * SA1111 Bus Glue | 8 | * SA1111 Bus Glue |
9 | * | 9 | * |
10 | * Written by Christopher Hoover <ch@hpl.hp.com> | 10 | * Written by Christopher Hoover <ch@hpl.hp.com> |
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | * This file is licenced under the GPL. | 13 | * This file is licenced under the GPL. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <asm/hardware.h> | 16 | #include <asm/hardware.h> |
17 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
18 | #include <asm/arch/assabet.h> | 18 | #include <asm/arch/assabet.h> |
@@ -31,7 +31,7 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
31 | { | 31 | { |
32 | unsigned int usb_rst = 0; | 32 | unsigned int usb_rst = 0; |
33 | 33 | ||
34 | printk(KERN_DEBUG __FILE__ | 34 | printk(KERN_DEBUG __FILE__ |
35 | ": starting SA-1111 OHCI USB Controller\n"); | 35 | ": starting SA-1111 OHCI USB Controller\n"); |
36 | 36 | ||
37 | #ifdef CONFIG_SA1100_BADGE4 | 37 | #ifdef CONFIG_SA1100_BADGE4 |
@@ -65,7 +65,7 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
65 | static void sa1111_stop_hc(struct sa1111_dev *dev) | 65 | static void sa1111_stop_hc(struct sa1111_dev *dev) |
66 | { | 66 | { |
67 | unsigned int usb_rst; | 67 | unsigned int usb_rst; |
68 | printk(KERN_DEBUG __FILE__ | 68 | printk(KERN_DEBUG __FILE__ |
69 | ": stopping SA-1111 OHCI USB Controller\n"); | 69 | ": stopping SA-1111 OHCI USB Controller\n"); |
70 | 70 | ||
71 | /* | 71 | /* |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index a2f42a2f47c6..405257f3e853 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under the GPL. | 7 | * This file is licenced under the GPL. |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | typedef __u32 __bitwise __hc32; | 15 | typedef __u32 __bitwise __hc32; |
16 | typedef __u16 __bitwise __hc16; | 16 | typedef __u16 __bitwise __hc16; |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * OHCI Endpoint Descriptor (ED) ... holds TD queue | 19 | * OHCI Endpoint Descriptor (ED) ... holds TD queue |
20 | * See OHCI spec, section 4.2 | 20 | * See OHCI spec, section 4.2 |
@@ -24,7 +24,7 @@ typedef __u16 __bitwise __hc16; | |||
24 | */ | 24 | */ |
25 | struct ed { | 25 | struct ed { |
26 | /* first fields are hardware-specified */ | 26 | /* first fields are hardware-specified */ |
27 | __hc32 hwINFO; /* endpoint config bitmap */ | 27 | __hc32 hwINFO; /* endpoint config bitmap */ |
28 | /* info bits defined by hcd */ | 28 | /* info bits defined by hcd */ |
29 | #define ED_DEQUEUE (1 << 27) | 29 | #define ED_DEQUEUE (1 << 27) |
30 | /* info bits defined by the hardware */ | 30 | /* info bits defined by the hardware */ |
@@ -52,11 +52,11 @@ struct ed { | |||
52 | * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... | 52 | * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... |
53 | */ | 53 | */ |
54 | u8 state; /* ED_{IDLE,UNLINK,OPER} */ | 54 | u8 state; /* ED_{IDLE,UNLINK,OPER} */ |
55 | #define ED_IDLE 0x00 /* NOT linked to HC */ | 55 | #define ED_IDLE 0x00 /* NOT linked to HC */ |
56 | #define ED_UNLINK 0x01 /* being unlinked from hc */ | 56 | #define ED_UNLINK 0x01 /* being unlinked from hc */ |
57 | #define ED_OPER 0x02 /* IS linked to hc */ | 57 | #define ED_OPER 0x02 /* IS linked to hc */ |
58 | 58 | ||
59 | u8 type; /* PIPE_{BULK,...} */ | 59 | u8 type; /* PIPE_{BULK,...} */ |
60 | 60 | ||
61 | /* periodic scheduling params (for intr and iso) */ | 61 | /* periodic scheduling params (for intr and iso) */ |
62 | u8 branch; | 62 | u8 branch; |
@@ -70,7 +70,7 @@ struct ed { | |||
70 | 70 | ||
71 | #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ | 71 | #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ |
72 | 72 | ||
73 | 73 | ||
74 | /* | 74 | /* |
75 | * OHCI Transfer Descriptor (TD) ... one per transfer segment | 75 | * OHCI Transfer Descriptor (TD) ... one per transfer segment |
76 | * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt) | 76 | * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt) |
@@ -107,22 +107,22 @@ struct td { | |||
107 | 107 | ||
108 | /* (no hwINFO #defines yet for iso tds) */ | 108 | /* (no hwINFO #defines yet for iso tds) */ |
109 | 109 | ||
110 | __hc32 hwCBP; /* Current Buffer Pointer (or 0) */ | 110 | __hc32 hwCBP; /* Current Buffer Pointer (or 0) */ |
111 | __hc32 hwNextTD; /* Next TD Pointer */ | 111 | __hc32 hwNextTD; /* Next TD Pointer */ |
112 | __hc32 hwBE; /* Memory Buffer End Pointer */ | 112 | __hc32 hwBE; /* Memory Buffer End Pointer */ |
113 | 113 | ||
114 | /* PSW is only for ISO. Only 1 PSW entry is used, but on | 114 | /* PSW is only for ISO. Only 1 PSW entry is used, but on |
115 | * big-endian PPC hardware that's the second entry. | 115 | * big-endian PPC hardware that's the second entry. |
116 | */ | 116 | */ |
117 | #define MAXPSW 2 | 117 | #define MAXPSW 2 |
118 | __hc16 hwPSW [MAXPSW]; | 118 | __hc16 hwPSW [MAXPSW]; |
119 | 119 | ||
120 | /* rest are purely for the driver's use */ | 120 | /* rest are purely for the driver's use */ |
121 | __u8 index; | 121 | __u8 index; |
122 | struct ed *ed; | 122 | struct ed *ed; |
123 | struct td *td_hash; /* dma-->td hashtable */ | 123 | struct td *td_hash; /* dma-->td hashtable */ |
124 | struct td *next_dl_td; | 124 | struct td *next_dl_td; |
125 | struct urb *urb; | 125 | struct urb *urb; |
126 | 126 | ||
127 | dma_addr_t td_dma; /* addr of this TD */ | 127 | dma_addr_t td_dma; /* addr of this TD */ |
128 | dma_addr_t data_dma; /* addr of data it points to */ | 128 | dma_addr_t data_dma; /* addr of data it points to */ |
@@ -152,8 +152,8 @@ struct td { | |||
152 | #define TD_NOTACCESSED 0x0F | 152 | #define TD_NOTACCESSED 0x0F |
153 | 153 | ||
154 | 154 | ||
155 | /* map OHCI TD status codes (CC) to errno values */ | 155 | /* map OHCI TD status codes (CC) to errno values */ |
156 | static const int cc_to_error [16] = { | 156 | static const int cc_to_error [16] = { |
157 | /* No Error */ 0, | 157 | /* No Error */ 0, |
158 | /* CRC Error */ -EILSEQ, | 158 | /* CRC Error */ -EILSEQ, |
159 | /* Bit Stuff */ -EPROTO, | 159 | /* Bit Stuff */ -EPROTO, |
@@ -169,7 +169,7 @@ static const int cc_to_error [16] = { | |||
169 | /* BufferOver */ -ECOMM, | 169 | /* BufferOver */ -ECOMM, |
170 | /* BuffUnder */ -ENOSR, | 170 | /* BuffUnder */ -ENOSR, |
171 | /* (for HCD) */ -EALREADY, | 171 | /* (for HCD) */ -EALREADY, |
172 | /* (for HCD) */ -EALREADY | 172 | /* (for HCD) */ -EALREADY |
173 | }; | 173 | }; |
174 | 174 | ||
175 | 175 | ||
@@ -182,7 +182,7 @@ struct ohci_hcca { | |||
182 | #define NUM_INTS 32 | 182 | #define NUM_INTS 32 |
183 | __hc32 int_table [NUM_INTS]; /* periodic schedule */ | 183 | __hc32 int_table [NUM_INTS]; /* periodic schedule */ |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * OHCI defines u16 frame_no, followed by u16 zero pad. | 186 | * OHCI defines u16 frame_no, followed by u16 zero pad. |
187 | * Since some processors can't do 16 bit bus accesses, | 187 | * Since some processors can't do 16 bit bus accesses, |
188 | * portable access must be a 32 bits wide. | 188 | * portable access must be a 32 bits wide. |
@@ -262,10 +262,10 @@ struct ohci_regs { | |||
262 | * HcCommandStatus (cmdstatus) register masks | 262 | * HcCommandStatus (cmdstatus) register masks |
263 | */ | 263 | */ |
264 | #define OHCI_HCR (1 << 0) /* host controller reset */ | 264 | #define OHCI_HCR (1 << 0) /* host controller reset */ |
265 | #define OHCI_CLF (1 << 1) /* control list filled */ | 265 | #define OHCI_CLF (1 << 1) /* control list filled */ |
266 | #define OHCI_BLF (1 << 2) /* bulk list filled */ | 266 | #define OHCI_BLF (1 << 2) /* bulk list filled */ |
267 | #define OHCI_OCR (1 << 3) /* ownership change request */ | 267 | #define OHCI_OCR (1 << 3) /* ownership change request */ |
268 | #define OHCI_SOC (3 << 16) /* scheduling overrun count */ | 268 | #define OHCI_SOC (3 << 16) /* scheduling overrun count */ |
269 | 269 | ||
270 | /* | 270 | /* |
271 | * masks used with interrupt registers: | 271 | * masks used with interrupt registers: |
@@ -285,20 +285,20 @@ struct ohci_regs { | |||
285 | 285 | ||
286 | 286 | ||
287 | /* OHCI ROOT HUB REGISTER MASKS */ | 287 | /* OHCI ROOT HUB REGISTER MASKS */ |
288 | 288 | ||
289 | /* roothub.portstatus [i] bits */ | 289 | /* roothub.portstatus [i] bits */ |
290 | #define RH_PS_CCS 0x00000001 /* current connect status */ | 290 | #define RH_PS_CCS 0x00000001 /* current connect status */ |
291 | #define RH_PS_PES 0x00000002 /* port enable status*/ | 291 | #define RH_PS_PES 0x00000002 /* port enable status*/ |
292 | #define RH_PS_PSS 0x00000004 /* port suspend status */ | 292 | #define RH_PS_PSS 0x00000004 /* port suspend status */ |
293 | #define RH_PS_POCI 0x00000008 /* port over current indicator */ | 293 | #define RH_PS_POCI 0x00000008 /* port over current indicator */ |
294 | #define RH_PS_PRS 0x00000010 /* port reset status */ | 294 | #define RH_PS_PRS 0x00000010 /* port reset status */ |
295 | #define RH_PS_PPS 0x00000100 /* port power status */ | 295 | #define RH_PS_PPS 0x00000100 /* port power status */ |
296 | #define RH_PS_LSDA 0x00000200 /* low speed device attached */ | 296 | #define RH_PS_LSDA 0x00000200 /* low speed device attached */ |
297 | #define RH_PS_CSC 0x00010000 /* connect status change */ | 297 | #define RH_PS_CSC 0x00010000 /* connect status change */ |
298 | #define RH_PS_PESC 0x00020000 /* port enable status change */ | 298 | #define RH_PS_PESC 0x00020000 /* port enable status change */ |
299 | #define RH_PS_PSSC 0x00040000 /* port suspend status change */ | 299 | #define RH_PS_PSSC 0x00040000 /* port suspend status change */ |
300 | #define RH_PS_OCIC 0x00080000 /* over current indicator change */ | 300 | #define RH_PS_OCIC 0x00080000 /* over current indicator change */ |
301 | #define RH_PS_PRSC 0x00100000 /* port reset status change */ | 301 | #define RH_PS_PRSC 0x00100000 /* port reset status change */ |
302 | 302 | ||
303 | /* roothub.status bits */ | 303 | /* roothub.status bits */ |
304 | #define RH_HS_LPS 0x00000001 /* local power status */ | 304 | #define RH_HS_LPS 0x00000001 /* local power status */ |
@@ -333,7 +333,7 @@ typedef struct urb_priv { | |||
333 | } urb_priv_t; | 333 | } urb_priv_t; |
334 | 334 | ||
335 | #define TD_HASH_SIZE 64 /* power'o'two */ | 335 | #define TD_HASH_SIZE 64 /* power'o'two */ |
336 | // sizeof (struct td) ~= 64 == 2^6 ... | 336 | // sizeof (struct td) ~= 64 == 2^6 ... |
337 | #define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE) | 337 | #define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE) |
338 | 338 | ||
339 | 339 | ||
@@ -364,11 +364,11 @@ struct ohci_hcd { | |||
364 | 364 | ||
365 | struct ed *ed_bulktail; /* last in bulk list */ | 365 | struct ed *ed_bulktail; /* last in bulk list */ |
366 | struct ed *ed_controltail; /* last in ctrl list */ | 366 | struct ed *ed_controltail; /* last in ctrl list */ |
367 | struct ed *periodic [NUM_INTS]; /* shadow int_table */ | 367 | struct ed *periodic [NUM_INTS]; /* shadow int_table */ |
368 | 368 | ||
369 | /* | 369 | /* |
370 | * OTG controllers and transceivers need software interaction; | 370 | * OTG controllers and transceivers need software interaction; |
371 | * other external transceivers should be software-transparent | 371 | * other external transceivers should be software-transparent |
372 | */ | 372 | */ |
373 | struct otg_transceiver *transceiver; | 373 | struct otg_transceiver *transceiver; |
374 | 374 | ||
@@ -385,7 +385,7 @@ struct ohci_hcd { | |||
385 | */ | 385 | */ |
386 | int num_ports; | 386 | int num_ports; |
387 | int load [NUM_INTS]; | 387 | int load [NUM_INTS]; |
388 | u32 hc_control; /* copy of hc control reg */ | 388 | u32 hc_control; /* copy of hc control reg */ |
389 | unsigned long next_statechange; /* suspend/resume */ | 389 | unsigned long next_statechange; /* suspend/resume */ |
390 | u32 fminterval; /* saved register */ | 390 | u32 fminterval; /* saved register */ |
391 | unsigned autostop:1; /* rh auto stopping/stopped */ | 391 | unsigned autostop:1; /* rh auto stopping/stopped */ |
@@ -598,11 +598,11 @@ static inline void disable (struct ohci_hcd *ohci) | |||
598 | } | 598 | } |
599 | 599 | ||
600 | #define FI 0x2edf /* 12000 bits per frame (-1) */ | 600 | #define FI 0x2edf /* 12000 bits per frame (-1) */ |
601 | #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) | 601 | #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) |
602 | #define FIT (1 << 31) | 602 | #define FIT (1 << 31) |
603 | #define LSTHRESH 0x628 /* lowspeed bit threshold */ | 603 | #define LSTHRESH 0x628 /* lowspeed bit threshold */ |
604 | 604 | ||
605 | static void periodic_reinit (struct ohci_hcd *ohci) | 605 | static inline void periodic_reinit (struct ohci_hcd *ohci) |
606 | { | 606 | { |
607 | u32 fi = ohci->fminterval & 0x03fff; | 607 | u32 fi = ohci->fminterval & 0x03fff; |
608 | u32 fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT; | 608 | u32 fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT; |
@@ -626,11 +626,11 @@ static void periodic_reinit (struct ohci_hcd *ohci) | |||
626 | temp = ohci_readl (hc, &hc->regs->roothub.register); \ | 626 | temp = ohci_readl (hc, &hc->regs->roothub.register); \ |
627 | temp; }) | 627 | temp; }) |
628 | 628 | ||
629 | static u32 roothub_a (struct ohci_hcd *hc) | 629 | static inline u32 roothub_a (struct ohci_hcd *hc) |
630 | { return read_roothub (hc, a, 0xfc0fe000); } | 630 | { return read_roothub (hc, a, 0xfc0fe000); } |
631 | static inline u32 roothub_b (struct ohci_hcd *hc) | 631 | static inline u32 roothub_b (struct ohci_hcd *hc) |
632 | { return ohci_readl (hc, &hc->regs->roothub.b); } | 632 | { return ohci_readl (hc, &hc->regs->roothub.b); } |
633 | static inline u32 roothub_status (struct ohci_hcd *hc) | 633 | static inline u32 roothub_status (struct ohci_hcd *hc) |
634 | { return ohci_readl (hc, &hc->regs->roothub.status); } | 634 | { return ohci_readl (hc, &hc->regs->roothub.status); } |
635 | static u32 roothub_portstatus (struct ohci_hcd *hc, int i) | 635 | static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) |
636 | { return read_roothub (hc, portstatus [i], 0xffe0fce0); } | 636 | { return read_roothub (hc, portstatus [i], 0xffe0fce0); } |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index a9d7119e3176..a7fa0d75567d 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/moduleparam.h> | 40 | #include <linux/moduleparam.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/ioport.h> | 42 | #include <linux/ioport.h> |
43 | #include <linux/pci_ids.h> | ||
43 | #include <linux/sched.h> | 44 | #include <linux/sched.h> |
44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
45 | #include <linux/smp_lock.h> | 46 | #include <linux/smp_lock.h> |
@@ -210,15 +211,16 @@ struct u132 { | |||
210 | * these cannot be inlines because we need the structure offset!! | 211 | * these cannot be inlines because we need the structure offset!! |
211 | * Does anyone have a better way????? | 212 | * Does anyone have a better way????? |
212 | */ | 213 | */ |
214 | #define ftdi_read_pcimem(pdev, member, data) usb_ftdi_elan_read_pcimem(pdev, \ | ||
215 | offsetof(struct ohci_regs, member), 0, data); | ||
216 | #define ftdi_write_pcimem(pdev, member, data) usb_ftdi_elan_write_pcimem(pdev, \ | ||
217 | offsetof(struct ohci_regs, member), 0, data); | ||
213 | #define u132_read_pcimem(u132, member, data) \ | 218 | #define u132_read_pcimem(u132, member, data) \ |
214 | usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \ | 219 | usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \ |
215 | ohci_regs, member), 0, data); | 220 | ohci_regs, member), 0, data); |
216 | #define u132_write_pcimem(u132, member, data) \ | 221 | #define u132_write_pcimem(u132, member, data) \ |
217 | usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ | 222 | usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ |
218 | ohci_regs, member), 0, data); | 223 | ohci_regs, member), 0, data); |
219 | #define u132_write_pcimem_byte(u132, member, data) \ | ||
220 | usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ | ||
221 | ohci_regs, member), 0x0e, data); | ||
222 | static inline struct u132 *udev_to_u132(struct u132_udev *udev) | 224 | static inline struct u132 *udev_to_u132(struct u132_udev *udev) |
223 | { | 225 | { |
224 | u8 udev_number = udev->udev_number; | 226 | u8 udev_number = udev->udev_number; |
@@ -1574,59 +1576,12 @@ static char *hcfs2string(int state) | |||
1574 | return "?"; | 1576 | return "?"; |
1575 | } | 1577 | } |
1576 | 1578 | ||
1577 | static int u132_usb_reset(struct u132 *u132) | ||
1578 | { | ||
1579 | int retval; | ||
1580 | retval = u132_read_pcimem(u132, control, &u132->hc_control); | ||
1581 | if (retval) | ||
1582 | return retval; | ||
1583 | u132->hc_control &= OHCI_CTRL_RWC; | ||
1584 | retval = u132_write_pcimem(u132, control, u132->hc_control); | ||
1585 | if (retval) | ||
1586 | return retval; | ||
1587 | return 0; | ||
1588 | } | ||
1589 | |||
1590 | static int u132_init(struct u132 *u132) | 1579 | static int u132_init(struct u132 *u132) |
1591 | { | 1580 | { |
1592 | int retval; | 1581 | int retval; |
1593 | u32 control; | 1582 | u32 control; |
1594 | u132_disable(u132); | 1583 | u132_disable(u132); |
1595 | u132->next_statechange = | 1584 | u132->next_statechange = jiffies; |
1596 | jiffies; /* SMM owns the HC? not for long! */ { | ||
1597 | u32 control; | ||
1598 | retval = u132_read_pcimem(u132, control, &control); | ||
1599 | if (retval) | ||
1600 | return retval; | ||
1601 | if (control & OHCI_CTRL_IR) { | ||
1602 | u32 temp = 50; | ||
1603 | retval = u132_write_pcimem(u132, intrenable, | ||
1604 | OHCI_INTR_OC); | ||
1605 | if (retval) | ||
1606 | return retval; | ||
1607 | retval = u132_write_pcimem_byte(u132, cmdstatus, | ||
1608 | OHCI_OCR); | ||
1609 | if (retval) | ||
1610 | return retval; | ||
1611 | check:{ | ||
1612 | retval = u132_read_pcimem(u132, control, | ||
1613 | &control); | ||
1614 | if (retval) | ||
1615 | return retval; | ||
1616 | } | ||
1617 | if (control & OHCI_CTRL_IR) { | ||
1618 | msleep(10); | ||
1619 | if (--temp == 0) { | ||
1620 | dev_err(&u132->platform_dev->dev, "USB " | ||
1621 | "HC takeover failed!(BIOS/SMM b" | ||
1622 | "ug) control=%08X\n", control); | ||
1623 | return -EBUSY; | ||
1624 | } | ||
1625 | goto check; | ||
1626 | } | ||
1627 | u132_usb_reset(u132); | ||
1628 | } | ||
1629 | } | ||
1630 | retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); | 1585 | retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); |
1631 | if (retval) | 1586 | if (retval) |
1632 | return retval; | 1587 | return retval; |
@@ -1725,7 +1680,7 @@ static int u132_run(struct u132 *u132) | |||
1725 | retry:retval = u132_read_pcimem(u132, cmdstatus, &status); | 1680 | retry:retval = u132_read_pcimem(u132, cmdstatus, &status); |
1726 | if (retval) | 1681 | if (retval) |
1727 | return retval; | 1682 | return retval; |
1728 | retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_HCR); | 1683 | retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR); |
1729 | if (retval) | 1684 | if (retval) |
1730 | return retval; | 1685 | return retval; |
1731 | extra:{ | 1686 | extra:{ |
@@ -1782,7 +1737,7 @@ static int u132_run(struct u132 *u132) | |||
1782 | retval = u132_write_pcimem(u132, control, u132->hc_control); | 1737 | retval = u132_write_pcimem(u132, control, u132->hc_control); |
1783 | if (retval) | 1738 | if (retval) |
1784 | return retval; | 1739 | return retval; |
1785 | retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_BLF); | 1740 | retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF); |
1786 | if (retval) | 1741 | if (retval) |
1787 | return retval; | 1742 | return retval; |
1788 | retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); | 1743 | retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); |
@@ -1839,8 +1794,8 @@ static void u132_hcd_stop(struct usb_hcd *hcd) | |||
1839 | { | 1794 | { |
1840 | struct u132 *u132 = hcd_to_u132(hcd); | 1795 | struct u132 *u132 = hcd_to_u132(hcd); |
1841 | if (u132->going > 1) { | 1796 | if (u132->going > 1) { |
1842 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" | 1797 | dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b" |
1843 | , u132->going); | 1798 | "een removed %d\n", u132, hcd, u132->going); |
1844 | } else if (u132->going > 0) { | 1799 | } else if (u132->going > 0) { |
1845 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 1800 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
1846 | "ed\n", hcd); | 1801 | "ed\n", hcd); |
@@ -2545,8 +2500,9 @@ static void u132_endpoint_disable(struct usb_hcd *hcd, | |||
2545 | { | 2500 | { |
2546 | struct u132 *u132 = hcd_to_u132(hcd); | 2501 | struct u132 *u132 = hcd_to_u132(hcd); |
2547 | if (u132->going > 2) { | 2502 | if (u132->going > 2) { |
2548 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" | 2503 | dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p" |
2549 | , u132->going); | 2504 | ") has been removed %d\n", u132, hcd, hep, |
2505 | u132->going); | ||
2550 | } else { | 2506 | } else { |
2551 | struct u132_endp *endp = hep->hcpriv; | 2507 | struct u132_endp *endp = hep->hcpriv; |
2552 | if (endp) | 2508 | if (endp) |
@@ -2790,7 +2746,6 @@ static int u132_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
2790 | } else if (u132->going > 0) { | 2746 | } else if (u132->going > 0) { |
2791 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 2747 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
2792 | "ed\n", hcd); | 2748 | "ed\n", hcd); |
2793 | dump_stack(); | ||
2794 | return -ESHUTDOWN; | 2749 | return -ESHUTDOWN; |
2795 | } else { | 2750 | } else { |
2796 | int i, changed = 0, length = 1; | 2751 | int i, changed = 0, length = 1; |
@@ -3034,12 +2989,15 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3034 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 2989 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
3035 | if (hcd) { | 2990 | if (hcd) { |
3036 | struct u132 *u132 = hcd_to_u132(hcd); | 2991 | struct u132 *u132 = hcd_to_u132(hcd); |
3037 | dump_stack(); | ||
3038 | if (u132->going++ > 1) { | 2992 | if (u132->going++ > 1) { |
2993 | dev_err(&u132->platform_dev->dev, "already being remove" | ||
2994 | "d\n"); | ||
3039 | return -ENODEV; | 2995 | return -ENODEV; |
3040 | } else { | 2996 | } else { |
3041 | int rings = MAX_U132_RINGS; | 2997 | int rings = MAX_U132_RINGS; |
3042 | int endps = MAX_U132_ENDPS; | 2998 | int endps = MAX_U132_ENDPS; |
2999 | dev_err(&u132->platform_dev->dev, "removing device u132" | ||
3000 | ".%d\n", u132->sequence_num); | ||
3043 | msleep(100); | 3001 | msleep(100); |
3044 | down(&u132->sw_lock); | 3002 | down(&u132->sw_lock); |
3045 | u132_monitor_cancel_work(u132); | 3003 | u132_monitor_cancel_work(u132); |
@@ -3121,10 +3079,24 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3121 | static int __devinit u132_probe(struct platform_device *pdev) | 3079 | static int __devinit u132_probe(struct platform_device *pdev) |
3122 | { | 3080 | { |
3123 | struct usb_hcd *hcd; | 3081 | struct usb_hcd *hcd; |
3082 | int retval; | ||
3083 | u32 control; | ||
3084 | u32 rh_a = -1; | ||
3085 | u32 num_ports; | ||
3124 | msleep(100); | 3086 | msleep(100); |
3125 | if (u132_exiting > 0) { | 3087 | if (u132_exiting > 0) { |
3126 | return -ENODEV; | 3088 | return -ENODEV; |
3127 | } /* refuse to confuse usbcore */ | 3089 | } |
3090 | retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE); | ||
3091 | if (retval) | ||
3092 | return retval; | ||
3093 | retval = ftdi_read_pcimem(pdev, control, &control); | ||
3094 | if (retval) | ||
3095 | return retval; | ||
3096 | retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a); | ||
3097 | if (retval) | ||
3098 | return retval; | ||
3099 | num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */ | ||
3128 | if (pdev->dev.dma_mask) { | 3100 | if (pdev->dev.dma_mask) { |
3129 | return -EINVAL; | 3101 | return -EINVAL; |
3130 | } | 3102 | } |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index e87692c31be4..acd101caeeeb 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -60,6 +60,11 @@ Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ | |||
60 | Alan Stern" | 60 | Alan Stern" |
61 | #define DRIVER_DESC "USB Universal Host Controller Interface driver" | 61 | #define DRIVER_DESC "USB Universal Host Controller Interface driver" |
62 | 62 | ||
63 | /* for flakey hardware, ignore overcurrent indicators */ | ||
64 | static int ignore_oc; | ||
65 | module_param(ignore_oc, bool, S_IRUGO); | ||
66 | MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications"); | ||
67 | |||
63 | /* | 68 | /* |
64 | * debug = 0, no debugging messages | 69 | * debug = 0, no debugging messages |
65 | * debug = 1, dump failed URBs except for stalls | 70 | * debug = 1, dump failed URBs except for stalls |
@@ -169,6 +174,11 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) | |||
169 | { | 174 | { |
170 | int port; | 175 | int port; |
171 | 176 | ||
177 | /* If we have to ignore overcurrent events then almost by definition | ||
178 | * we can't depend on resume-detect interrupts. */ | ||
179 | if (ignore_oc) | ||
180 | return 1; | ||
181 | |||
172 | switch (to_pci_dev(uhci_dev(uhci))->vendor) { | 182 | switch (to_pci_dev(uhci_dev(uhci))->vendor) { |
173 | default: | 183 | default: |
174 | break; | 184 | break; |
@@ -921,7 +931,8 @@ static int __init uhci_hcd_init(void) | |||
921 | { | 931 | { |
922 | int retval = -ENOMEM; | 932 | int retval = -ENOMEM; |
923 | 933 | ||
924 | printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n"); | 934 | printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n", |
935 | ignore_oc ? ", overcurrent ignored" : ""); | ||
925 | 936 | ||
926 | if (usb_disabled()) | 937 | if (usb_disabled()) |
927 | return -ENODEV; | 938 | return -ENODEV; |
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index f8347f1a10b6..bacc25c53ba3 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -52,10 +52,20 @@ static int any_ports_active(struct uhci_hcd *uhci) | |||
52 | static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) | 52 | static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) |
53 | { | 53 | { |
54 | int port; | 54 | int port; |
55 | int mask = RWC_BITS; | ||
56 | |||
57 | /* Some boards (both VIA and Intel apparently) report bogus | ||
58 | * overcurrent indications, causing massive log spam unless | ||
59 | * we completely ignore them. This doesn't seem to be a problem | ||
60 | * with the chipset so much as with the way it is connected on | ||
61 | * the motherboard; if the overcurrent input is left to float | ||
62 | * then it may constantly register false positives. */ | ||
63 | if (ignore_oc) | ||
64 | mask &= ~USBPORTSC_OCC; | ||
55 | 65 | ||
56 | *buf = 0; | 66 | *buf = 0; |
57 | for (port = 0; port < uhci->rh_numports; ++port) { | 67 | for (port = 0; port < uhci->rh_numports; ++port) { |
58 | if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) || | 68 | if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) || |
59 | test_bit(port, &uhci->port_c_suspend)) | 69 | test_bit(port, &uhci->port_c_suspend)) |
60 | *buf |= (1 << (port + 1)); | 70 | *buf |= (1 << (port + 1)); |
61 | } | 71 | } |
@@ -263,7 +273,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
263 | wPortChange |= USB_PORT_STAT_C_CONNECTION; | 273 | wPortChange |= USB_PORT_STAT_C_CONNECTION; |
264 | if (status & USBPORTSC_PEC) | 274 | if (status & USBPORTSC_PEC) |
265 | wPortChange |= USB_PORT_STAT_C_ENABLE; | 275 | wPortChange |= USB_PORT_STAT_C_ENABLE; |
266 | if (status & USBPORTSC_OCC) | 276 | if ((status & USBPORTSC_OCC) && !ignore_oc) |
267 | wPortChange |= USB_PORT_STAT_C_OVERCURRENT; | 277 | wPortChange |= USB_PORT_STAT_C_OVERCURRENT; |
268 | 278 | ||
269 | if (test_bit(port, &uhci->port_c_suspend)) { | 279 | if (test_bit(port, &uhci->port_c_suspend)) { |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 8a62d4785755..e308f6dc2b87 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -7,7 +7,8 @@ comment "USB Input Devices" | |||
7 | config USB_HID | 7 | config USB_HID |
8 | tristate "USB Human Interface Device (full HID) support" | 8 | tristate "USB Human Interface Device (full HID) support" |
9 | default y | 9 | default y |
10 | depends on USB && HID | 10 | depends on USB |
11 | select HID | ||
11 | ---help--- | 12 | ---help--- |
12 | Say Y here if you want full HID support to connect USB keyboards, | 13 | Say Y here if you want full HID support to connect USB keyboards, |
13 | mice, joysticks, graphic tablets, or any other HID based devices | 14 | mice, joysticks, graphic tablets, or any other HID based devices |
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c index e7cc20ab8155..12b42746ded8 100644 --- a/drivers/usb/input/wacom_sys.c +++ b/drivers/usb/input/wacom_sys.c | |||
@@ -159,13 +159,13 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
159 | { | 159 | { |
160 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 160 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
161 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); | 161 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); |
162 | input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0); | 162 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
163 | } | 163 | } |
164 | 164 | ||
165 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 165 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
166 | { | 166 | { |
167 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); | 167 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); |
168 | input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0); | 168 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
169 | } | 169 | } |
170 | 170 | ||
171 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 171 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c index 92726fe89379..4142e36730fc 100644 --- a/drivers/usb/input/wacom_wac.c +++ b/drivers/usb/input/wacom_wac.c | |||
@@ -209,13 +209,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); |
211 | } | 211 | } |
212 | } | ||
213 | |||
214 | if (data[1] & 0x10) | ||
215 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ | 212 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ |
213 | } | ||
216 | else | 214 | else |
217 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 215 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ |
218 | wacom_report_key(wcombo, wacom->tool[0], data[1] & 0x10); | 216 | |
217 | if (data[1] & 0x10) /* only report prox-in when in area */ | ||
218 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
219 | if (!(data[1] & 0x90)) /* report prox-out when physically out */ | ||
220 | wacom_report_key(wcombo, wacom->tool[0], 0); | ||
219 | wacom_input_sync(wcombo); | 221 | wacom_input_sync(wcombo); |
220 | 222 | ||
221 | /* send pad data */ | 223 | /* send pad data */ |
@@ -405,7 +407,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
405 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) | 407 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) |
406 | return 0; | 408 | return 0; |
407 | 409 | ||
408 | if (wacom->features->type >= INTUOS3) { | 410 | if (wacom->features->type >= INTUOS3S) { |
409 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); | 411 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); |
410 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); | 412 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); |
411 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); | 413 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); |
@@ -423,7 +425,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
423 | 425 | ||
424 | if (data[1] & 0x02) { | 426 | if (data[1] & 0x02) { |
425 | /* Rotation packet */ | 427 | /* Rotation packet */ |
426 | if (wacom->features->type >= INTUOS3) { | 428 | if (wacom->features->type >= INTUOS3S) { |
427 | /* I3 marker pen rotation reported as wheel | 429 | /* I3 marker pen rotation reported as wheel |
428 | * due to valuator limitation | 430 | * due to valuator limitation |
429 | */ | 431 | */ |
@@ -547,11 +549,11 @@ static struct wacom_features wacom_features[] = { | |||
547 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, | 549 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, |
548 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, | 550 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, |
549 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, | 551 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, |
550 | { "Wacom Volito", 8, 5104, 3712, 511, 0, GRAPHIRE }, | 552 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
551 | { "Wacom PenStation2", 8, 3250, 2320, 255, 0, GRAPHIRE }, | 553 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, |
552 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 0, GRAPHIRE }, | 554 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
553 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 0, GRAPHIRE }, | 555 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, |
554 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 0, GRAPHIRE }, | 556 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE }, |
555 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, | 557 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, |
556 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, | 558 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, |
557 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, | 559 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, |
@@ -580,7 +582,7 @@ static struct wacom_features wacom_features[] = { | |||
580 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, | 582 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, |
581 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, | 583 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, |
582 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, | 584 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, |
583 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 15, INTUOS3S }, | 585 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, |
584 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 586 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, |
585 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, | 587 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, |
586 | { } | 588 | { } |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 6c7f3efb1d40..b5332e679c46 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -1376,7 +1376,7 @@ static int auerchar_open (struct inode *inode, struct file *file) | |||
1376 | } | 1376 | } |
1377 | 1377 | ||
1378 | /* we have access to the device. Now lets allocate memory */ | 1378 | /* we have access to the device. Now lets allocate memory */ |
1379 | ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL); | 1379 | ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL); |
1380 | if (ccp == NULL) { | 1380 | if (ccp == NULL) { |
1381 | err ("out of memory"); | 1381 | err ("out of memory"); |
1382 | ret = -ENOMEM; | 1382 | ret = -ENOMEM; |
@@ -1384,7 +1384,6 @@ static int auerchar_open (struct inode *inode, struct file *file) | |||
1384 | } | 1384 | } |
1385 | 1385 | ||
1386 | /* Initialize device descriptor */ | 1386 | /* Initialize device descriptor */ |
1387 | memset( ccp, 0, sizeof(auerchar_t)); | ||
1388 | init_MUTEX( &ccp->mutex); | 1387 | init_MUTEX( &ccp->mutex); |
1389 | init_MUTEX( &ccp->readmutex); | 1388 | init_MUTEX( &ccp->readmutex); |
1390 | auerbuf_init (&ccp->bufctl); | 1389 | auerbuf_init (&ccp->bufctl); |
@@ -1912,14 +1911,13 @@ static int auerswald_probe (struct usb_interface *intf, | |||
1912 | return -ENODEV; | 1911 | return -ENODEV; |
1913 | 1912 | ||
1914 | /* allocate memory for our device and initialize it */ | 1913 | /* allocate memory for our device and initialize it */ |
1915 | cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL); | 1914 | cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL); |
1916 | if (cp == NULL) { | 1915 | if (cp == NULL) { |
1917 | err ("out of memory"); | 1916 | err ("out of memory"); |
1918 | goto pfail; | 1917 | goto pfail; |
1919 | } | 1918 | } |
1920 | 1919 | ||
1921 | /* Initialize device descriptor */ | 1920 | /* Initialize device descriptor */ |
1922 | memset (cp, 0, sizeof(auerswald_t)); | ||
1923 | init_MUTEX (&cp->mutex); | 1921 | init_MUTEX (&cp->mutex); |
1924 | cp->usbdev = usbdev; | 1922 | cp->usbdev = usbdev; |
1925 | auerchain_init (&cp->controlchain); | 1923 | auerchain_init (&cp->controlchain); |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 18b1925032a8..41c0161abdb9 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/ioctl.h> | 42 | #include <linux/ioctl.h> |
43 | #include <linux/pci_ids.h> | ||
43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
44 | #include <linux/module.h> | 45 | #include <linux/module.h> |
45 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
@@ -51,6 +52,10 @@ MODULE_AUTHOR("Tony Olech"); | |||
51 | MODULE_DESCRIPTION("FTDI ELAN driver"); | 52 | MODULE_DESCRIPTION("FTDI ELAN driver"); |
52 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
53 | #define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444) | 54 | #define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444) |
55 | static int distrust_firmware = 1; | ||
56 | module_param(distrust_firmware, bool, 0); | ||
57 | MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren" | ||
58 | "t setup"); | ||
54 | extern struct platform_driver u132_platform_driver; | 59 | extern struct platform_driver u132_platform_driver; |
55 | static struct workqueue_struct *status_queue; | 60 | static struct workqueue_struct *status_queue; |
56 | static struct workqueue_struct *command_queue; | 61 | static struct workqueue_struct *command_queue; |
@@ -66,7 +71,9 @@ static struct list_head ftdi_static_list; | |||
66 | * end of the global variables protected by ftdi_module_lock | 71 | * end of the global variables protected by ftdi_module_lock |
67 | */ | 72 | */ |
68 | #include "usb_u132.h" | 73 | #include "usb_u132.h" |
69 | #define TD_DEVNOTRESP 5 | 74 | #include <asm/io.h> |
75 | #include "../core/hcd.h" | ||
76 | #include "../host/ohci.h" | ||
70 | /* Define these values to match your devices*/ | 77 | /* Define these values to match your devices*/ |
71 | #define USB_FTDI_ELAN_VENDOR_ID 0x0403 | 78 | #define USB_FTDI_ELAN_VENDOR_ID 0x0403 |
72 | #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea | 79 | #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea |
@@ -551,7 +558,7 @@ static void ftdi_elan_status_work(struct work_struct *work) | |||
551 | } else { | 558 | } else { |
552 | dev_err(&ftdi->udev->dev, "initialized failed - trying " | 559 | dev_err(&ftdi->udev->dev, "initialized failed - trying " |
553 | "again in 10 seconds\n"); | 560 | "again in 10 seconds\n"); |
554 | work_delay_in_msec = 10 *1000; | 561 | work_delay_in_msec = 1 *1000; |
555 | } | 562 | } |
556 | } else if (ftdi->registered == 0) { | 563 | } else if (ftdi->registered == 0) { |
557 | work_delay_in_msec = 10; | 564 | work_delay_in_msec = 10; |
@@ -2288,82 +2295,288 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi) | |||
2288 | } | 2295 | } |
2289 | } | 2296 | } |
2290 | 2297 | ||
2291 | static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | 2298 | |
2299 | #define ftdi_read_pcimem(ftdi, member, data) ftdi_elan_read_pcimem(ftdi, \ | ||
2300 | offsetof(struct ohci_regs, member), 0, data); | ||
2301 | #define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \ | ||
2302 | offsetof(struct ohci_regs, member), 0, data); | ||
2303 | #define OHCI_QUIRK_AMD756 0x01 | ||
2304 | #define OHCI_QUIRK_SUPERIO 0x02 | ||
2305 | #define OHCI_QUIRK_INITRESET 0x04 | ||
2306 | #define OHCI_BIG_ENDIAN 0x08 | ||
2307 | #define OHCI_QUIRK_ZFMICRO 0x10 | ||
2308 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR | ||
2309 | #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ | ||
2310 | OHCI_INTR_WDH) | ||
2311 | static int ftdi_elan_check_controller(struct usb_ftdi *ftdi, int quirk) | ||
2312 | { | ||
2313 | int devices = 0; | ||
2314 | int retval; | ||
2315 | u32 hc_control; | ||
2316 | int num_ports; | ||
2317 | u32 control; | ||
2318 | u32 rh_a = -1; | ||
2319 | u32 status; | ||
2320 | u32 fminterval; | ||
2321 | u32 hc_fminterval; | ||
2322 | u32 periodicstart; | ||
2323 | u32 cmdstatus; | ||
2324 | u32 roothub_a; | ||
2325 | int mask = OHCI_INTR_INIT; | ||
2326 | int sleep_time = 0; | ||
2327 | int reset_timeout = 30; /* ... allow extra time */ | ||
2328 | int temp; | ||
2329 | retval = ftdi_write_pcimem(ftdi, intrdisable, OHCI_INTR_MIE); | ||
2330 | if (retval) | ||
2331 | return retval; | ||
2332 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2333 | if (retval) | ||
2334 | return retval; | ||
2335 | retval = ftdi_read_pcimem(ftdi, roothub.a, &rh_a); | ||
2336 | if (retval) | ||
2337 | return retval; | ||
2338 | num_ports = rh_a & RH_A_NDP; | ||
2339 | retval = ftdi_read_pcimem(ftdi, fminterval, &hc_fminterval); | ||
2340 | if (retval) | ||
2341 | return retval; | ||
2342 | hc_fminterval &= 0x3fff; | ||
2343 | if (hc_fminterval != FI) { | ||
2344 | } | ||
2345 | hc_fminterval |= FSMP(hc_fminterval) << 16; | ||
2346 | retval = ftdi_read_pcimem(ftdi, control, &hc_control); | ||
2347 | if (retval) | ||
2348 | return retval; | ||
2349 | switch (hc_control & OHCI_CTRL_HCFS) { | ||
2350 | case OHCI_USB_OPER: | ||
2351 | sleep_time = 0; | ||
2352 | break; | ||
2353 | case OHCI_USB_SUSPEND: | ||
2354 | case OHCI_USB_RESUME: | ||
2355 | hc_control &= OHCI_CTRL_RWC; | ||
2356 | hc_control |= OHCI_USB_RESUME; | ||
2357 | sleep_time = 10; | ||
2358 | break; | ||
2359 | default: | ||
2360 | hc_control &= OHCI_CTRL_RWC; | ||
2361 | hc_control |= OHCI_USB_RESET; | ||
2362 | sleep_time = 50; | ||
2363 | break; | ||
2364 | } | ||
2365 | retval = ftdi_write_pcimem(ftdi, control, hc_control); | ||
2366 | if (retval) | ||
2367 | return retval; | ||
2368 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2369 | if (retval) | ||
2370 | return retval; | ||
2371 | msleep(sleep_time); | ||
2372 | retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a); | ||
2373 | if (retval) | ||
2374 | return retval; | ||
2375 | if (!(roothub_a & RH_A_NPS)) { /* power down each port */ | ||
2376 | for (temp = 0; temp < num_ports; temp++) { | ||
2377 | retval = ftdi_write_pcimem(ftdi, | ||
2378 | roothub.portstatus[temp], RH_PS_LSDA); | ||
2379 | if (retval) | ||
2380 | return retval; | ||
2381 | } | ||
2382 | } | ||
2383 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2384 | if (retval) | ||
2385 | return retval; | ||
2386 | retry:retval = ftdi_read_pcimem(ftdi, cmdstatus, &status); | ||
2387 | if (retval) | ||
2388 | return retval; | ||
2389 | retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_HCR); | ||
2390 | if (retval) | ||
2391 | return retval; | ||
2392 | extra:{ | ||
2393 | retval = ftdi_read_pcimem(ftdi, cmdstatus, &status); | ||
2394 | if (retval) | ||
2395 | return retval; | ||
2396 | if (0 != (status & OHCI_HCR)) { | ||
2397 | if (--reset_timeout == 0) { | ||
2398 | dev_err(&ftdi->udev->dev, "USB HC reset timed o" | ||
2399 | "ut!\n"); | ||
2400 | return -ENODEV; | ||
2401 | } else { | ||
2402 | msleep(5); | ||
2403 | goto extra; | ||
2404 | } | ||
2405 | } | ||
2406 | } | ||
2407 | if (quirk & OHCI_QUIRK_INITRESET) { | ||
2408 | retval = ftdi_write_pcimem(ftdi, control, hc_control); | ||
2409 | if (retval) | ||
2410 | return retval; | ||
2411 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2412 | if (retval) | ||
2413 | return retval; | ||
2414 | } | ||
2415 | retval = ftdi_write_pcimem(ftdi, ed_controlhead, 0x00000000); | ||
2416 | if (retval) | ||
2417 | return retval; | ||
2418 | retval = ftdi_write_pcimem(ftdi, ed_bulkhead, 0x11000000); | ||
2419 | if (retval) | ||
2420 | return retval; | ||
2421 | retval = ftdi_write_pcimem(ftdi, hcca, 0x00000000); | ||
2422 | if (retval) | ||
2423 | return retval; | ||
2424 | retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval); | ||
2425 | if (retval) | ||
2426 | return retval; | ||
2427 | retval = ftdi_write_pcimem(ftdi, fminterval, | ||
2428 | ((fminterval & FIT) ^ FIT) | hc_fminterval); | ||
2429 | if (retval) | ||
2430 | return retval; | ||
2431 | retval = ftdi_write_pcimem(ftdi, periodicstart, | ||
2432 | ((9 *hc_fminterval) / 10) & 0x3fff); | ||
2433 | if (retval) | ||
2434 | return retval; | ||
2435 | retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval); | ||
2436 | if (retval) | ||
2437 | return retval; | ||
2438 | retval = ftdi_read_pcimem(ftdi, periodicstart, &periodicstart); | ||
2439 | if (retval) | ||
2440 | return retval; | ||
2441 | if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) { | ||
2442 | if (!(quirk & OHCI_QUIRK_INITRESET)) { | ||
2443 | quirk |= OHCI_QUIRK_INITRESET; | ||
2444 | goto retry; | ||
2445 | } else | ||
2446 | dev_err(&ftdi->udev->dev, "init err(%08x %04x)\n", | ||
2447 | fminterval, periodicstart); | ||
2448 | } /* start controller operations */ | ||
2449 | hc_control &= OHCI_CTRL_RWC; | ||
2450 | hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER; | ||
2451 | retval = ftdi_write_pcimem(ftdi, control, hc_control); | ||
2452 | if (retval) | ||
2453 | return retval; | ||
2454 | retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_BLF); | ||
2455 | if (retval) | ||
2456 | return retval; | ||
2457 | retval = ftdi_read_pcimem(ftdi, cmdstatus, &cmdstatus); | ||
2458 | if (retval) | ||
2459 | return retval; | ||
2460 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2461 | if (retval) | ||
2462 | return retval; | ||
2463 | retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_DRWE); | ||
2464 | if (retval) | ||
2465 | return retval; | ||
2466 | retval = ftdi_write_pcimem(ftdi, intrstatus, mask); | ||
2467 | if (retval) | ||
2468 | return retval; | ||
2469 | retval = ftdi_write_pcimem(ftdi, intrdisable, | ||
2470 | OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO | | ||
2471 | OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH | | ||
2472 | OHCI_INTR_SO); | ||
2473 | if (retval) | ||
2474 | return retval; /* handle root hub init quirks ... */ | ||
2475 | retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a); | ||
2476 | if (retval) | ||
2477 | return retval; | ||
2478 | roothub_a &= ~(RH_A_PSM | RH_A_OCPM); | ||
2479 | if (quirk & OHCI_QUIRK_SUPERIO) { | ||
2480 | roothub_a |= RH_A_NOCP; | ||
2481 | roothub_a &= ~(RH_A_POTPGT | RH_A_NPS); | ||
2482 | retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a); | ||
2483 | if (retval) | ||
2484 | return retval; | ||
2485 | } else if ((quirk & OHCI_QUIRK_AMD756) || distrust_firmware) { | ||
2486 | roothub_a |= RH_A_NPS; | ||
2487 | retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a); | ||
2488 | if (retval) | ||
2489 | return retval; | ||
2490 | } | ||
2491 | retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_LPSC); | ||
2492 | if (retval) | ||
2493 | return retval; | ||
2494 | retval = ftdi_write_pcimem(ftdi, roothub.b, | ||
2495 | (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM); | ||
2496 | if (retval) | ||
2497 | return retval; | ||
2498 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2499 | if (retval) | ||
2500 | return retval; | ||
2501 | mdelay((roothub_a >> 23) & 0x1fe); | ||
2502 | for (temp = 0; temp < num_ports; temp++) { | ||
2503 | u32 portstatus; | ||
2504 | retval = ftdi_read_pcimem(ftdi, roothub.portstatus[temp], | ||
2505 | &portstatus); | ||
2506 | if (retval) | ||
2507 | return retval; | ||
2508 | if (1 & portstatus) | ||
2509 | devices += 1; | ||
2510 | } | ||
2511 | return devices; | ||
2512 | } | ||
2513 | |||
2514 | static int ftdi_elan_setup_controller(struct usb_ftdi *ftdi, int fn) | ||
2292 | { | 2515 | { |
2293 | u32 latence_timer; | 2516 | u32 latence_timer; |
2294 | u32 controlreg; | ||
2295 | int UxxxStatus; | 2517 | int UxxxStatus; |
2296 | u32 pcidata; | 2518 | u32 pcidata; |
2297 | int reg = 0; | 2519 | int reg = 0; |
2298 | int foundOHCI = 0; | 2520 | int activePCIfn = fn << 8; |
2299 | u8 fn; | 2521 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); |
2300 | int activePCIfn = 0; | ||
2301 | u32 pciVID = 0; | ||
2302 | u32 pciPID = 0; | ||
2303 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2304 | if (UxxxStatus) | ||
2305 | return UxxxStatus; | ||
2306 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L); | ||
2307 | if (UxxxStatus) | ||
2308 | return UxxxStatus; | ||
2309 | msleep(750); | ||
2310 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100); | ||
2311 | if (UxxxStatus) | 2522 | if (UxxxStatus) |
2312 | return UxxxStatus; | 2523 | return UxxxStatus; |
2313 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500); | 2524 | reg = 16; |
2525 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, | ||
2526 | 0xFFFFFFFF); | ||
2314 | if (UxxxStatus) | 2527 | if (UxxxStatus) |
2315 | return UxxxStatus; | 2528 | return UxxxStatus; |
2316 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2529 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2530 | &pcidata); | ||
2317 | if (UxxxStatus) | 2531 | if (UxxxStatus) |
2318 | return UxxxStatus; | 2532 | return UxxxStatus; |
2319 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000); | 2533 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, |
2534 | 0xF0000000); | ||
2320 | if (UxxxStatus) | 2535 | if (UxxxStatus) |
2321 | return UxxxStatus; | 2536 | return UxxxStatus; |
2322 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000); | 2537 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2538 | &pcidata); | ||
2323 | if (UxxxStatus) | 2539 | if (UxxxStatus) |
2324 | return UxxxStatus; | 2540 | return UxxxStatus; |
2325 | msleep(250); | 2541 | reg = 12; |
2326 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000); | 2542 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2543 | &latence_timer); | ||
2327 | if (UxxxStatus) | 2544 | if (UxxxStatus) |
2328 | return UxxxStatus; | 2545 | return UxxxStatus; |
2329 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2546 | latence_timer &= 0xFFFF00FF; |
2547 | latence_timer |= 0x00001600; | ||
2548 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, | ||
2549 | latence_timer); | ||
2330 | if (UxxxStatus) | 2550 | if (UxxxStatus) |
2331 | return UxxxStatus; | 2551 | return UxxxStatus; |
2332 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800); | 2552 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2553 | &pcidata); | ||
2333 | if (UxxxStatus) | 2554 | if (UxxxStatus) |
2334 | return UxxxStatus; | 2555 | return UxxxStatus; |
2335 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2556 | reg = 4; |
2557 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, | ||
2558 | 0x06); | ||
2336 | if (UxxxStatus) | 2559 | if (UxxxStatus) |
2337 | return UxxxStatus; | 2560 | return UxxxStatus; |
2338 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2561 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2562 | &pcidata); | ||
2339 | if (UxxxStatus) | 2563 | if (UxxxStatus) |
2340 | return UxxxStatus; | 2564 | return UxxxStatus; |
2341 | msleep(1000); | 2565 | for (reg = 0; reg <= 0x54; reg += 4) { |
2342 | for (fn = 0; (fn < 4) && (!foundOHCI); fn++) { | 2566 | UxxxStatus = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); |
2343 | activePCIfn = fn << 8; | ||
2344 | ftdi->function = fn + 1; | ||
2345 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, | ||
2346 | &pcidata); | ||
2347 | if (UxxxStatus) | 2567 | if (UxxxStatus) |
2348 | return UxxxStatus; | 2568 | return UxxxStatus; |
2349 | pciVID = pcidata & 0xFFFF; | ||
2350 | pciPID = (pcidata >> 16) & 0xFFFF; | ||
2351 | if ((pciVID == 0x1045) && (pciPID == 0xc861)) { | ||
2352 | foundOHCI = 1; | ||
2353 | } else if ((pciVID == 0x1033) && (pciPID == 0x0035)) { | ||
2354 | foundOHCI = 1; | ||
2355 | } else if ((pciVID == 0x10b9) && (pciPID == 0x5237)) { | ||
2356 | foundOHCI = 1; | ||
2357 | } else if ((pciVID == 0x11c1) && (pciPID == 0x5802)) { | ||
2358 | foundOHCI = 1; | ||
2359 | } else if ((pciVID == 0x11AB) && (pciPID == 0x1FA6)) { | ||
2360 | } | ||
2361 | } | ||
2362 | if (foundOHCI == 0) { | ||
2363 | return -ENXIO; | ||
2364 | } | 2569 | } |
2365 | ftdi->platform_data.vendor = pciVID; | 2570 | return 0; |
2366 | ftdi->platform_data.device = pciPID; | 2571 | } |
2572 | |||
2573 | static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn) | ||
2574 | { | ||
2575 | u32 latence_timer; | ||
2576 | int UxxxStatus; | ||
2577 | u32 pcidata; | ||
2578 | int reg = 0; | ||
2579 | int activePCIfn = fn << 8; | ||
2367 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); | 2580 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); |
2368 | if (UxxxStatus) | 2581 | if (UxxxStatus) |
2369 | return UxxxStatus; | 2582 | return UxxxStatus; |
@@ -2377,7 +2590,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | |||
2377 | if (UxxxStatus) | 2590 | if (UxxxStatus) |
2378 | return UxxxStatus; | 2591 | return UxxxStatus; |
2379 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, | 2592 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, |
2380 | 0xF0000000); | 2593 | 0x00000000); |
2381 | if (UxxxStatus) | 2594 | if (UxxxStatus) |
2382 | return UxxxStatus; | 2595 | return UxxxStatus; |
2383 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, | 2596 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
@@ -2401,7 +2614,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | |||
2401 | return UxxxStatus; | 2614 | return UxxxStatus; |
2402 | reg = 4; | 2615 | reg = 4; |
2403 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, | 2616 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, |
2404 | 0x06); | 2617 | 0x00); |
2405 | if (UxxxStatus) | 2618 | if (UxxxStatus) |
2406 | return UxxxStatus; | 2619 | return UxxxStatus; |
2407 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, | 2620 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
@@ -2411,159 +2624,139 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | |||
2411 | return 0; | 2624 | return 0; |
2412 | } | 2625 | } |
2413 | 2626 | ||
2627 | static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk) | ||
2628 | { | ||
2629 | int result; | ||
2630 | int UxxxStatus; | ||
2631 | UxxxStatus = ftdi_elan_setup_controller(ftdi, fn); | ||
2632 | if (UxxxStatus) | ||
2633 | return UxxxStatus; | ||
2634 | result = ftdi_elan_check_controller(ftdi, quirk); | ||
2635 | UxxxStatus = ftdi_elan_close_controller(ftdi, fn); | ||
2636 | if (UxxxStatus) | ||
2637 | return UxxxStatus; | ||
2638 | return result; | ||
2639 | } | ||
2640 | |||
2641 | static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | ||
2642 | { | ||
2643 | u32 controlreg; | ||
2644 | u8 sensebits; | ||
2645 | int UxxxStatus; | ||
2646 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2647 | if (UxxxStatus) | ||
2648 | return UxxxStatus; | ||
2649 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L); | ||
2650 | if (UxxxStatus) | ||
2651 | return UxxxStatus; | ||
2652 | msleep(750); | ||
2653 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100); | ||
2654 | if (UxxxStatus) | ||
2655 | return UxxxStatus; | ||
2656 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500); | ||
2657 | if (UxxxStatus) | ||
2658 | return UxxxStatus; | ||
2659 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2660 | if (UxxxStatus) | ||
2661 | return UxxxStatus; | ||
2662 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000); | ||
2663 | if (UxxxStatus) | ||
2664 | return UxxxStatus; | ||
2665 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000); | ||
2666 | if (UxxxStatus) | ||
2667 | return UxxxStatus; | ||
2668 | msleep(250); | ||
2669 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000); | ||
2670 | if (UxxxStatus) | ||
2671 | return UxxxStatus; | ||
2672 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2673 | if (UxxxStatus) | ||
2674 | return UxxxStatus; | ||
2675 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800); | ||
2676 | if (UxxxStatus) | ||
2677 | return UxxxStatus; | ||
2678 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2679 | if (UxxxStatus) | ||
2680 | return UxxxStatus; | ||
2681 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2682 | if (UxxxStatus) | ||
2683 | return UxxxStatus; | ||
2684 | msleep(1000); | ||
2685 | sensebits = (controlreg >> 16) & 0x000F; | ||
2686 | if (0x0D == sensebits) | ||
2687 | return 0; | ||
2688 | else | ||
2689 | return - ENXIO; | ||
2690 | } | ||
2691 | |||
2414 | static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi) | 2692 | static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi) |
2415 | { | 2693 | { |
2694 | int UxxxStatus; | ||
2416 | u32 pcidata; | 2695 | u32 pcidata; |
2417 | int U132Status; | 2696 | int reg = 0; |
2418 | int reg; | 2697 | u8 fn; |
2419 | int reset_repeat = 0; | 2698 | int activePCIfn = 0; |
2420 | do_reset:reg = 8; | 2699 | int max_devices = 0; |
2421 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x01); | 2700 | int controllers = 0; |
2422 | if (U132Status) | 2701 | int unrecognized = 0; |
2423 | return U132Status; | 2702 | ftdi->function = 0; |
2424 | reset_check:{ | 2703 | for (fn = 0; (fn < 4); fn++) { |
2425 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | 2704 | u32 pciVID = 0; |
2426 | if (U132Status) | 2705 | u32 pciPID = 0; |
2427 | return U132Status; | 2706 | int devices = 0; |
2428 | if (pcidata & 1) { | 2707 | activePCIfn = fn << 8; |
2429 | msleep(500); | 2708 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2430 | if (reset_repeat++ > 100) { | 2709 | &pcidata); |
2431 | reset_repeat = 0; | 2710 | if (UxxxStatus) |
2432 | goto do_reset; | 2711 | return UxxxStatus; |
2433 | } else | 2712 | pciVID = pcidata & 0xFFFF; |
2434 | goto reset_check; | 2713 | pciPID = (pcidata >> 16) & 0xFFFF; |
2714 | if ((pciVID == PCI_VENDOR_ID_OPTI) && (pciPID == 0xc861)) { | ||
2715 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2716 | controllers += 1; | ||
2717 | } else if ((pciVID == PCI_VENDOR_ID_NEC) && (pciPID == 0x0035)) | ||
2718 | { | ||
2719 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2720 | controllers += 1; | ||
2721 | } else if ((pciVID == PCI_VENDOR_ID_AL) && (pciPID == 0x5237)) { | ||
2722 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2723 | controllers += 1; | ||
2724 | } else if ((pciVID == PCI_VENDOR_ID_ATT) && (pciPID == 0x5802)) | ||
2725 | { | ||
2726 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2727 | controllers += 1; | ||
2728 | } else if (pciVID == PCI_VENDOR_ID_AMD && pciPID == 0x740c) { | ||
2729 | devices = ftdi_elan_found_controller(ftdi, fn, | ||
2730 | OHCI_QUIRK_AMD756); | ||
2731 | controllers += 1; | ||
2732 | } else if (pciVID == PCI_VENDOR_ID_COMPAQ && pciPID == 0xa0f8) { | ||
2733 | devices = ftdi_elan_found_controller(ftdi, fn, | ||
2734 | OHCI_QUIRK_ZFMICRO); | ||
2735 | controllers += 1; | ||
2736 | } else if (0 == pcidata) { | ||
2737 | } else | ||
2738 | unrecognized += 1; | ||
2739 | if (devices > max_devices) { | ||
2740 | max_devices = devices; | ||
2741 | ftdi->function = fn + 1; | ||
2742 | ftdi->platform_data.vendor = pciVID; | ||
2743 | ftdi->platform_data.device = pciPID; | ||
2435 | } | 2744 | } |
2436 | } | 2745 | } |
2437 | goto dump_regs; | 2746 | if (ftdi->function > 0) { |
2438 | msleep(500); | 2747 | UxxxStatus = ftdi_elan_setup_controller(ftdi, |
2439 | reg = 0x28; | 2748 | ftdi->function - 1); |
2440 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x11000000); | 2749 | if (UxxxStatus) |
2441 | if (U132Status) | 2750 | return UxxxStatus; |
2442 | return U132Status; | 2751 | return 0; |
2443 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | 2752 | } else if (controllers > 0) { |
2444 | if (U132Status) | 2753 | return -ENXIO; |
2445 | return U132Status; | 2754 | } else if (unrecognized > 0) { |
2446 | reg = 0x40; | 2755 | return -ENXIO; |
2447 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf); | 2756 | } else { |
2448 | if (U132Status) | 2757 | ftdi->enumerated = 0; |
2449 | return U132Status; | 2758 | return -ENXIO; |
2450 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2451 | if (U132Status) | ||
2452 | return U132Status; | ||
2453 | reg = 0x34; | ||
2454 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf2edf); | ||
2455 | if (U132Status) | ||
2456 | return U132Status; | ||
2457 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2458 | if (U132Status) | ||
2459 | return U132Status; | ||
2460 | reg = 4; | ||
2461 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0xA0); | ||
2462 | if (U132Status) | ||
2463 | return U132Status; | ||
2464 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2465 | if (U132Status) | ||
2466 | return U132Status; | ||
2467 | msleep(250); | ||
2468 | reg = 8; | ||
2469 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x04); | ||
2470 | if (U132Status) | ||
2471 | return U132Status; | ||
2472 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2473 | if (U132Status) | ||
2474 | return U132Status; | ||
2475 | reg = 0x28; | ||
2476 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2477 | if (U132Status) | ||
2478 | return U132Status; | ||
2479 | reg = 8; | ||
2480 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2481 | if (U132Status) | ||
2482 | return U132Status; | ||
2483 | reg = 0x48; | ||
2484 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x00001200); | ||
2485 | if (U132Status) | ||
2486 | return U132Status; | ||
2487 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2488 | if (U132Status) | ||
2489 | return U132Status; | ||
2490 | reg = 0x54; | ||
2491 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2492 | if (U132Status) | ||
2493 | return U132Status; | ||
2494 | reg = 0x58; | ||
2495 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2496 | if (U132Status) | ||
2497 | return U132Status; | ||
2498 | reg = 0x34; | ||
2499 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x28002edf); | ||
2500 | if (U132Status) | ||
2501 | return U132Status; | ||
2502 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2503 | if (U132Status) | ||
2504 | return U132Status; | ||
2505 | msleep(100); | ||
2506 | reg = 0x50; | ||
2507 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10000); | ||
2508 | if (U132Status) | ||
2509 | return U132Status; | ||
2510 | reg = 0x54; | ||
2511 | power_check:U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2512 | if (U132Status) | ||
2513 | return U132Status; | ||
2514 | if (!(pcidata & 1)) { | ||
2515 | msleep(500); | ||
2516 | goto power_check; | ||
2517 | } | ||
2518 | msleep(3000); | ||
2519 | reg = 0x54; | ||
2520 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2521 | if (U132Status) | ||
2522 | return U132Status; | ||
2523 | reg = 0x58; | ||
2524 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2525 | if (U132Status) | ||
2526 | return U132Status; | ||
2527 | reg = 0x54; | ||
2528 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02); | ||
2529 | if (U132Status) | ||
2530 | return U132Status; | ||
2531 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2532 | if (U132Status) | ||
2533 | return U132Status; | ||
2534 | reg = 0x54; | ||
2535 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10); | ||
2536 | if (U132Status) | ||
2537 | return U132Status; | ||
2538 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2539 | if (U132Status) | ||
2540 | return U132Status; | ||
2541 | msleep(750); | ||
2542 | reg = 0x54; | ||
2543 | if (0) { | ||
2544 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02); | ||
2545 | if (U132Status) | ||
2546 | return U132Status; | ||
2547 | } | ||
2548 | if (0) { | ||
2549 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2550 | if (U132Status) | ||
2551 | return U132Status; | ||
2552 | } | ||
2553 | reg = 0x54; | ||
2554 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2555 | if (U132Status) | ||
2556 | return U132Status; | ||
2557 | reg = 0x58; | ||
2558 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2559 | if (U132Status) | ||
2560 | return U132Status; | ||
2561 | dump_regs:for (reg = 0; reg <= 0x54; reg += 4) { | ||
2562 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2563 | if (U132Status) | ||
2564 | return U132Status; | ||
2565 | } | 2759 | } |
2566 | return 0; | ||
2567 | } | 2760 | } |
2568 | 2761 | ||
2569 | 2762 | ||
@@ -2688,6 +2881,7 @@ static void ftdi_elan_disconnect(struct usb_interface *interface) | |||
2688 | platform_device_unregister(&ftdi->platform_dev); | 2881 | platform_device_unregister(&ftdi->platform_dev); |
2689 | ftdi->synchronized = 0; | 2882 | ftdi->synchronized = 0; |
2690 | ftdi->enumerated = 0; | 2883 | ftdi->enumerated = 0; |
2884 | ftdi->initialized = 0; | ||
2691 | ftdi->registered = 0; | 2885 | ftdi->registered = 0; |
2692 | } | 2886 | } |
2693 | flush_workqueue(status_queue); | 2887 | flush_workqueue(status_queue); |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 7163f05c5b27..0d9de2f73930 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -282,6 +282,7 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) | |||
282 | dev->dev = NULL; | 282 | dev->dev = NULL; |
283 | goto out; | 283 | goto out; |
284 | } | 284 | } |
285 | dev_set_drvdata(dev->dev, dev); | ||
285 | 286 | ||
286 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | 287 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; |
287 | 288 | ||
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 33cd91d11eca..67e2fc20eeeb 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c | |||
@@ -120,8 +120,8 @@ static void tv_disconnect(struct usb_interface *interface) | |||
120 | struct trancevibrator *dev; | 120 | struct trancevibrator *dev; |
121 | 121 | ||
122 | dev = usb_get_intfdata (interface); | 122 | dev = usb_get_intfdata (interface); |
123 | usb_set_intfdata(interface, NULL); | ||
124 | device_remove_file(&interface->dev, &dev_attr_speed); | 123 | device_remove_file(&interface->dev, &dev_attr_speed); |
124 | usb_set_intfdata(interface, NULL); | ||
125 | usb_put_dev(dev->udev); | 125 | usb_put_dev(dev->udev); |
126 | kfree(dev); | 126 | kfree(dev); |
127 | } | 127 | } |
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c index a3242be21959..a6f0f4d934df 100644 --- a/drivers/usb/net/gl620a.c +++ b/drivers/usb/net/gl620a.c | |||
@@ -79,160 +79,6 @@ struct gl_header { | |||
79 | struct gl_packet packets; | 79 | struct gl_packet packets; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #ifdef GENELINK_ACK | ||
83 | |||
84 | // FIXME: this code is incomplete, not debugged; it doesn't | ||
85 | // handle interrupts correctly; it should use the generic | ||
86 | // status IRQ code (which didn't exist back in 2001). | ||
87 | |||
88 | struct gl_priv { | ||
89 | struct urb *irq_urb; | ||
90 | char irq_buf [INTERRUPT_BUFSIZE]; | ||
91 | }; | ||
92 | |||
93 | static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value) | ||
94 | { | ||
95 | int retval; | ||
96 | |||
97 | retval = usb_control_msg(dev->udev, | ||
98 | usb_sndctrlpipe(dev->udev, 0), | ||
99 | request, | ||
100 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
101 | value, | ||
102 | 0, // index | ||
103 | 0, // data buffer | ||
104 | 0, // size | ||
105 | USB_CTRL_SET_TIMEOUT); | ||
106 | return retval; | ||
107 | } | ||
108 | |||
109 | static void gl_interrupt_complete(struct urb *urb) | ||
110 | { | ||
111 | int status = urb->status; | ||
112 | |||
113 | switch (status) { | ||
114 | case 0: | ||
115 | /* success */ | ||
116 | break; | ||
117 | case -ECONNRESET: | ||
118 | case -ENOENT: | ||
119 | case -ESHUTDOWN: | ||
120 | /* this urb is terminated, clean up */ | ||
121 | dbg("%s - urb shutting down with status: %d", | ||
122 | __FUNCTION__, status); | ||
123 | return; | ||
124 | default: | ||
125 | dbg("%s - nonzero urb status received: %d", | ||
126 | __FUNCTION__, urb->status); | ||
127 | } | ||
128 | |||
129 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
130 | if (status) | ||
131 | err("%s - usb_submit_urb failed with result %d", | ||
132 | __FUNCTION__, status); | ||
133 | } | ||
134 | |||
135 | static int gl_interrupt_read(struct usbnet *dev) | ||
136 | { | ||
137 | struct gl_priv *priv = dev->priv_data; | ||
138 | int retval; | ||
139 | |||
140 | // issue usb interrupt read | ||
141 | if (priv && priv->irq_urb) { | ||
142 | // submit urb | ||
143 | if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0) | ||
144 | dbg("gl_interrupt_read: submit fail - %X...", retval); | ||
145 | else | ||
146 | dbg("gl_interrupt_read: submit success..."); | ||
147 | } | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | // check whether another side is connected | ||
153 | static int genelink_check_connect(struct usbnet *dev) | ||
154 | { | ||
155 | int retval; | ||
156 | |||
157 | dbg("genelink_check_connect..."); | ||
158 | |||
159 | // detect whether another side is connected | ||
160 | if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) { | ||
161 | dbg("%s: genelink_check_connect write fail - %X", | ||
162 | dev->net->name, retval); | ||
163 | return retval; | ||
164 | } | ||
165 | |||
166 | // usb interrupt read to ack another side | ||
167 | if ((retval = gl_interrupt_read(dev)) != 0) { | ||
168 | dbg("%s: genelink_check_connect read fail - %X", | ||
169 | dev->net->name, retval); | ||
170 | return retval; | ||
171 | } | ||
172 | |||
173 | dbg("%s: genelink_check_connect read success", dev->net->name); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | // allocate and initialize the private data for genelink | ||
178 | static int genelink_init(struct usbnet *dev) | ||
179 | { | ||
180 | struct gl_priv *priv; | ||
181 | |||
182 | // allocate the private data structure | ||
183 | if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) { | ||
184 | dbg("%s: cannot allocate private data per device", | ||
185 | dev->net->name); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | |||
189 | // allocate irq urb | ||
190 | if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) { | ||
191 | dbg("%s: cannot allocate private irq urb per device", | ||
192 | dev->net->name); | ||
193 | kfree(priv); | ||
194 | return -ENOMEM; | ||
195 | } | ||
196 | |||
197 | // fill irq urb | ||
198 | usb_fill_int_urb(priv->irq_urb, dev->udev, | ||
199 | usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE), | ||
200 | priv->irq_buf, INTERRUPT_BUFSIZE, | ||
201 | gl_interrupt_complete, 0, | ||
202 | GENELINK_INTERRUPT_INTERVAL); | ||
203 | |||
204 | // set private data pointer | ||
205 | dev->priv_data = priv; | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | // release the private data | ||
211 | static int genelink_free(struct usbnet *dev) | ||
212 | { | ||
213 | struct gl_priv *priv = dev->priv_data; | ||
214 | |||
215 | if (!priv) | ||
216 | return 0; | ||
217 | |||
218 | // FIXME: can't cancel here; it's synchronous, and | ||
219 | // should have happened earlier in any case (interrupt | ||
220 | // handling needs to be generic) | ||
221 | |||
222 | // cancel irq urb first | ||
223 | usb_kill_urb(priv->irq_urb); | ||
224 | |||
225 | // free irq urb | ||
226 | usb_free_urb(priv->irq_urb); | ||
227 | |||
228 | // free the private data structure | ||
229 | kfree(priv); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | #endif | ||
235 | |||
236 | static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 82 | static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
237 | { | 83 | { |
238 | struct gl_header *header; | 84 | struct gl_header *header; |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index c54235f73cb6..e0eecda78ec1 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -124,10 +124,11 @@ | |||
124 | #define RX_URB_FAIL 3 | 124 | #define RX_URB_FAIL 3 |
125 | 125 | ||
126 | /* Define these values to match your device */ | 126 | /* Define these values to match your device */ |
127 | #define VENDOR_ID_REALTEK 0x0bda | 127 | #define VENDOR_ID_REALTEK 0x0bda |
128 | #define VENDOR_ID_MELCO 0x0411 | 128 | #define VENDOR_ID_MELCO 0x0411 |
129 | #define VENDOR_ID_MICRONET 0x3980 | 129 | #define VENDOR_ID_MICRONET 0x3980 |
130 | #define VENDOR_ID_LONGSHINE 0x07b8 | 130 | #define VENDOR_ID_LONGSHINE 0x07b8 |
131 | #define VENDOR_ID_OQO 0x1557 | ||
131 | #define VENDOR_ID_ZYXEL 0x0586 | 132 | #define VENDOR_ID_ZYXEL 0x0586 |
132 | 133 | ||
133 | #define PRODUCT_ID_RTL8150 0x8150 | 134 | #define PRODUCT_ID_RTL8150 0x8150 |
@@ -144,6 +145,7 @@ static struct usb_device_id rtl8150_table[] = { | |||
144 | {USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)}, | 145 | {USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)}, |
145 | {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)}, | 146 | {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)}, |
146 | {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)}, | 147 | {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)}, |
148 | {USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)}, | ||
147 | {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)}, | 149 | {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)}, |
148 | {} | 150 | {} |
149 | }; | 151 | }; |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 96c73726d74a..f2ca76a9cbac 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -19,8 +19,11 @@ | |||
19 | static struct usb_device_id id_table [] = { | 19 | static struct usb_device_id id_table [] = { |
20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ | 20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ |
21 | { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ | 21 | { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ |
22 | { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */ | ||
23 | { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */ | ||
22 | { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ | 24 | { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ |
23 | { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ | 25 | { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ |
26 | { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ | ||
24 | { }, | 27 | { }, |
25 | }; | 28 | }; |
26 | MODULE_DEVICE_TABLE(usb, id_table); | 29 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 2f9b7ac32663..7ebaffd6ed86 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = { | |||
69 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 69 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
70 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 70 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
71 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 71 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
72 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ | ||
72 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 73 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
73 | { } /* Terminating Entry */ | 74 | { } /* Terminating Entry */ |
74 | }; | 75 | }; |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 45cdf9bc43b2..6bc1f404e186 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -962,21 +962,6 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi | |||
962 | cypress_set_termios(port, &priv->tmp_termios); | 962 | cypress_set_termios(port, &priv->tmp_termios); |
963 | return (0); | 963 | return (0); |
964 | break; | 964 | break; |
965 | /* these are called when setting baud rate from gpsd */ | ||
966 | case TCGETS: | ||
967 | if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) { | ||
968 | return -EFAULT; | ||
969 | } | ||
970 | return (0); | ||
971 | break; | ||
972 | case TCSETS: | ||
973 | if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) { | ||
974 | return -EFAULT; | ||
975 | } | ||
976 | /* here we need to call cypress_set_termios to invoke the new settings */ | ||
977 | cypress_set_termios(port, &priv->tmp_termios); | ||
978 | return (0); | ||
979 | break; | ||
980 | /* This code comes from drivers/char/serial.c and ftdi_sio.c */ | 965 | /* This code comes from drivers/char/serial.c and ftdi_sio.c */ |
981 | case TIOCMIWAIT: | 966 | case TIOCMIWAIT: |
982 | while (priv != NULL) { | 967 | while (priv != NULL) { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 41b0ad2d56ac..6986e756f7c0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -452,6 +452,7 @@ static struct usb_device_id id_table_combined [] = { | |||
452 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, | 452 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, |
453 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 453 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
454 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 454 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
455 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, | ||
455 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 456 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
456 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 457 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
457 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 458 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index bae117d359af..40dd394de58d 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -312,8 +312,9 @@ | |||
312 | 312 | ||
313 | /* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ | 313 | /* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ |
314 | /* unit for PIC16's/PIC18's */ | 314 | /* unit for PIC16's/PIC18's */ |
315 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | 315 | #define FTDI_CCSICDU20_0_PID 0xF9D0 |
316 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | 316 | #define FTDI_CCSICDU40_1_PID 0xF9D1 |
317 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | ||
317 | 318 | ||
318 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | 319 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ |
319 | #define INSIDE_ACCESSO 0xFAD0 | 320 | #define INSIDE_ACCESSO 0xFAD0 |
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 77b977206a8c..d3be9214c7c1 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/usb/serial.h> | 16 | #include <linux/usb/serial.h> |
17 | #include <asm/uaccess.h> | ||
18 | |||
19 | static int debug; | ||
17 | 20 | ||
18 | static struct usb_device_id id_table [] = { | 21 | static struct usb_device_id id_table [] = { |
19 | { USB_DEVICE(0x1404, 0xcddc) }, | 22 | { USB_DEVICE(0x1404, 0xcddc) }, |
@@ -21,6 +24,26 @@ static struct usb_device_id id_table [] = { | |||
21 | }; | 24 | }; |
22 | MODULE_DEVICE_TABLE(usb, id_table); | 25 | MODULE_DEVICE_TABLE(usb, id_table); |
23 | 26 | ||
27 | static int funsoft_ioctl(struct usb_serial_port *port, struct file *file, | ||
28 | unsigned int cmd, unsigned long arg) | ||
29 | { | ||
30 | struct termios t; | ||
31 | |||
32 | dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd); | ||
33 | |||
34 | if (cmd == TCSETSF) { | ||
35 | if (user_termios_to_kernel_termios(&t, (void __user *)arg)) | ||
36 | return -EFAULT; | ||
37 | |||
38 | dbg("%s - iflag:%x oflag:%x cflag:%x lflag:%x", __FUNCTION__, | ||
39 | t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag); | ||
40 | |||
41 | if (!(t.c_lflag & ICANON)) | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | return -ENOIOCTLCMD; | ||
45 | } | ||
46 | |||
24 | static struct usb_driver funsoft_driver = { | 47 | static struct usb_driver funsoft_driver = { |
25 | .name = "funsoft", | 48 | .name = "funsoft", |
26 | .probe = usb_serial_probe, | 49 | .probe = usb_serial_probe, |
@@ -39,6 +62,7 @@ static struct usb_serial_driver funsoft_device = { | |||
39 | .num_bulk_in = NUM_DONT_CARE, | 62 | .num_bulk_in = NUM_DONT_CARE, |
40 | .num_bulk_out = NUM_DONT_CARE, | 63 | .num_bulk_out = NUM_DONT_CARE, |
41 | .num_ports = 1, | 64 | .num_ports = 1, |
65 | .ioctl = funsoft_ioctl, | ||
42 | }; | 66 | }; |
43 | 67 | ||
44 | static int __init funsoft_init(void) | 68 | static int __init funsoft_init(void) |
@@ -63,3 +87,6 @@ static void __exit funsoft_exit(void) | |||
63 | module_init(funsoft_init); | 87 | module_init(funsoft_init); |
64 | module_exit(funsoft_exit); | 88 | module_exit(funsoft_exit); |
65 | MODULE_LICENSE("GPL"); | 89 | MODULE_LICENSE("GPL"); |
90 | |||
91 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
92 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 73d755df4840..5c4b06a99ac0 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -87,10 +87,6 @@ static int klsi_105_write_room (struct usb_serial_port *port); | |||
87 | static void klsi_105_read_bulk_callback (struct urb *urb); | 87 | static void klsi_105_read_bulk_callback (struct urb *urb); |
88 | static void klsi_105_set_termios (struct usb_serial_port *port, | 88 | static void klsi_105_set_termios (struct usb_serial_port *port, |
89 | struct ktermios *old); | 89 | struct ktermios *old); |
90 | static int klsi_105_ioctl (struct usb_serial_port *port, | ||
91 | struct file * file, | ||
92 | unsigned int cmd, | ||
93 | unsigned long arg); | ||
94 | static void klsi_105_throttle (struct usb_serial_port *port); | 90 | static void klsi_105_throttle (struct usb_serial_port *port); |
95 | static void klsi_105_unthrottle (struct usb_serial_port *port); | 91 | static void klsi_105_unthrottle (struct usb_serial_port *port); |
96 | /* | 92 | /* |
@@ -140,7 +136,6 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
140 | .chars_in_buffer = klsi_105_chars_in_buffer, | 136 | .chars_in_buffer = klsi_105_chars_in_buffer, |
141 | .write_room = klsi_105_write_room, | 137 | .write_room = klsi_105_write_room, |
142 | .read_bulk_callback =klsi_105_read_bulk_callback, | 138 | .read_bulk_callback =klsi_105_read_bulk_callback, |
143 | .ioctl = klsi_105_ioctl, | ||
144 | .set_termios = klsi_105_set_termios, | 139 | .set_termios = klsi_105_set_termios, |
145 | /*.break_ctl = klsi_105_break_ctl,*/ | 140 | /*.break_ctl = klsi_105_break_ctl,*/ |
146 | .tiocmget = klsi_105_tiocmget, | 141 | .tiocmget = klsi_105_tiocmget, |
@@ -899,69 +894,6 @@ static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file, | |||
899 | */ | 894 | */ |
900 | return retval; | 895 | return retval; |
901 | } | 896 | } |
902 | |||
903 | static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file, | ||
904 | unsigned int cmd, unsigned long arg) | ||
905 | { | ||
906 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
907 | void __user *user_arg = (void __user *)arg; | ||
908 | |||
909 | dbg("%scmd=0x%x", __FUNCTION__, cmd); | ||
910 | |||
911 | /* Based on code from acm.c and others */ | ||
912 | switch (cmd) { | ||
913 | case TIOCMIWAIT: | ||
914 | /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ | ||
915 | /* TODO */ | ||
916 | dbg("%s - TIOCMIWAIT not handled", __FUNCTION__); | ||
917 | return -ENOIOCTLCMD; | ||
918 | case TIOCGICOUNT: | ||
919 | /* return count of modemline transitions */ | ||
920 | /* TODO */ | ||
921 | dbg("%s - TIOCGICOUNT not handled", __FUNCTION__); | ||
922 | return -ENOIOCTLCMD; | ||
923 | case TCGETS: | ||
924 | /* return current info to caller */ | ||
925 | dbg("%s - TCGETS data faked/incomplete", __FUNCTION__); | ||
926 | |||
927 | if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios))) | ||
928 | return -EFAULT; | ||
929 | |||
930 | if (kernel_termios_to_user_termios((struct termios __user *)arg, | ||
931 | &priv->termios)) | ||
932 | return -EFAULT; | ||
933 | return 0; | ||
934 | case TCSETS: | ||
935 | /* set port termios to the one given by the user */ | ||
936 | dbg("%s - TCSETS not handled", __FUNCTION__); | ||
937 | |||
938 | if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios))) | ||
939 | return -EFAULT; | ||
940 | |||
941 | if (user_termios_to_kernel_termios(&priv->termios, | ||
942 | (struct termios __user *)arg)) | ||
943 | return -EFAULT; | ||
944 | klsi_105_set_termios(port, &priv->termios); | ||
945 | return 0; | ||
946 | case TCSETSW: { | ||
947 | /* set port termios and try to wait for completion of last | ||
948 | * write operation */ | ||
949 | /* We guess here. If there are not too many write urbs | ||
950 | * outstanding, we lie. */ | ||
951 | /* what is the right way to wait here? schedule() ? */ | ||
952 | /* | ||
953 | while (klsi_105_chars_in_buffer(port) > (NUM_URBS / 4 ) * URB_TRANSFER_BUFFER_SIZE) | ||
954 | schedule(); | ||
955 | */ | ||
956 | return -ENOIOCTLCMD; | ||
957 | } | ||
958 | default: | ||
959 | dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd); | ||
960 | return(-ENOIOCTLCMD); | ||
961 | break; | ||
962 | } | ||
963 | return 0; | ||
964 | } /* klsi_105_ioctl */ | ||
965 | 897 | ||
966 | static void klsi_105_throttle (struct usb_serial_port *port) | 898 | static void klsi_105_throttle (struct usb_serial_port *port) |
967 | { | 899 | { |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 8cc728a49e41..83f661403ba1 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -2460,12 +2460,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, | |||
2460 | tty_ldisc_deref(ld); | 2460 | tty_ldisc_deref(ld); |
2461 | return 0; | 2461 | return 0; |
2462 | 2462 | ||
2463 | case TCGETS: | ||
2464 | if (kernel_termios_to_user_termios | ||
2465 | ((struct termios __user *)argp, tty->termios)) | ||
2466 | return -EFAULT; | ||
2467 | return 0; | ||
2468 | |||
2469 | case TIOCSERGETLSR: | 2463 | case TIOCSERGETLSR: |
2470 | dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); | 2464 | dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); |
2471 | return mos7840_get_lsr_info(mos7840_port, argp); | 2465 | return mos7840_get_lsr_info(mos7840_port, argp); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0ae4098718c3..819266b7e2f8 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -79,6 +79,7 @@ static int option_send_setup(struct usb_serial_port *port); | |||
79 | #define OPTION_PRODUCT_COBRA 0x6500 | 79 | #define OPTION_PRODUCT_COBRA 0x6500 |
80 | #define OPTION_PRODUCT_COBRA2 0x6600 | 80 | #define OPTION_PRODUCT_COBRA2 0x6600 |
81 | #define HUAWEI_PRODUCT_E600 0x1001 | 81 | #define HUAWEI_PRODUCT_E600 0x1001 |
82 | #define HUAWEI_PRODUCT_E220 0x1003 | ||
82 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 | 83 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 |
83 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 | 84 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 |
84 | #define ANYDATA_PRODUCT_ID 0x6501 | 85 | #define ANYDATA_PRODUCT_ID 0x6501 |
@@ -90,6 +91,7 @@ static struct usb_device_id option_ids[] = { | |||
90 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, | 91 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, |
91 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | 92 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, |
92 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 93 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
94 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, | ||
93 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 95 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
94 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 96 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
95 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, | 97 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, |
@@ -103,6 +105,7 @@ static struct usb_device_id option_ids1[] = { | |||
103 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, | 105 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, |
104 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | 106 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, |
105 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 107 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
108 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, | ||
106 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 109 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
107 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 110 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
108 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, | 111 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index db8b26012c75..5fe7ff441a09 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -153,6 +153,13 @@ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, | |||
153 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 153 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
154 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | 154 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
155 | 155 | ||
156 | /* Reported by <honkkis@gmail.com> */ | ||
157 | UNUSUAL_DEV( 0x0421, 0x0433, 0x0100, 0x0100, | ||
158 | "Nokia", | ||
159 | "E70", | ||
160 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
161 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | ||
162 | |||
156 | /* Reported by Jon Hart <Jon.Hart@web.de> */ | 163 | /* Reported by Jon Hart <Jon.Hart@web.de> */ |
157 | UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100, | 164 | UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100, |
158 | "Nokia", | 165 | "Nokia", |
@@ -1328,6 +1335,15 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, | |||
1328 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1335 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1329 | US_FL_IGNORE_RESIDUE ), | 1336 | US_FL_IGNORE_RESIDUE ), |
1330 | 1337 | ||
1338 | /* This prevents the kernel from detecting the virtual cd-drive with the | ||
1339 | * Windows drivers. <johann.wilhelm@student.tugraz.at> | ||
1340 | */ | ||
1341 | UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0xffff, | ||
1342 | "HUAWEI", | ||
1343 | "E220 USB-UMTS Install", | ||
1344 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1345 | US_FL_IGNORE_DEVICE), | ||
1346 | |||
1331 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1347 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
1332 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, | 1348 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, |
1333 | "Minolta", | 1349 | "Minolta", |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 38eb0b69c2d7..b4947c810706 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -1216,7 +1216,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options) | |||
1216 | done: | 1216 | done: |
1217 | if (res_specified) { | 1217 | if (res_specified) { |
1218 | dev_info(dev, "overriding resolution: %dx%d\n", xres, yres); | 1218 | dev_info(dev, "overriding resolution: %dx%d\n", xres, yres); |
1219 | inf->xres = xres; inf->yres = yres; | 1219 | inf->modes[0].xres = xres; inf->modes[0].yres = yres; |
1220 | } | 1220 | } |
1221 | if (bpp_specified) | 1221 | if (bpp_specified) |
1222 | switch (bpp) { | 1222 | switch (bpp) { |
@@ -1225,48 +1225,48 @@ static int __init pxafb_parse_options(struct device *dev, char *options) | |||
1225 | case 4: | 1225 | case 4: |
1226 | case 8: | 1226 | case 8: |
1227 | case 16: | 1227 | case 16: |
1228 | inf->bpp = bpp; | 1228 | inf->modes[0].bpp = bpp; |
1229 | dev_info(dev, "overriding bit depth: %d\n", bpp); | 1229 | dev_info(dev, "overriding bit depth: %d\n", bpp); |
1230 | break; | 1230 | break; |
1231 | default: | 1231 | default: |
1232 | dev_err(dev, "Depth %d is not valid\n", bpp); | 1232 | dev_err(dev, "Depth %d is not valid\n", bpp); |
1233 | } | 1233 | } |
1234 | } else if (!strncmp(this_opt, "pixclock:", 9)) { | 1234 | } else if (!strncmp(this_opt, "pixclock:", 9)) { |
1235 | inf->pixclock = simple_strtoul(this_opt+9, NULL, 0); | 1235 | inf->modes[0].pixclock = simple_strtoul(this_opt+9, NULL, 0); |
1236 | dev_info(dev, "override pixclock: %ld\n", inf->pixclock); | 1236 | dev_info(dev, "override pixclock: %ld\n", inf->modes[0].pixclock); |
1237 | } else if (!strncmp(this_opt, "left:", 5)) { | 1237 | } else if (!strncmp(this_opt, "left:", 5)) { |
1238 | inf->left_margin = simple_strtoul(this_opt+5, NULL, 0); | 1238 | inf->modes[0].left_margin = simple_strtoul(this_opt+5, NULL, 0); |
1239 | dev_info(dev, "override left: %u\n", inf->left_margin); | 1239 | dev_info(dev, "override left: %u\n", inf->modes[0].left_margin); |
1240 | } else if (!strncmp(this_opt, "right:", 6)) { | 1240 | } else if (!strncmp(this_opt, "right:", 6)) { |
1241 | inf->right_margin = simple_strtoul(this_opt+6, NULL, 0); | 1241 | inf->modes[0].right_margin = simple_strtoul(this_opt+6, NULL, 0); |
1242 | dev_info(dev, "override right: %u\n", inf->right_margin); | 1242 | dev_info(dev, "override right: %u\n", inf->modes[0].right_margin); |
1243 | } else if (!strncmp(this_opt, "upper:", 6)) { | 1243 | } else if (!strncmp(this_opt, "upper:", 6)) { |
1244 | inf->upper_margin = simple_strtoul(this_opt+6, NULL, 0); | 1244 | inf->modes[0].upper_margin = simple_strtoul(this_opt+6, NULL, 0); |
1245 | dev_info(dev, "override upper: %u\n", inf->upper_margin); | 1245 | dev_info(dev, "override upper: %u\n", inf->modes[0].upper_margin); |
1246 | } else if (!strncmp(this_opt, "lower:", 6)) { | 1246 | } else if (!strncmp(this_opt, "lower:", 6)) { |
1247 | inf->lower_margin = simple_strtoul(this_opt+6, NULL, 0); | 1247 | inf->modes[0].lower_margin = simple_strtoul(this_opt+6, NULL, 0); |
1248 | dev_info(dev, "override lower: %u\n", inf->lower_margin); | 1248 | dev_info(dev, "override lower: %u\n", inf->modes[0].lower_margin); |
1249 | } else if (!strncmp(this_opt, "hsynclen:", 9)) { | 1249 | } else if (!strncmp(this_opt, "hsynclen:", 9)) { |
1250 | inf->hsync_len = simple_strtoul(this_opt+9, NULL, 0); | 1250 | inf->modes[0].hsync_len = simple_strtoul(this_opt+9, NULL, 0); |
1251 | dev_info(dev, "override hsynclen: %u\n", inf->hsync_len); | 1251 | dev_info(dev, "override hsynclen: %u\n", inf->modes[0].hsync_len); |
1252 | } else if (!strncmp(this_opt, "vsynclen:", 9)) { | 1252 | } else if (!strncmp(this_opt, "vsynclen:", 9)) { |
1253 | inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0); | 1253 | inf->modes[0].vsync_len = simple_strtoul(this_opt+9, NULL, 0); |
1254 | dev_info(dev, "override vsynclen: %u\n", inf->vsync_len); | 1254 | dev_info(dev, "override vsynclen: %u\n", inf->modes[0].vsync_len); |
1255 | } else if (!strncmp(this_opt, "hsync:", 6)) { | 1255 | } else if (!strncmp(this_opt, "hsync:", 6)) { |
1256 | if (simple_strtoul(this_opt+6, NULL, 0) == 0) { | 1256 | if (simple_strtoul(this_opt+6, NULL, 0) == 0) { |
1257 | dev_info(dev, "override hsync: Active Low\n"); | 1257 | dev_info(dev, "override hsync: Active Low\n"); |
1258 | inf->sync &= ~FB_SYNC_HOR_HIGH_ACT; | 1258 | inf->modes[0].sync &= ~FB_SYNC_HOR_HIGH_ACT; |
1259 | } else { | 1259 | } else { |
1260 | dev_info(dev, "override hsync: Active High\n"); | 1260 | dev_info(dev, "override hsync: Active High\n"); |
1261 | inf->sync |= FB_SYNC_HOR_HIGH_ACT; | 1261 | inf->modes[0].sync |= FB_SYNC_HOR_HIGH_ACT; |
1262 | } | 1262 | } |
1263 | } else if (!strncmp(this_opt, "vsync:", 6)) { | 1263 | } else if (!strncmp(this_opt, "vsync:", 6)) { |
1264 | if (simple_strtoul(this_opt+6, NULL, 0) == 0) { | 1264 | if (simple_strtoul(this_opt+6, NULL, 0) == 0) { |
1265 | dev_info(dev, "override vsync: Active Low\n"); | 1265 | dev_info(dev, "override vsync: Active Low\n"); |
1266 | inf->sync &= ~FB_SYNC_VERT_HIGH_ACT; | 1266 | inf->modes[0].sync &= ~FB_SYNC_VERT_HIGH_ACT; |
1267 | } else { | 1267 | } else { |
1268 | dev_info(dev, "override vsync: Active High\n"); | 1268 | dev_info(dev, "override vsync: Active High\n"); |
1269 | inf->sync |= FB_SYNC_VERT_HIGH_ACT; | 1269 | inf->modes[0].sync |= FB_SYNC_VERT_HIGH_ACT; |
1270 | } | 1270 | } |
1271 | } else if (!strncmp(this_opt, "dpc:", 4)) { | 1271 | } else if (!strncmp(this_opt, "dpc:", 4)) { |
1272 | if (simple_strtoul(this_opt+4, NULL, 0) == 0) { | 1272 | if (simple_strtoul(this_opt+4, NULL, 0) == 0) { |
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index cd10b18150b8..5d2a4a4b731c 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c | |||
@@ -1200,9 +1200,9 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) | |||
1200 | * Our LCD controller task (which is called when we blank or unblank) | 1200 | * Our LCD controller task (which is called when we blank or unblank) |
1201 | * via keventd. | 1201 | * via keventd. |
1202 | */ | 1202 | */ |
1203 | static void sa1100fb_task(void *dummy) | 1203 | static void sa1100fb_task(struct work_struct *w) |
1204 | { | 1204 | { |
1205 | struct sa1100fb_info *fbi = dummy; | 1205 | struct sa1100fb_info *fbi = container_of(w, struct sa1100fb_info, task); |
1206 | u_int state = xchg(&fbi->task_state, -1); | 1206 | u_int state = xchg(&fbi->task_state, -1); |
1207 | 1207 | ||
1208 | set_ctrlr_state(fbi, state); | 1208 | set_ctrlr_state(fbi, state); |
@@ -1444,7 +1444,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) | |||
1444 | fbi->max_bpp / 8; | 1444 | fbi->max_bpp / 8; |
1445 | 1445 | ||
1446 | init_waitqueue_head(&fbi->ctrlr_wait); | 1446 | init_waitqueue_head(&fbi->ctrlr_wait); |
1447 | INIT_WORK(&fbi->task, sa1100fb_task, fbi); | 1447 | INIT_WORK(&fbi->task, sa1100fb_task); |
1448 | init_MUTEX(&fbi->ctrlr_sem); | 1448 | init_MUTEX(&fbi->ctrlr_sem); |
1449 | 1449 | ||
1450 | return fbi; | 1450 | return fbi; |