diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-05-29 07:08:14 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-09 18:21:49 -0400 |
commit | 7b5a65b9e649dad9cf9c6d282df4162843070351 (patch) | |
tree | 440645a0fd7d465e10214a4372a0d7a5a15901c3 /drivers/message | |
parent | 14d0f0b063f5363984dd305a792854f9c23e9e97 (diff) |
[SCSI] mpt fusion: Added support for MPT discovery completion check
sas_discovery_quiesce_io flag is used to control IO start/resume functionality.
IO will be stoped while doing discovery of topology. Once discovery is completed
It will resume IO. Resending patch including James review.
Signed-off-by: Kashyap Desai <kadesai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 56 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 1 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 25 |
3 files changed, 80 insertions, 2 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index a66369218c97..54326e09629c 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -277,6 +277,56 @@ mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | /** | 279 | /** |
280 | * mpt_is_discovery_complete - determine if discovery has completed | ||
281 | * @ioc: per adatper instance | ||
282 | * | ||
283 | * Returns 1 when discovery completed, else zero. | ||
284 | */ | ||
285 | static int | ||
286 | mpt_is_discovery_complete(MPT_ADAPTER *ioc) | ||
287 | { | ||
288 | ConfigExtendedPageHeader_t hdr; | ||
289 | CONFIGPARMS cfg; | ||
290 | SasIOUnitPage0_t *buffer; | ||
291 | dma_addr_t dma_handle; | ||
292 | int rc = 0; | ||
293 | |||
294 | memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t)); | ||
295 | memset(&cfg, 0, sizeof(CONFIGPARMS)); | ||
296 | hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION; | ||
297 | hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; | ||
298 | hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | ||
299 | cfg.cfghdr.ehdr = &hdr; | ||
300 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
301 | |||
302 | if ((mpt_config(ioc, &cfg))) | ||
303 | goto out; | ||
304 | if (!hdr.ExtPageLength) | ||
305 | goto out; | ||
306 | |||
307 | buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | ||
308 | &dma_handle); | ||
309 | if (!buffer) | ||
310 | goto out; | ||
311 | |||
312 | cfg.physAddr = dma_handle; | ||
313 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
314 | |||
315 | if ((mpt_config(ioc, &cfg))) | ||
316 | goto out_free_consistent; | ||
317 | |||
318 | if (!(buffer->PhyData[0].PortFlags & | ||
319 | MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS)) | ||
320 | rc = 1; | ||
321 | |||
322 | out_free_consistent: | ||
323 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | ||
324 | buffer, dma_handle); | ||
325 | out: | ||
326 | return rc; | ||
327 | } | ||
328 | |||
329 | /** | ||
280 | * mpt_fault_reset_work - work performed on workq after ioc fault | 330 | * mpt_fault_reset_work - work performed on workq after ioc fault |
281 | * @work: input argument, used to derive ioc | 331 | * @work: input argument, used to derive ioc |
282 | * | 332 | * |
@@ -307,6 +357,12 @@ mpt_fault_reset_work(struct work_struct *work) | |||
307 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " | 357 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " |
308 | "reset (%04xh)\n", ioc->name, ioc_raw_state & | 358 | "reset (%04xh)\n", ioc->name, ioc_raw_state & |
309 | MPI_DOORBELL_DATA_MASK); | 359 | MPI_DOORBELL_DATA_MASK); |
360 | } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) { | ||
361 | if ((mpt_is_discovery_complete(ioc))) { | ||
362 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing " | ||
363 | "discovery_quiesce_io flag\n", ioc->name)); | ||
364 | ioc->sas_discovery_quiesce_io = 0; | ||
365 | } | ||
310 | } | 366 | } |
311 | 367 | ||
312 | out: | 368 | out: |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 4a606764e317..8cd0a16cdfac 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -706,6 +706,7 @@ typedef struct _MPT_ADAPTER | |||
706 | struct mutex sas_discovery_mutex; | 706 | struct mutex sas_discovery_mutex; |
707 | u8 sas_discovery_runtime; | 707 | u8 sas_discovery_runtime; |
708 | u8 sas_discovery_ignore_events; | 708 | u8 sas_discovery_ignore_events; |
709 | u8 sas_discovery_quiesce_io; | ||
709 | int sas_index; /* index refrencing */ | 710 | int sas_index; /* index refrencing */ |
710 | MPT_SAS_MGMT sas_mgmt; | 711 | MPT_SAS_MGMT sas_mgmt; |
711 | struct work_struct sas_persist_task; | 712 | struct work_struct sas_persist_task; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index b162f7a1c563..40dbaaaf49e1 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -1008,6 +1008,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
1008 | static int | 1008 | static int |
1009 | mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | 1009 | mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) |
1010 | { | 1010 | { |
1011 | MPT_SCSI_HOST *hd; | ||
1012 | MPT_ADAPTER *ioc; | ||
1011 | VirtDevice *vdevice = SCpnt->device->hostdata; | 1013 | VirtDevice *vdevice = SCpnt->device->hostdata; |
1012 | 1014 | ||
1013 | if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) { | 1015 | if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) { |
@@ -1016,6 +1018,12 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1016 | return 0; | 1018 | return 0; |
1017 | } | 1019 | } |
1018 | 1020 | ||
1021 | hd = shost_priv(SCpnt->device->host); | ||
1022 | ioc = hd->ioc; | ||
1023 | |||
1024 | if (ioc->sas_discovery_quiesce_io) | ||
1025 | return SCSI_MLQUEUE_HOST_BUSY; | ||
1026 | |||
1019 | // scsi_print_command(SCpnt); | 1027 | // scsi_print_command(SCpnt); |
1020 | 1028 | ||
1021 | return mptscsih_qcmd(SCpnt,done); | 1029 | return mptscsih_qcmd(SCpnt,done); |
@@ -3009,6 +3017,7 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc, | |||
3009 | EVENT_DATA_SAS_DISCOVERY *discovery_data) | 3017 | EVENT_DATA_SAS_DISCOVERY *discovery_data) |
3010 | { | 3018 | { |
3011 | struct mptsas_discovery_event *ev; | 3019 | struct mptsas_discovery_event *ev; |
3020 | u32 discovery_status; | ||
3012 | 3021 | ||
3013 | /* | 3022 | /* |
3014 | * DiscoveryStatus | 3023 | * DiscoveryStatus |
@@ -3017,7 +3026,9 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc, | |||
3017 | * kicks off discovery, and return to zero | 3026 | * kicks off discovery, and return to zero |
3018 | * once its completed. | 3027 | * once its completed. |
3019 | */ | 3028 | */ |
3020 | if (discovery_data->DiscoveryStatus) | 3029 | discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus); |
3030 | ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0; | ||
3031 | if (discovery_status) | ||
3021 | return; | 3032 | return; |
3022 | 3033 | ||
3023 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | 3034 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
@@ -3299,12 +3310,22 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3299 | return error; | 3310 | return error; |
3300 | } | 3311 | } |
3301 | 3312 | ||
3313 | void | ||
3314 | mptsas_shutdown(struct pci_dev *pdev) | ||
3315 | { | ||
3316 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | ||
3317 | |||
3318 | ioc->sas_discovery_quiesce_io = 0; | ||
3319 | } | ||
3320 | |||
3302 | static void __devexit mptsas_remove(struct pci_dev *pdev) | 3321 | static void __devexit mptsas_remove(struct pci_dev *pdev) |
3303 | { | 3322 | { |
3304 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 3323 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
3305 | struct mptsas_portinfo *p, *n; | 3324 | struct mptsas_portinfo *p, *n; |
3306 | int i; | 3325 | int i; |
3307 | 3326 | ||
3327 | mptsas_shutdown(pdev); | ||
3328 | |||
3308 | ioc->sas_discovery_ignore_events = 1; | 3329 | ioc->sas_discovery_ignore_events = 1; |
3309 | sas_remove_host(ioc->sh); | 3330 | sas_remove_host(ioc->sh); |
3310 | 3331 | ||
@@ -3342,7 +3363,7 @@ static struct pci_driver mptsas_driver = { | |||
3342 | .id_table = mptsas_pci_table, | 3363 | .id_table = mptsas_pci_table, |
3343 | .probe = mptsas_probe, | 3364 | .probe = mptsas_probe, |
3344 | .remove = __devexit_p(mptsas_remove), | 3365 | .remove = __devexit_p(mptsas_remove), |
3345 | .shutdown = mptscsih_shutdown, | 3366 | .shutdown = mptsas_shutdown, |
3346 | #ifdef CONFIG_PM | 3367 | #ifdef CONFIG_PM |
3347 | .suspend = mptscsih_suspend, | 3368 | .suspend = mptscsih_suspend, |
3348 | .resume = mptscsih_resume, | 3369 | .resume = mptscsih_resume, |