diff options
Diffstat (limited to 'drivers/message/fusion/mptsas.c')
-rw-r--r-- | drivers/message/fusion/mptsas.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index e0a8bb8ba7d8..17e9757e728b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -228,31 +228,35 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) | |||
228 | * implement ->target_alloc. | 228 | * implement ->target_alloc. |
229 | */ | 229 | */ |
230 | static int | 230 | static int |
231 | mptsas_slave_alloc(struct scsi_device *device) | 231 | mptsas_slave_alloc(struct scsi_device *sdev) |
232 | { | 232 | { |
233 | struct Scsi_Host *host = device->host; | 233 | struct Scsi_Host *host = sdev->host; |
234 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 234 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
235 | struct sas_rphy *rphy; | 235 | struct sas_rphy *rphy; |
236 | struct mptsas_portinfo *p; | 236 | struct mptsas_portinfo *p; |
237 | VirtTarget *vtarget; | ||
237 | VirtDevice *vdev; | 238 | VirtDevice *vdev; |
238 | uint target = device->id; | 239 | struct scsi_target *starget; |
239 | int i; | 240 | int i; |
240 | 241 | ||
241 | if ((vdev = hd->Targets[target]) != NULL) | ||
242 | goto out; | ||
243 | |||
244 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); | 242 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); |
245 | if (!vdev) { | 243 | if (!vdev) { |
246 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 244 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", |
247 | hd->ioc->name, sizeof(VirtDevice)); | 245 | hd->ioc->name, sizeof(VirtDevice)); |
248 | return -ENOMEM; | 246 | return -ENOMEM; |
249 | } | 247 | } |
250 | |||
251 | memset(vdev, 0, sizeof(VirtDevice)); | 248 | memset(vdev, 0, sizeof(VirtDevice)); |
252 | vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
253 | vdev->ioc_id = hd->ioc->id; | 249 | vdev->ioc_id = hd->ioc->id; |
250 | sdev->hostdata = vdev; | ||
251 | starget = scsi_target(sdev); | ||
252 | vtarget = starget->hostdata; | ||
253 | vdev->vtarget = vtarget; | ||
254 | if (vtarget->num_luns == 0) { | ||
255 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
256 | hd->Targets[sdev->id] = vtarget; | ||
257 | } | ||
254 | 258 | ||
255 | rphy = dev_to_rphy(device->sdev_target->dev.parent); | 259 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); |
256 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | 260 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { |
257 | for (i = 0; i < p->num_phys; i++) { | 261 | for (i = 0; i < p->num_phys; i++) { |
258 | if (p->phy_info[i].attached.sas_address == | 262 | if (p->phy_info[i].attached.sas_address == |
@@ -260,7 +264,7 @@ mptsas_slave_alloc(struct scsi_device *device) | |||
260 | vdev->target_id = | 264 | vdev->target_id = |
261 | p->phy_info[i].attached.target; | 265 | p->phy_info[i].attached.target; |
262 | vdev->bus_id = p->phy_info[i].attached.bus; | 266 | vdev->bus_id = p->phy_info[i].attached.bus; |
263 | hd->Targets[device->id] = vdev; | 267 | vdev->lun = sdev->lun; |
264 | goto out; | 268 | goto out; |
265 | } | 269 | } |
266 | } | 270 | } |
@@ -271,19 +275,24 @@ mptsas_slave_alloc(struct scsi_device *device) | |||
271 | return -ENODEV; | 275 | return -ENODEV; |
272 | 276 | ||
273 | out: | 277 | out: |
274 | vdev->num_luns++; | 278 | vtarget->ioc_id = vdev->ioc_id; |
275 | device->hostdata = vdev; | 279 | vtarget->target_id = vdev->target_id; |
280 | vtarget->bus_id = vdev->bus_id; | ||
281 | vtarget->num_luns++; | ||
276 | return 0; | 282 | return 0; |
277 | } | 283 | } |
278 | 284 | ||
279 | static struct scsi_host_template mptsas_driver_template = { | 285 | static struct scsi_host_template mptsas_driver_template = { |
286 | .module = THIS_MODULE, | ||
280 | .proc_name = "mptsas", | 287 | .proc_name = "mptsas", |
281 | .proc_info = mptscsih_proc_info, | 288 | .proc_info = mptscsih_proc_info, |
282 | .name = "MPT SPI Host", | 289 | .name = "MPT SPI Host", |
283 | .info = mptscsih_info, | 290 | .info = mptscsih_info, |
284 | .queuecommand = mptscsih_qcmd, | 291 | .queuecommand = mptscsih_qcmd, |
292 | .target_alloc = mptscsih_target_alloc, | ||
285 | .slave_alloc = mptsas_slave_alloc, | 293 | .slave_alloc = mptsas_slave_alloc, |
286 | .slave_configure = mptscsih_slave_configure, | 294 | .slave_configure = mptscsih_slave_configure, |
295 | .target_destroy = mptscsih_target_destroy, | ||
287 | .slave_destroy = mptscsih_slave_destroy, | 296 | .slave_destroy = mptscsih_slave_destroy, |
288 | .change_queue_depth = mptscsih_change_queue_depth, | 297 | .change_queue_depth = mptscsih_change_queue_depth, |
289 | .eh_abort_handler = mptscsih_abort, | 298 | .eh_abort_handler = mptscsih_abort, |
@@ -986,7 +995,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) | |||
986 | goto out_free_port_info; | 995 | goto out_free_port_info; |
987 | 996 | ||
988 | list_add_tail(&port_info->list, &ioc->sas_topology); | 997 | list_add_tail(&port_info->list, &ioc->sas_topology); |
989 | |||
990 | for (i = 0; i < port_info->num_phys; i++) { | 998 | for (i = 0; i < port_info->num_phys; i++) { |
991 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], | 999 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], |
992 | (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << | 1000 | (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << |
@@ -1133,13 +1141,15 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1133 | printk(MYIOC_s_WARN_FMT | 1141 | printk(MYIOC_s_WARN_FMT |
1134 | "Skipping because it's not operational!\n", | 1142 | "Skipping because it's not operational!\n", |
1135 | ioc->name); | 1143 | ioc->name); |
1136 | return -ENODEV; | 1144 | error = -ENODEV; |
1145 | goto out_mptsas_probe; | ||
1137 | } | 1146 | } |
1138 | 1147 | ||
1139 | if (!ioc->active) { | 1148 | if (!ioc->active) { |
1140 | printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", | 1149 | printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", |
1141 | ioc->name); | 1150 | ioc->name); |
1142 | return -ENODEV; | 1151 | error = -ENODEV; |
1152 | goto out_mptsas_probe; | ||
1143 | } | 1153 | } |
1144 | 1154 | ||
1145 | /* Sanity check - ensure at least 1 port is INITIATOR capable | 1155 | /* Sanity check - ensure at least 1 port is INITIATOR capable |
@@ -1163,7 +1173,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1163 | printk(MYIOC_s_WARN_FMT | 1173 | printk(MYIOC_s_WARN_FMT |
1164 | "Unable to register controller with SCSI subsystem\n", | 1174 | "Unable to register controller with SCSI subsystem\n", |
1165 | ioc->name); | 1175 | ioc->name); |
1166 | return -1; | 1176 | error = -1; |
1177 | goto out_mptsas_probe; | ||
1167 | } | 1178 | } |
1168 | 1179 | ||
1169 | spin_lock_irqsave(&ioc->FreeQlock, flags); | 1180 | spin_lock_irqsave(&ioc->FreeQlock, flags); |
@@ -1237,7 +1248,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1237 | mem = kmalloc(sz, GFP_ATOMIC); | 1248 | mem = kmalloc(sz, GFP_ATOMIC); |
1238 | if (mem == NULL) { | 1249 | if (mem == NULL) { |
1239 | error = -ENOMEM; | 1250 | error = -ENOMEM; |
1240 | goto mptsas_probe_failed; | 1251 | goto out_mptsas_probe; |
1241 | } | 1252 | } |
1242 | 1253 | ||
1243 | memset(mem, 0, sz); | 1254 | memset(mem, 0, sz); |
@@ -1255,14 +1266,14 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1255 | mem = kmalloc(sz, GFP_ATOMIC); | 1266 | mem = kmalloc(sz, GFP_ATOMIC); |
1256 | if (mem == NULL) { | 1267 | if (mem == NULL) { |
1257 | error = -ENOMEM; | 1268 | error = -ENOMEM; |
1258 | goto mptsas_probe_failed; | 1269 | goto out_mptsas_probe; |
1259 | } | 1270 | } |
1260 | 1271 | ||
1261 | memset(mem, 0, sz); | 1272 | memset(mem, 0, sz); |
1262 | hd->Targets = (VirtDevice **) mem; | 1273 | hd->Targets = (VirtTarget **) mem; |
1263 | 1274 | ||
1264 | dprintk((KERN_INFO | 1275 | dprintk((KERN_INFO |
1265 | " Targets @ %p, sz=%d\n", hd->Targets, sz)); | 1276 | " vtarget @ %p, sz=%d\n", hd->Targets, sz)); |
1266 | 1277 | ||
1267 | /* Clear the TM flags | 1278 | /* Clear the TM flags |
1268 | */ | 1279 | */ |
@@ -1308,14 +1319,14 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1308 | if (error) { | 1319 | if (error) { |
1309 | dprintk((KERN_ERR MYNAM | 1320 | dprintk((KERN_ERR MYNAM |
1310 | "scsi_add_host failed\n")); | 1321 | "scsi_add_host failed\n")); |
1311 | goto mptsas_probe_failed; | 1322 | goto out_mptsas_probe; |
1312 | } | 1323 | } |
1313 | 1324 | ||
1314 | mptsas_scan_sas_topology(ioc); | 1325 | mptsas_scan_sas_topology(ioc); |
1315 | 1326 | ||
1316 | return 0; | 1327 | return 0; |
1317 | 1328 | ||
1318 | mptsas_probe_failed: | 1329 | out_mptsas_probe: |
1319 | 1330 | ||
1320 | mptscsih_remove(pdev); | 1331 | mptscsih_remove(pdev); |
1321 | return error; | 1332 | return error; |