Lines Matching +full:host +full:- +full:command

2    3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
7 Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
22 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
41 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
50 -------
51 2.26.02.000 - Driver cleanup for kernel submission.
52 2.26.02.001 - Replace schedule_timeout() calls with msleep().
53 2.26.02.002 - Add support for PAE mode.
59 Remove un-needed eh_abort handler.
61 2.26.02.003 - Correctly handle single sgl's with use_sg=1.
62 2.26.02.004 - Add support for 9550SX controllers.
63 2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher.
64 2.26.02.006 - Fix 9550SX pchip reset timeout.
66 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic().
67 2.26.02.008 - Free irq handler in __twa_shutdown().
70 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails.
71 2.26.02.010 - Add support for 9690SA controllers.
72 2.26.02.011 - Increase max AENs drained to 256.
76 2.26.02.012 - Add power management support.
77 2.26.02.013 - Fix bug in twa_load_sgl().
78 2.26.02.014 - Force 60 second timeout default.
100 #include "3w-9xxx.h"
107 static int twa_major = -1;
158 struct Scsi_Host *host = class_to_shost(dev); in twa_show_stats() local
159 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; in twa_show_stats()
163 spin_lock_irqsave(tw_dev->host->host_lock, flags); in twa_show_stats()
164 len = sysfs_emit(buf, "3w-9xxx Driver version: %s\n" in twa_show_stats()
173 "SCSI Host Resets: %4d\n" in twa_show_stats()
176 tw_dev->posted_request_count, in twa_show_stats()
177 tw_dev->max_posted_request_count, in twa_show_stats()
178 tw_dev->pending_request_count, in twa_show_stats()
179 tw_dev->max_pending_request_count, in twa_show_stats()
180 tw_dev->sgl_entries, in twa_show_stats()
181 tw_dev->max_sgl_entries, in twa_show_stats()
182 tw_dev->sector_count, in twa_show_stats()
183 tw_dev->max_sector_count, in twa_show_stats()
184 tw_dev->num_resets, in twa_show_stats()
185 tw_dev->aen_count); in twa_show_stats()
186 spin_unlock_irqrestore(tw_dev->host->host_lock, flags); in twa_show_stats()
199 /* Host attributes initializer */
218 * single entry buffers. Note that we treat a zero-length transfer like
236 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; in twa_aen_complete()
237 tw_dev->posted_request_count--; in twa_aen_complete()
238 aen = le16_to_cpu(header->status_block.error); in twa_aen_complete()
239 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_aen_complete()
240 command_packet = &full_command_packet->command.oldcommand; in twa_aen_complete()
243 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) { in twa_aen_complete()
274 tw_dev->state[request_id] = TW_S_COMPLETED; in twa_aen_complete()
276 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags); in twa_aen_complete()
298 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_aen_drain_queue()
309 sglist[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); in twa_aen_drain_queue()
311 if (tw_dev->generic_buffer_phys[request_id] & TW_ALIGNMENT_9000_SGL) { in twa_aen_drain_queue()
312 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain"); in twa_aen_drain_queue()
316 /* Mark internal command */ in twa_aen_drain_queue()
317 tw_dev->srb[request_id] = NULL; in twa_aen_drain_queue()
320 /* Send command to the board */ in twa_aen_drain_queue()
322 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense"); in twa_aen_drain_queue()
328 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue"); in twa_aen_drain_queue()
329 tw_dev->posted_request_count--; in twa_aen_drain_queue()
333 tw_dev->posted_request_count--; in twa_aen_drain_queue()
334 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; in twa_aen_drain_queue()
335 aen = le16_to_cpu(header->status_block.error); in twa_aen_drain_queue()
368 tw_dev->state[request_id] = TW_S_INITIAL; in twa_aen_drain_queue()
378 char host[16]; in twa_aen_queue_event() local
381 tw_dev->aen_count++; in twa_aen_queue_event()
384 event = tw_dev->event_queue[tw_dev->error_index]; in twa_aen_queue_event()
387 host[0] = '\0'; in twa_aen_queue_event()
388 if (tw_dev->host) { in twa_aen_queue_event()
389 sprintf(host, " scsi%d:", tw_dev->host->host_no); in twa_aen_queue_event()
390 if (event->retrieved == TW_AEN_NOT_RETRIEVED) in twa_aen_queue_event()
391 tw_dev->aen_clobber = 1; in twa_aen_queue_event()
394 aen = le16_to_cpu(header->status_block.error); in twa_aen_queue_event()
397 event->severity = TW_SEV_OUT(header->status_block.severity__reserved); in twa_aen_queue_event()
398 /* event->time_stamp_sec overflows in y2106 */ in twa_aen_queue_event()
399 local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60)); in twa_aen_queue_event()
400 event->time_stamp_sec = local_time; in twa_aen_queue_event()
401 event->aen_code = aen; in twa_aen_queue_event()
402 event->retrieved = TW_AEN_NOT_RETRIEVED; in twa_aen_queue_event()
403 event->sequence_id = tw_dev->error_sequence_id; in twa_aen_queue_event()
404 tw_dev->error_sequence_id++; in twa_aen_queue_event()
407 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]); in twa_aen_queue_event()
409 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0'; in twa_aen_queue_event()
410 event->parameter_len = strlen(header->err_specific_desc); in twa_aen_queue_event()
411 …memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + (error_str[0] == '… in twa_aen_queue_event()
412 if (event->severity != TW_AEN_SEVERITY_DEBUG) in twa_aen_queue_event()
413 printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n", in twa_aen_queue_event()
414 host, in twa_aen_queue_event()
415 twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)), in twa_aen_queue_event()
418 header->err_specific_desc); in twa_aen_queue_event()
420 tw_dev->aen_count--; in twa_aen_queue_event()
422 if ((tw_dev->error_index + 1) == TW_Q_LENGTH) in twa_aen_queue_event()
423 tw_dev->event_queue_wrapped = 1; in twa_aen_queue_event()
424 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH; in twa_aen_queue_event()
435 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_aen_read_queue()
446 sglist[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); in twa_aen_read_queue()
448 /* Mark internal command */ in twa_aen_read_queue()
449 tw_dev->srb[request_id] = NULL; in twa_aen_read_queue()
451 /* Now post the command packet */ in twa_aen_read_queue()
453 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue"); in twa_aen_read_queue()
475 /* This function will sync firmware time with the host time */
484 /* Fill out the command packet */ in twa_aen_sync_time()
485 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_aen_sync_time()
487 command_packet = &full_command_packet->command.oldcommand; in twa_aen_sync_time()
488 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM); in twa_aen_sync_time()
489 command_packet->request_id = request_id; in twa_aen_sync_time()
490 …command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[requ… in twa_aen_sync_time()
491 command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); in twa_aen_sync_time()
492 command_packet->size = TW_COMMAND_SIZE; in twa_aen_sync_time()
493 command_packet->byte6_offset.parameter_count = cpu_to_le16(1); in twa_aen_sync_time()
496 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; in twa_aen_sync_time()
498 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */ in twa_aen_sync_time()
499 param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */ in twa_aen_sync_time()
500 param->parameter_size_bytes = cpu_to_le16(4); in twa_aen_sync_time()
504 local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60)); in twa_aen_sync_time()
505 div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime); in twa_aen_sync_time()
507 memcpy(param->data, &(__le32){cpu_to_le32(schedulertime)}, sizeof(__le32)); in twa_aen_sync_time()
509 /* Mark internal command */ in twa_aen_sync_time()
510 tw_dev->srb[request_id] = NULL; in twa_aen_sync_time()
512 /* Now post the command */ in twa_aen_sync_time()
524 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, in twa_allocate_memory()
527 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed"); in twa_allocate_memory()
532 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory"); in twa_allocate_memory()
533 dma_free_coherent(&tw_dev->tw_pci_dev->dev, size * TW_Q_LENGTH, in twa_allocate_memory()
543 tw_dev->command_packet_phys[i] = dma_handle+(i*size); in twa_allocate_memory()
544 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size)); in twa_allocate_memory()
547 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size); in twa_allocate_memory()
548 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size)); in twa_allocate_memory()
586 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL"); in twa_check_srl()
590 tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl; in twa_check_srl()
591 tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch; in twa_check_srl()
592 tw_dev->tw_compat_info.working_build = fw_on_ctlr_build; in twa_check_srl()
603 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL"); in twa_check_srl()
608 …TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firm… in twa_check_srl()
610 …TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driv… in twa_check_srl()
614 tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL; in twa_check_srl()
615 tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH; in twa_check_srl()
616 tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD; in twa_check_srl()
620 strscpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, in twa_check_srl()
621 sizeof(tw_dev->tw_compat_info.driver_version)); in twa_check_srl()
622 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL; in twa_check_srl()
623 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH; in twa_check_srl()
624 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD; in twa_check_srl()
625 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL; in twa_check_srl()
626 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH; in twa_check_srl()
627 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD; in twa_check_srl()
628 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl; in twa_check_srl()
629 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch; in twa_check_srl()
630 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build; in twa_check_srl()
661 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { in twa_chrdev_ioctl()
666 /* First copy down the driver command */ in twa_chrdev_ioctl()
680 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, in twa_chrdev_ioctl()
697 spin_lock_irqsave(tw_dev->host->host_lock, flags); in twa_chrdev_ioctl()
700 /* Flag internal command */ in twa_chrdev_ioctl()
701 tw_dev->srb[request_id] = NULL; in twa_chrdev_ioctl()
704 tw_dev->chrdev_request_id = request_id; in twa_chrdev_ioctl()
706 full_command_packet = &tw_ioctl->firmware_command; in twa_chrdev_ioctl()
708 /* Load request id and sglist for both command types */ in twa_chrdev_ioctl()
711 …memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_F… in twa_chrdev_ioctl()
713 /* Now post the command packet to the controller */ in twa_chrdev_ioctl()
715 spin_unlock_irqrestore(tw_dev->host->host_lock, flags); in twa_chrdev_ioctl()
719 /* Now wait for command to complete */ in twa_chrdev_ioctl()
720 …timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FR… in twa_chrdev_ioctl()
723 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { in twa_chrdev_ioctl()
725 …printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, … in twa_chrdev_ioctl()
726 tw_dev->host->host_no, TW_DRIVER, 0x37, in twa_chrdev_ioctl()
733 /* Now copy in the command packet response */ in twa_chrdev_ioctl()
734 …memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_F… in twa_chrdev_ioctl()
737 spin_lock_irqsave(tw_dev->host->host_lock, flags); in twa_chrdev_ioctl()
738 tw_dev->posted_request_count--; in twa_chrdev_ioctl()
739 tw_dev->state[request_id] = TW_S_COMPLETED; in twa_chrdev_ioctl()
741 spin_unlock_irqrestore(tw_dev->host->host_lock, flags); in twa_chrdev_ioctl()
744 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
746 tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; in twa_chrdev_ioctl()
747 memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info)); in twa_chrdev_ioctl()
750 if (tw_dev->event_queue_wrapped) { in twa_chrdev_ioctl()
751 if (tw_dev->aen_clobber) { in twa_chrdev_ioctl()
752 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; in twa_chrdev_ioctl()
753 tw_dev->aen_clobber = 0; in twa_chrdev_ioctl()
755 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
757 if (!tw_dev->error_index) { in twa_chrdev_ioctl()
758 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; in twa_chrdev_ioctl()
761 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
763 event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH; in twa_chrdev_ioctl()
764 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); in twa_chrdev_ioctl()
765 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; in twa_chrdev_ioctl()
768 if (tw_dev->event_queue_wrapped) { in twa_chrdev_ioctl()
769 if (tw_dev->aen_clobber) { in twa_chrdev_ioctl()
770 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; in twa_chrdev_ioctl()
771 tw_dev->aen_clobber = 0; in twa_chrdev_ioctl()
773 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
774 event_index = tw_dev->error_index; in twa_chrdev_ioctl()
776 if (!tw_dev->error_index) { in twa_chrdev_ioctl()
777 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; in twa_chrdev_ioctl()
780 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
783 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); in twa_chrdev_ioctl()
784 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; in twa_chrdev_ioctl()
787 event = (TW_Event *)tw_ioctl->data_buffer; in twa_chrdev_ioctl()
788 sequence_id = event->sequence_id; in twa_chrdev_ioctl()
789 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
791 if (tw_dev->event_queue_wrapped) { in twa_chrdev_ioctl()
792 if (tw_dev->aen_clobber) { in twa_chrdev_ioctl()
793 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; in twa_chrdev_ioctl()
794 tw_dev->aen_clobber = 0; in twa_chrdev_ioctl()
796 start_index = tw_dev->error_index; in twa_chrdev_ioctl()
798 if (!tw_dev->error_index) { in twa_chrdev_ioctl()
799 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; in twa_chrdev_ioctl()
804 …event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW… in twa_chrdev_ioctl()
806 if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) { in twa_chrdev_ioctl()
807 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER) in twa_chrdev_ioctl()
808 tw_dev->aen_clobber = 1; in twa_chrdev_ioctl()
809 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; in twa_chrdev_ioctl()
812 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); in twa_chrdev_ioctl()
813 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; in twa_chrdev_ioctl()
816 event = (TW_Event *)tw_ioctl->data_buffer; in twa_chrdev_ioctl()
817 sequence_id = event->sequence_id; in twa_chrdev_ioctl()
818 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
820 if (tw_dev->event_queue_wrapped) { in twa_chrdev_ioctl()
821 if (tw_dev->aen_clobber) { in twa_chrdev_ioctl()
822 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER; in twa_chrdev_ioctl()
823 tw_dev->aen_clobber = 0; in twa_chrdev_ioctl()
825 start_index = tw_dev->error_index; in twa_chrdev_ioctl()
827 if (!tw_dev->error_index) { in twa_chrdev_ioctl()
828 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; in twa_chrdev_ioctl()
833 …event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW… in twa_chrdev_ioctl()
835 if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) { in twa_chrdev_ioctl()
836 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER) in twa_chrdev_ioctl()
837 tw_dev->aen_clobber = 1; in twa_chrdev_ioctl()
838 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS; in twa_chrdev_ioctl()
841 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event)); in twa_chrdev_ioctl()
842 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED; in twa_chrdev_ioctl()
845 tw_lock = (TW_Lock *)tw_ioctl->data_buffer; in twa_chrdev_ioctl()
848 if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || in twa_chrdev_ioctl()
849 ktime_after(current_time, tw_dev->ioctl_time)) { in twa_chrdev_ioctl()
850 tw_dev->ioctl_sem_lock = 1; in twa_chrdev_ioctl()
851 tw_dev->ioctl_time = ktime_add_ms(current_time, tw_lock->timeout_msec); in twa_chrdev_ioctl()
852 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
853 tw_lock->time_remaining_msec = tw_lock->timeout_msec; in twa_chrdev_ioctl()
855 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED; in twa_chrdev_ioctl()
856 tw_lock->time_remaining_msec = ktime_ms_delta(tw_dev->ioctl_time, current_time); in twa_chrdev_ioctl()
860 if (tw_dev->ioctl_sem_lock == 1) { in twa_chrdev_ioctl()
861 tw_dev->ioctl_sem_lock = 0; in twa_chrdev_ioctl()
862 tw_ioctl->driver_command.status = 0; in twa_chrdev_ioctl()
864 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED; in twa_chrdev_ioctl()
877 dma_free_coherent(&tw_dev->tw_pci_dev->dev, in twa_chrdev_ioctl()
881 mutex_unlock(&tw_dev->ioctl_lock); in twa_chrdev_ioctl()
895 retval = -EACCES; in twa_chrdev_open()
914 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing"); in twa_decode_bits()
919 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing"); in twa_decode_bits()
921 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT); in twa_decode_bits()
925 if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) && in twa_decode_bits()
926 (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) || in twa_decode_bits()
927 (!test_bit(TW_IN_RESET, &tw_dev->flags))) in twa_decode_bits()
928 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); in twa_decode_bits()
933 if (tw_dev->reset_print == 0) { in twa_decode_bits()
934 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing"); in twa_decode_bits()
935 tw_dev->reset_print = 1; in twa_decode_bits()
972 if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) { in twa_empty_response_queue_large()
980 /* P-chip settle time */ in twa_empty_response_queue_large()
997 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_fill_sense()
1000 …error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err… in twa_fill_sense()
1003 error = le16_to_cpu(full_command_packet->header.status_block.error); in twa_fill_sense()
1006 printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n", in twa_fill_sense()
1007 tw_dev->host->host_no, in twa_fill_sense()
1010 full_command_packet->header.err_specific_desc); in twa_fill_sense()
1012 printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n", in twa_fill_sense()
1015 full_command_packet->header.err_specific_desc); in twa_fill_sense()
1019 …memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DAT… in twa_fill_sense()
1020 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1); in twa_fill_sense()
1032 if (tw_dev->command_packet_virt[0]) in twa_free_device_extension()
1033 dma_free_coherent(&tw_dev->tw_pci_dev->dev, in twa_free_device_extension()
1035 tw_dev->command_packet_virt[0], in twa_free_device_extension()
1036 tw_dev->command_packet_phys[0]); in twa_free_device_extension()
1038 if (tw_dev->generic_buffer_virt[0]) in twa_free_device_extension()
1039 dma_free_coherent(&tw_dev->tw_pci_dev->dev, in twa_free_device_extension()
1041 tw_dev->generic_buffer_virt[0], in twa_free_device_extension()
1042 tw_dev->generic_buffer_phys[0]); in twa_free_device_extension()
1044 kfree(tw_dev->event_queue[0]); in twa_free_device_extension()
1050 tw_dev->free_queue[tw_dev->free_tail] = request_id; in twa_free_request_id()
1051 tw_dev->state[request_id] = TW_S_FINISHED; in twa_free_request_id()
1052 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH; in twa_free_request_id()
1063 /* Setup the command packet */ in twa_get_param()
1064 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_get_param()
1066 command_packet = &full_command_packet->command.oldcommand; in twa_get_param()
1068 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM); in twa_get_param()
1069 command_packet->size = TW_COMMAND_SIZE; in twa_get_param()
1070 command_packet->request_id = request_id; in twa_get_param()
1071 command_packet->byte6_offset.block_count = cpu_to_le16(1); in twa_get_param()
1074 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; in twa_get_param()
1076 param->table_id = cpu_to_le16(table_id | 0x8000); in twa_get_param()
1077 param->parameter_id = cpu_to_le16(parameter_id); in twa_get_param()
1078 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes); in twa_get_param()
1080 …command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[requ… in twa_get_param()
1081 command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); in twa_get_param()
1083 /* Post the command packet to the board */ in twa_get_param()
1088 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param") in twa_get_param()
1090 retval = (void *)&(param->data[0]); in twa_get_param()
1092 tw_dev->posted_request_count--; in twa_get_param()
1093 tw_dev->state[request_id] = TW_S_INITIAL; in twa_get_param()
1101 *request_id = tw_dev->free_queue[tw_dev->free_head]; in twa_get_request_id()
1102 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH; in twa_get_request_id()
1103 tw_dev->state[*request_id] = TW_S_STARTED; in twa_get_request_id()
1106 /* This function will send an initconnection command to controller */
1122 /* Initialize InitConnection command packet */ in twa_initconnection()
1123 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_initconnection()
1125 full_command_packet->header.header_desc.size_header = 128; in twa_initconnection()
1127 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand; in twa_initconnection()
1128 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION); in twa_initconnection()
1129 tw_initconnect->request_id = request_id; in twa_initconnection()
1130 tw_initconnect->message_credits = cpu_to_le16(message_credits); in twa_initconnection()
1132 /* Turn on 64-bit sgl support if we need to */ in twa_initconnection()
1135 tw_initconnect->features = cpu_to_le32(set_features); in twa_initconnection()
1138 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED; in twa_initconnection()
1139 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl); in twa_initconnection()
1140 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id); in twa_initconnection()
1141 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch); in twa_initconnection()
1142 tw_initconnect->fw_build = cpu_to_le16(current_fw_build); in twa_initconnection()
1144 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE; in twa_initconnection()
1146 /* Send command packet to the board */ in twa_initconnection()
1151 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection"); in twa_initconnection()
1154 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl); in twa_initconnection()
1155 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id); in twa_initconnection()
1156 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch); in twa_initconnection()
1157 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build); in twa_initconnection()
1158 *init_connect_result = le32_to_cpu(tw_initconnect->result); in twa_initconnection()
1163 tw_dev->posted_request_count--; in twa_initconnection()
1164 tw_dev->state[request_id] = TW_S_INITIAL; in twa_initconnection()
1174 /* Initialize command packet buffers */ in twa_initialize_device_extension()
1176 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed"); in twa_initialize_device_extension()
1182 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed"); in twa_initialize_device_extension()
1187 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL); in twa_initialize_device_extension()
1188 if (!tw_dev->event_queue[0]) { in twa_initialize_device_extension()
1189 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed"); in twa_initialize_device_extension()
1195 …tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Eve… in twa_initialize_device_extension()
1196 tw_dev->free_queue[i] = i; in twa_initialize_device_extension()
1197 tw_dev->state[i] = TW_S_INITIAL; in twa_initialize_device_extension()
1200 tw_dev->pending_head = TW_Q_START; in twa_initialize_device_extension()
1201 tw_dev->pending_tail = TW_Q_START; in twa_initialize_device_extension()
1202 tw_dev->free_head = TW_Q_START; in twa_initialize_device_extension()
1203 tw_dev->free_tail = TW_Q_START; in twa_initialize_device_extension()
1204 tw_dev->error_sequence_id = 1; in twa_initialize_device_extension()
1205 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; in twa_initialize_device_extension()
1207 mutex_init(&tw_dev->ioctl_lock); in twa_initialize_device_extension()
1208 init_waitqueue_head(&tw_dev->ioctl_wqueue); in twa_initialize_device_extension()
1226 spin_lock(tw_dev->host->host_lock); in twa_interrupt()
1238 if (test_bit(TW_IN_RESET, &tw_dev->flags)) in twa_interrupt()
1249 /* Handle host interrupt */ in twa_interrupt()
1256 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) { in twa_interrupt()
1261 tw_dev->state[request_id] = TW_S_COMPLETED; in twa_interrupt()
1263 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags); in twa_interrupt()
1268 /* Handle command interrupt */ in twa_interrupt()
1272 while (tw_dev->pending_request_count > 0) { in twa_interrupt()
1273 request_id = tw_dev->pending_queue[tw_dev->pending_head]; in twa_interrupt()
1274 if (tw_dev->state[request_id] != TW_S_PENDING) { in twa_interrupt()
1275 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending"); in twa_interrupt()
1280 tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH; in twa_interrupt()
1281 tw_dev->pending_request_count--; in twa_interrupt()
1283 /* If we get here, we will continue re-posting on the next command interrupt */ in twa_interrupt()
1297 full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_interrupt()
1299 /* Check for command packet errors */ in twa_interrupt()
1300 if (full_command_packet->command.newcommand.status != 0) { in twa_interrupt()
1301 if (tw_dev->srb[request_id] != NULL) { in twa_interrupt()
1305 if (request_id != tw_dev->chrdev_request_id) { in twa_interrupt()
1312 if (tw_dev->state[request_id] != TW_S_POSTED) { in twa_interrupt()
1313 if (tw_dev->srb[request_id] != NULL) { in twa_interrupt()
1314 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted"); in twa_interrupt()
1320 /* Check for internal command completion */ in twa_interrupt()
1321 if (tw_dev->srb[request_id] == NULL) { in twa_interrupt()
1322 if (request_id != tw_dev->chrdev_request_id) { in twa_interrupt()
1324 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt"); in twa_interrupt()
1326 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; in twa_interrupt()
1327 wake_up(&tw_dev->ioctl_wqueue); in twa_interrupt()
1332 cmd = tw_dev->srb[request_id]; in twa_interrupt()
1335 /* If no error command was a success */ in twa_interrupt()
1337 cmd->result = (DID_OK << 16); in twa_interrupt()
1340 /* If error, command failed */ in twa_interrupt()
1342 /* Ask for a host reset */ in twa_interrupt()
1343 cmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION; in twa_interrupt()
1347 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) { in twa_interrupt()
1348 u32 length = le32_to_cpu(full_command_packet->command.newcommand.sg_list[0].length); in twa_interrupt()
1351 scsi_set_resid(cmd, scsi_bufflen(cmd) - length); in twa_interrupt()
1358 tw_dev->state[request_id] = TW_S_COMPLETED; in twa_interrupt()
1360 tw_dev->posted_request_count--; in twa_interrupt()
1375 spin_unlock(tw_dev->host->host_lock); in twa_interrupt()
1390 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { in twa_load_sgl()
1391 newcommand = &full_command_packet->command.newcommand; in twa_load_sgl()
1392 newcommand->request_id__lunl = in twa_load_sgl()
1393 TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); in twa_load_sgl()
1395 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache)); in twa_load_sgl()
1396 newcommand->sg_list[0].length = cpu_to_le32(length); in twa_load_sgl()
1398 newcommand->sgl_entries__lunh = in twa_load_sgl()
1399 TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0); in twa_load_sgl()
1401 oldcommand = &full_command_packet->command.oldcommand; in twa_load_sgl()
1402 oldcommand->request_id = request_id; in twa_load_sgl()
1404 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { in twa_load_sgl()
1406 if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA) in twa_load_sgl()
1407 sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae); in twa_load_sgl()
1409 sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); in twa_load_sgl()
1410 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache)); in twa_load_sgl()
1411 sgl->length = cpu_to_le32(length); in twa_load_sgl()
1413 oldcommand->size += pae; in twa_load_sgl()
1423 TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id]; in twa_poll_response()
1429 …TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response"); in twa_poll_response()
1432 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { in twa_poll_response()
1433 if (full_command_packet->command.newcommand.status != 0) { in twa_poll_response()
1440 if (full_command_packet->command.oldcommand.status != 0) { in twa_poll_response()
1512 /* This function will attempt to post a command packet to the board */
1519 command_que_value = tw_dev->command_packet_phys[request_id]; in twa_post_command_packet()
1522 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) || in twa_post_command_packet()
1523 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) { in twa_post_command_packet()
1533 …if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (statu… in twa_post_command_packet()
1541 /* Couldn't post the command packet, so we do it later */ in twa_post_command_packet()
1542 if (tw_dev->state[request_id] != TW_S_PENDING) { in twa_post_command_packet()
1543 tw_dev->state[request_id] = TW_S_PENDING; in twa_post_command_packet()
1544 tw_dev->pending_request_count++; in twa_post_command_packet()
1545 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) { in twa_post_command_packet()
1546 tw_dev->max_pending_request_count = tw_dev->pending_request_count; in twa_post_command_packet()
1548 tw_dev->pending_queue[tw_dev->pending_tail] = request_id; in twa_post_command_packet()
1549 tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH; in twa_post_command_packet()
1554 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) || in twa_post_command_packet()
1555 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) { in twa_post_command_packet()
1567 tw_dev->state[request_id] = TW_S_POSTED; in twa_post_command_packet()
1568 tw_dev->posted_request_count++; in twa_post_command_packet()
1569 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) { in twa_post_command_packet()
1570 tw_dev->max_posted_request_count = tw_dev->posted_request_count; in twa_post_command_packet()
1585 set_bit(TW_IN_RESET, &tw_dev->flags); in twa_reset_device_extension()
1588 spin_lock_irqsave(tw_dev->host->host_lock, flags); in twa_reset_device_extension()
1592 if ((tw_dev->state[i] != TW_S_FINISHED) && in twa_reset_device_extension()
1593 (tw_dev->state[i] != TW_S_INITIAL) && in twa_reset_device_extension()
1594 (tw_dev->state[i] != TW_S_COMPLETED)) { in twa_reset_device_extension()
1595 if (tw_dev->srb[i]) { in twa_reset_device_extension()
1596 struct scsi_cmnd *cmd = tw_dev->srb[i]; in twa_reset_device_extension()
1598 cmd->result = (DID_RESET << 16); in twa_reset_device_extension()
1608 tw_dev->free_queue[i] = i; in twa_reset_device_extension()
1609 tw_dev->state[i] = TW_S_INITIAL; in twa_reset_device_extension()
1611 tw_dev->free_head = TW_Q_START; in twa_reset_device_extension()
1612 tw_dev->free_tail = TW_Q_START; in twa_reset_device_extension()
1613 tw_dev->posted_request_count = 0; in twa_reset_device_extension()
1614 tw_dev->pending_request_count = 0; in twa_reset_device_extension()
1615 tw_dev->pending_head = TW_Q_START; in twa_reset_device_extension()
1616 tw_dev->pending_tail = TW_Q_START; in twa_reset_device_extension()
1617 tw_dev->reset_print = 0; in twa_reset_device_extension()
1619 spin_unlock_irqrestore(tw_dev->host->host_lock, flags); in twa_reset_device_extension()
1625 clear_bit(TW_IN_RESET, &tw_dev->flags); in twa_reset_device_extension()
1626 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; in twa_reset_device_extension()
1643 …TW_PRINTK(tw_dev->host, TW_DRIVER, 0x36, "Response queue (large) empty failed during reset sequenc… in twa_reset_sequence()
1652 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence"); in twa_reset_sequence()
1660 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence"); in twa_reset_sequence()
1670 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence"); in twa_reset_sequence()
1683 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence"); in twa_reset_sequence()
1725 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; in twa_scsi_eh_reset()
1727 tw_dev->num_resets++; in twa_scsi_eh_reset()
1729 sdev_printk(KERN_WARNING, SCpnt->device, in twa_scsi_eh_reset()
1730 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", in twa_scsi_eh_reset()
1731 TW_DRIVER, 0x2c, SCpnt->cmnd[0]); in twa_scsi_eh_reset()
1734 mutex_lock(&tw_dev->ioctl_lock); in twa_scsi_eh_reset()
1738 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); in twa_scsi_eh_reset()
1744 mutex_unlock(&tw_dev->ioctl_lock); in twa_scsi_eh_reset()
1753 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; in twa_scsi_queue_lck()
1756 if (test_bit(TW_IN_RESET, &tw_dev->flags)) { in twa_scsi_queue_lck()
1762 if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { in twa_scsi_queue_lck()
1763 SCpnt->result = (DID_BAD_TARGET << 16); in twa_scsi_queue_lck()
1772 /* Save the scsi command for use by the ISR */ in twa_scsi_queue_lck()
1773 tw_dev->srb[request_id] = SCpnt; in twa_scsi_queue_lck()
1783 SCpnt->result = (DID_ERROR << 16); in twa_scsi_queue_lck()
1787 tw_dev->state[request_id] = TW_S_COMPLETED; in twa_scsi_queue_lck()
1810 if (tw_dev->srb[request_id]) in DEF_SCSI_QCMD()
1811 srb = tw_dev->srb[request_id]; in DEF_SCSI_QCMD()
1813 /* Initialize command packet */ in DEF_SCSI_QCMD()
1814 full_command_packet = tw_dev->command_packet_virt[request_id]; in DEF_SCSI_QCMD()
1815 full_command_packet->header.header_desc.size_header = 128; in DEF_SCSI_QCMD()
1816 full_command_packet->header.status_block.error = 0; in DEF_SCSI_QCMD()
1817 full_command_packet->header.status_block.severity__reserved = 0; in DEF_SCSI_QCMD()
1819 command_packet = &full_command_packet->command.newcommand; in DEF_SCSI_QCMD()
1820 command_packet->status = 0; in DEF_SCSI_QCMD()
1821 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI); in DEF_SCSI_QCMD()
1825 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN); in DEF_SCSI_QCMD()
1827 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN); in DEF_SCSI_QCMD()
1830 command_packet->unit = srb->device->id; in DEF_SCSI_QCMD()
1831 command_packet->request_id__lunl = in DEF_SCSI_QCMD()
1832 TW_REQ_LUN_IN(srb->device->lun, request_id); in DEF_SCSI_QCMD()
1834 command_packet->request_id__lunl = in DEF_SCSI_QCMD()
1836 command_packet->unit = 0; in DEF_SCSI_QCMD()
1839 command_packet->sgl_offset = 16; in DEF_SCSI_QCMD()
1846 if (srb->sc_data_direction == DMA_TO_DEVICE || in DEF_SCSI_QCMD()
1847 srb->sc_data_direction == DMA_BIDIRECTIONAL) in DEF_SCSI_QCMD()
1849 tw_dev->generic_buffer_virt[request_id], in DEF_SCSI_QCMD()
1851 command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); in DEF_SCSI_QCMD()
1852 command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); in DEF_SCSI_QCMD()
1859 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg)); in DEF_SCSI_QCMD()
1860 command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(sg)); in DEF_SCSI_QCMD()
1861 if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { in DEF_SCSI_QCMD()
1862 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi"); in DEF_SCSI_QCMD()
1867 …command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->s… in DEF_SCSI_QCMD()
1872 command_packet->sg_list[i].address = sglistarg[i].address; in DEF_SCSI_QCMD()
1873 command_packet->sg_list[i].length = sglistarg[i].length; in DEF_SCSI_QCMD()
1874 if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { in DEF_SCSI_QCMD()
1875 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post"); in DEF_SCSI_QCMD()
1879 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN(0, use_sg); in DEF_SCSI_QCMD()
1883 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) in DEF_SCSI_QCMD()
1884 num_sectors = (u32)srb->cmnd[4]; in DEF_SCSI_QCMD()
1886 if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) in DEF_SCSI_QCMD()
1887 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8); in DEF_SCSI_QCMD()
1891 tw_dev->sector_count = num_sectors; in DEF_SCSI_QCMD()
1892 if (tw_dev->sector_count > tw_dev->max_sector_count) in DEF_SCSI_QCMD()
1893 tw_dev->max_sector_count = tw_dev->sector_count; in DEF_SCSI_QCMD()
1897 tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]); in DEF_SCSI_QCMD()
1898 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries) in DEF_SCSI_QCMD()
1899 tw_dev->max_sgl_entries = tw_dev->sgl_entries; in DEF_SCSI_QCMD()
1902 /* Now post the command to the board */ in DEF_SCSI_QCMD()
1916 struct scsi_cmnd *cmd = tw_dev->srb[request_id]; in twa_scsiop_execute_scsi_complete()
1919 (cmd->sc_data_direction == DMA_FROM_DEVICE || in twa_scsiop_execute_scsi_complete()
1920 cmd->sc_data_direction == DMA_BIDIRECTIONAL)) { in twa_scsiop_execute_scsi_complete()
1922 void *buf = tw_dev->generic_buffer_virt[request_id]; in twa_scsiop_execute_scsi_complete()
1936 free_irq(tw_dev->tw_pci_dev->irq, tw_dev); in __twa_shutdown()
1938 printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); in __twa_shutdown()
1942 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed"); in __twa_shutdown()
1944 printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n"); in __twa_shutdown()
1954 struct Scsi_Host *host = pci_get_drvdata(pdev); in twa_shutdown() local
1955 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; in twa_shutdown()
1970 /* This function gets called when a disk is coming on-line */
1974 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ); in twa_slave_configure()
1986 .can_queue = TW_Q_LENGTH-2,
1988 .this_id = -1,
2000 struct Scsi_Host *host = NULL; in twa_probe() local
2007 TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device"); in twa_probe()
2008 return -ENODEV; in twa_probe()
2014 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); in twa_probe()
2016 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); in twa_probe()
2018 TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); in twa_probe()
2019 retval = -ENODEV; in twa_probe()
2023 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); in twa_probe()
2024 if (!host) { in twa_probe()
2025 TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension"); in twa_probe()
2026 retval = -ENOMEM; in twa_probe()
2029 tw_dev = (TW_Device_Extension *)host->hostdata; in twa_probe()
2032 tw_dev->host = host; in twa_probe()
2033 tw_dev->tw_pci_dev = pdev; in twa_probe()
2036 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension"); in twa_probe()
2037 retval = -ENOMEM; in twa_probe()
2042 retval = pci_request_regions(pdev, "3w-9xxx"); in twa_probe()
2044 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region"); in twa_probe()
2048 if (pdev->device == PCI_DEVICE_ID_3WARE_9000) { in twa_probe()
2057 tw_dev->base_addr = ioremap(mem_addr, mem_len); in twa_probe()
2058 if (!tw_dev->base_addr) { in twa_probe()
2059 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap"); in twa_probe()
2060 retval = -ENOMEM; in twa_probe()
2069 retval = -ENOMEM; in twa_probe()
2073 /* Set host specific parameters */ in twa_probe()
2074 if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) || in twa_probe()
2075 (pdev->device == PCI_DEVICE_ID_3WARE_9690SA)) in twa_probe()
2076 host->max_id = TW_MAX_UNITS_9650SE; in twa_probe()
2078 host->max_id = TW_MAX_UNITS; in twa_probe()
2080 host->max_cmd_len = TW_MAX_CDB_LEN; in twa_probe()
2083 host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl); in twa_probe()
2084 host->max_channel = 0; in twa_probe()
2087 retval = scsi_add_host(host, &pdev->dev); in twa_probe()
2089 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); in twa_probe()
2093 pci_set_drvdata(pdev, host); in twa_probe()
2095 printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%lx, IRQ: %d.\n", in twa_probe()
2096 host->host_no, mem_addr, pdev->irq); in twa_probe()
2097 printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n", in twa_probe()
2098 host->host_no, in twa_probe()
2107 if (use_msi && (pdev->device != PCI_DEVICE_ID_3WARE_9000) && in twa_probe()
2109 set_bit(TW_USING_MSI, &tw_dev->flags); in twa_probe()
2112 retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev); in twa_probe()
2114 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ"); in twa_probe()
2121 /* Re-enable interrupts on the card */ in twa_probe()
2124 /* Finally, scan the host */ in twa_probe()
2125 scsi_scan_host(host); in twa_probe()
2127 if (twa_major == -1) { in twa_probe()
2129 TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device"); in twa_probe()
2134 if (test_bit(TW_USING_MSI, &tw_dev->flags)) in twa_probe()
2136 scsi_remove_host(host); in twa_probe()
2138 iounmap(tw_dev->base_addr); in twa_probe()
2143 scsi_host_put(host); in twa_probe()
2153 struct Scsi_Host *host = pci_get_drvdata(pdev); in twa_remove() local
2154 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; in twa_remove()
2156 scsi_remove_host(tw_dev->host); in twa_remove()
2161 twa_major = -1; in twa_remove()
2168 if (test_bit(TW_USING_MSI, &tw_dev->flags)) in twa_remove()
2172 iounmap(tw_dev->base_addr); in twa_remove()
2180 scsi_host_put(tw_dev->host); in twa_remove()
2182 twa_device_extension_count--; in twa_remove()
2189 struct Scsi_Host *host = pci_get_drvdata(pdev); in twa_suspend() local
2190 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; in twa_suspend()
2192 printk(KERN_WARNING "3w-9xxx: Suspending host %d.\n", tw_dev->host->host_no); in twa_suspend()
2195 free_irq(tw_dev->tw_pci_dev->irq, tw_dev); in twa_suspend()
2197 if (test_bit(TW_USING_MSI, &tw_dev->flags)) in twa_suspend()
2202 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x38, "Connection shutdown failed during suspend"); in twa_suspend()
2204 printk(KERN_WARNING "3w-9xxx: Suspend complete.\n"); in twa_suspend()
2216 struct Scsi_Host *host = pci_get_drvdata(pdev); in twa_resume() local
2217 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; in twa_resume()
2219 printk(KERN_WARNING "3w-9xxx: Resuming host %d.\n", tw_dev->host->host_no); in twa_resume()
2223 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); in twa_resume()
2225 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); in twa_resume()
2227 TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume"); in twa_resume()
2228 retval = -ENODEV; in twa_resume()
2234 retval = -ENODEV; in twa_resume()
2239 retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev); in twa_resume()
2241 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x42, "Error requesting IRQ during resume"); in twa_resume()
2242 retval = -ENODEV; in twa_resume()
2247 if (test_bit(TW_USING_MSI, &tw_dev->flags)) in twa_resume()
2250 /* Re-enable interrupts on the card */ in twa_resume()
2253 printk(KERN_WARNING "3w-9xxx: Resume complete.\n"); in twa_resume()
2257 scsi_remove_host(host); in twa_resume()
2280 .name = "3w-9xxx",