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/fusion | |
| 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/fusion')
| -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, |
