diff options
author | Arvind Kumar <arvindkumar@vmware.com> | 2012-03-08 05:18:53 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-03-27 03:26:36 -0400 |
commit | a93107355d2d4557e7e19ea1724bdb710268cd34 (patch) | |
tree | 8a0d1280bac8f3ae53d92da2491d40ee5d649fc1 /drivers/scsi/vmw_pvscsi.c | |
parent | 3f0bc3b331a371392bb64c5b211b60ec84d5a444 (diff) |
[SCSI] vmw_pvscsi: Try setting host->max_id as suggested by the device.
Fetch the config page from the device to learn max target id to set
host->max_id.
Also, fix some indentation issues and update the 'Maintained by' field.
Signed-off-by: Arvind Kumar <arvindkumar@vmware.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/vmw_pvscsi.c')
-rw-r--r-- | drivers/scsi/vmw_pvscsi.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 7264116185d5..4411d4224401 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | * | 19 | * |
20 | * Maintained by: Alok N Kataria <akataria@vmware.com> | 20 | * Maintained by: Arvind Kumar <arvindkumar@vmware.com> |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
@@ -1178,11 +1178,67 @@ static int __devinit pvscsi_allocate_sg(struct pvscsi_adapter *adapter) | |||
1178 | return 0; | 1178 | return 0; |
1179 | } | 1179 | } |
1180 | 1180 | ||
1181 | /* | ||
1182 | * Query the device, fetch the config info and return the | ||
1183 | * maximum number of targets on the adapter. In case of | ||
1184 | * failure due to any reason return default i.e. 16. | ||
1185 | */ | ||
1186 | static u32 pvscsi_get_max_targets(struct pvscsi_adapter *adapter) | ||
1187 | { | ||
1188 | struct PVSCSICmdDescConfigCmd cmd; | ||
1189 | struct PVSCSIConfigPageHeader *header; | ||
1190 | struct device *dev; | ||
1191 | dma_addr_t configPagePA; | ||
1192 | void *config_page; | ||
1193 | u32 numPhys = 16; | ||
1194 | |||
1195 | dev = pvscsi_dev(adapter); | ||
1196 | config_page = pci_alloc_consistent(adapter->dev, PAGE_SIZE, | ||
1197 | &configPagePA); | ||
1198 | if (!config_page) { | ||
1199 | dev_warn(dev, "vmw_pvscsi: failed to allocate memory for config page\n"); | ||
1200 | goto exit; | ||
1201 | } | ||
1202 | BUG_ON(configPagePA & ~PAGE_MASK); | ||
1203 | |||
1204 | /* Fetch config info from the device. */ | ||
1205 | cmd.configPageAddress = ((u64)PVSCSI_CONFIG_CONTROLLER_ADDRESS) << 32; | ||
1206 | cmd.configPageNum = PVSCSI_CONFIG_PAGE_CONTROLLER; | ||
1207 | cmd.cmpAddr = configPagePA; | ||
1208 | cmd._pad = 0; | ||
1209 | |||
1210 | /* | ||
1211 | * Mark the completion page header with error values. If the device | ||
1212 | * completes the command successfully, it sets the status values to | ||
1213 | * indicate success. | ||
1214 | */ | ||
1215 | header = config_page; | ||
1216 | memset(header, 0, sizeof *header); | ||
1217 | header->hostStatus = BTSTAT_INVPARAM; | ||
1218 | header->scsiStatus = SDSTAT_CHECK; | ||
1219 | |||
1220 | pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_CONFIG, &cmd, sizeof cmd); | ||
1221 | |||
1222 | if (header->hostStatus == BTSTAT_SUCCESS && | ||
1223 | header->scsiStatus == SDSTAT_GOOD) { | ||
1224 | struct PVSCSIConfigPageController *config; | ||
1225 | |||
1226 | config = config_page; | ||
1227 | numPhys = config->numPhys; | ||
1228 | } else | ||
1229 | dev_warn(dev, "vmw_pvscsi: PVSCSI_CMD_CONFIG failed. hostStatus = 0x%x, scsiStatus = 0x%x\n", | ||
1230 | header->hostStatus, header->scsiStatus); | ||
1231 | pci_free_consistent(adapter->dev, PAGE_SIZE, config_page, configPagePA); | ||
1232 | exit: | ||
1233 | return numPhys; | ||
1234 | } | ||
1235 | |||
1181 | static int __devinit pvscsi_probe(struct pci_dev *pdev, | 1236 | static int __devinit pvscsi_probe(struct pci_dev *pdev, |
1182 | const struct pci_device_id *id) | 1237 | const struct pci_device_id *id) |
1183 | { | 1238 | { |
1184 | struct pvscsi_adapter *adapter; | 1239 | struct pvscsi_adapter *adapter; |
1185 | struct Scsi_Host *host; | 1240 | struct Scsi_Host *host; |
1241 | struct device *dev; | ||
1186 | unsigned int i; | 1242 | unsigned int i; |
1187 | unsigned long flags = 0; | 1243 | unsigned long flags = 0; |
1188 | int error; | 1244 | int error; |
@@ -1272,6 +1328,13 @@ static int __devinit pvscsi_probe(struct pci_dev *pdev, | |||
1272 | } | 1328 | } |
1273 | 1329 | ||
1274 | /* | 1330 | /* |
1331 | * Ask the device for max number of targets. | ||
1332 | */ | ||
1333 | host->max_id = pvscsi_get_max_targets(adapter); | ||
1334 | dev = pvscsi_dev(adapter); | ||
1335 | dev_info(dev, "vmw_pvscsi: host->max_id: %u\n", host->max_id); | ||
1336 | |||
1337 | /* | ||
1275 | * From this point on we should reset the adapter if anything goes | 1338 | * From this point on we should reset the adapter if anything goes |
1276 | * wrong. | 1339 | * wrong. |
1277 | */ | 1340 | */ |