Lines Matching refs:tw_dev
38 static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
58 static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
65 sprintf(host, " scsi%d:", tw_dev->host->host_no);
71 outl(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
76 outl(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
77 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
82 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
87 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
91 if (tw_dev->reset_print == 0) {
93 tw_dev->reset_print = 1;
102 static int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
108 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
112 tw_decode_bits(tw_dev, status_reg_value, 0);
115 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
118 tw_decode_bits(tw_dev, status_reg_value, 0);
131 static int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
137 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
141 tw_decode_bits(tw_dev, status_reg_value, 0);
144 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
147 tw_decode_bits(tw_dev, status_reg_value, 0);
160 static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
166 command_que_value = tw_dev->command_packet_physical_address[request_id];
167 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
171 tw_decode_bits(tw_dev, status_reg_value, 1);
176 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
177 tw_dev->state[request_id] = TW_S_POSTED;
178 tw_dev->posted_request_count++;
179 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
180 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
184 if (tw_dev->state[request_id] != TW_S_PENDING) {
185 tw_dev->state[request_id] = TW_S_PENDING;
186 tw_dev->pending_request_count++;
187 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
188 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
190 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
191 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
192 tw_dev->pending_tail = TW_Q_START;
194 tw_dev->pending_tail = tw_dev->pending_tail + 1;
197 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
204 static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
210 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
212 printk(KERN_WARNING "3w-xxxx: scsi%d: Command failed: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, command->status, command->flags, TW_UNIT_OUT(command->unit__hostid));
221 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
224 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
227 tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
230 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
233 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
235 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
249 static int tw_check_errors(TW_Device_Extension *tw_dev)
253 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
256 tw_decode_bits(tw_dev, status_reg_value, 0);
264 static void tw_empty_response_que(TW_Device_Extension *tw_dev)
268 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
271 response_que_value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
272 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
277 static void tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
279 tw_dev->free_queue[tw_dev->free_tail] = request_id;
280 tw_dev->state[request_id] = TW_S_FINISHED;
281 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
285 static void tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
287 *request_id = tw_dev->free_queue[tw_dev->free_head];
288 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
289 tw_dev->state[*request_id] = TW_S_STARTED;
297 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
301 spin_lock_irqsave(tw_dev->host->host_lock, flags);
314 tw_dev->posted_request_count,
315 tw_dev->max_posted_request_count,
316 tw_dev->pending_request_count,
317 tw_dev->max_pending_request_count,
318 tw_dev->sgl_entries,
319 tw_dev->max_sgl_entries,
320 tw_dev->sector_count,
321 tw_dev->max_sector_count,
322 tw_dev->num_resets,
323 tw_dev->aen_count);
324 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
357 static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
367 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
370 tw_decode_bits(tw_dev, status_reg_value, 1);
373 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
377 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
385 command_que_value = tw_dev->command_packet_physical_address[request_id];
391 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
395 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
400 param_value = tw_dev->alignment_physical_address[request_id];
411 tw_dev->srb[request_id] = NULL; /* Flag internal command */
412 tw_dev->state[request_id] = TW_S_POSTED;
413 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
423 static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
430 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
434 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
440 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
445 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
448 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
451 printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
455 tw_dev->aen_count++;
458 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
459 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
460 tw_dev->aen_tail = TW_Q_START;
462 tw_dev->aen_tail = tw_dev->aen_tail + 1;
464 if (tw_dev->aen_head == tw_dev->aen_tail) {
465 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
466 tw_dev->aen_head = TW_Q_START;
468 tw_dev->aen_head = tw_dev->aen_head + 1;
472 error = tw_aen_read_queue(tw_dev, request_id);
474 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
475 tw_dev->state[request_id] = TW_S_COMPLETED;
476 tw_state_request_finish(tw_dev, request_id);
479 tw_dev->state[request_id] = TW_S_COMPLETED;
480 tw_state_request_finish(tw_dev, request_id);
487 static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
504 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
508 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
511 tw_empty_response_que(tw_dev);
514 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
518 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
526 command_que_value = tw_dev->command_packet_physical_address[request_id];
533 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
537 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
542 param_value = tw_dev->alignment_physical_address[request_id];
553 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
556 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
557 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
569 tw_decode_sense(tw_dev, request_id, 0);
595 tw_dev->aen_count++;
613 tw_dev->aen_count++;
619 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
620 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
621 tw_dev->aen_tail = TW_Q_START;
623 tw_dev->aen_tail = tw_dev->aen_tail + 1;
625 if (tw_dev->aen_head == tw_dev->aen_tail) {
626 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
627 tw_dev->aen_head = TW_Q_START;
629 tw_dev->aen_head = tw_dev->aen_head + 1;
645 static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
653 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
659 if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
661 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
670 tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
671 tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
674 tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
675 tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
700 TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
708 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
727 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
750 spin_lock_irqsave(tw_dev->host->host_lock, flags);
751 if (tw_dev->aen_head == tw_dev->aen_tail) {
754 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
755 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
756 tw_dev->aen_head = TW_Q_START;
758 tw_dev->aen_head = tw_dev->aen_head + 1;
761 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
766 spin_lock_irqsave(tw_dev->host->host_lock, flags);
768 tw_state_request_start(tw_dev, &request_id);
771 tw_dev->srb[request_id] = NULL;
774 tw_dev->chrdev_request_id = request_id;
794 memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
797 tw_post_command_packet(tw_dev, request_id);
798 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
803 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
806 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
808 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
810 if (tw_reset_device_extension(tw_dev)) {
811 printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
817 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
820 spin_lock_irqsave(tw_dev->host->host_lock, flags);
821 tw_dev->posted_request_count--;
822 tw_dev->state[request_id] = TW_S_COMPLETED;
823 tw_state_request_finish(tw_dev, request_id);
824 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
837 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
839 mutex_unlock(&tw_dev->ioctl_lock);
869 static void tw_free_device_extension(TW_Device_Extension *tw_dev)
874 if (tw_dev->command_packet_virtual_address[0])
875 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Command)*TW_Q_LENGTH, tw_dev->command_packet_virtual_address[0], tw_dev->command_packet_physical_address[0]);
877 if (tw_dev->alignment_virtual_address[0])
878 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_Q_LENGTH, tw_dev->alignment_virtual_address[0], tw_dev->alignment_physical_address[0]);
882 static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
892 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
897 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
906 command_que_value = tw_dev->command_packet_physical_address[request_id];
914 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
917 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
918 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
928 tw_decode_sense(tw_dev, request_id, 0);
936 static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
947 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
951 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
953 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
961 param_value = tw_dev->alignment_physical_address[request_id];
964 tw_dev->state[request_id] = TW_S_COMPLETED;
965 tw_state_request_finish(tw_dev, request_id);
966 tw_dev->srb[request_id]->result = (DID_OK << 16);
967 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
976 command_que_value = tw_dev->command_packet_physical_address[request_id];
983 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
986 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
987 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
997 tw_decode_sense(tw_dev, request_id, 0);
1006 static int tw_reset_sequence(TW_Device_Extension *tw_dev)
1014 TW_SOFT_RESET(tw_dev);
1016 error = tw_aen_drain_queue(tw_dev);
1018 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
1024 if (tw_check_errors(tw_dev)) {
1025 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
1035 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
1039 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1041 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
1045 error = tw_setfeature(tw_dev, 2, 1, &c);
1054 static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1061 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1068 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1075 tw_dev->free_queue[i] = i;
1076 tw_dev->state[i] = TW_S_INITIAL;
1079 tw_dev->pending_head = TW_Q_START;
1080 tw_dev->pending_tail = TW_Q_START;
1081 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1083 mutex_init(&tw_dev->ioctl_lock);
1084 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1116 static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
1124 set_bit(TW_IN_RESET, &tw_dev->flags);
1125 TW_DISABLE_INTERRUPTS(tw_dev);
1126 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1127 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1131 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1132 (tw_dev->state[i] != TW_S_INITIAL) &&
1133 (tw_dev->state[i] != TW_S_COMPLETED)) {
1134 srb = tw_dev->srb[i];
1137 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1138 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
1145 tw_dev->free_queue[i] = i;
1146 tw_dev->state[i] = TW_S_INITIAL;
1148 tw_dev->free_head = TW_Q_START;
1149 tw_dev->free_tail = TW_Q_START;
1150 tw_dev->posted_request_count = 0;
1151 tw_dev->pending_request_count = 0;
1152 tw_dev->pending_head = TW_Q_START;
1153 tw_dev->pending_tail = TW_Q_START;
1154 tw_dev->reset_print = 0;
1156 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1158 if (tw_reset_sequence(tw_dev)) {
1159 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
1163 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1164 clear_bit(TW_IN_RESET, &tw_dev->flags);
1165 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1175 TW_Device_Extension *tw_dev;
1178 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1201 TW_Device_Extension *tw_dev=NULL;
1204 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1206 tw_dev->num_resets++;
1213 mutex_lock(&tw_dev->ioctl_lock);
1216 if (tw_reset_device_extension(tw_dev)) {
1217 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
1223 mutex_unlock(&tw_dev->ioctl_lock);
1228 static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1238 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1252 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1256 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1261 param_value = tw_dev->alignment_physical_address[request_id];
1269 command_que_value = tw_dev->command_packet_physical_address[request_id];
1276 tw_post_command_packet(tw_dev, request_id);
1281 static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1284 scsi_sg_copy_from_buffer(tw_dev->srb[request_id], data, len);
1288 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1302 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1304 tw_transfer_internal(tw_dev, request_id, request_buffer,
1307 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1314 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1315 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1317 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1318 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1326 static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1336 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1337 tw_dev->state[request_id] = TW_S_COMPLETED;
1338 tw_state_request_finish(tw_dev, request_id);
1339 tw_dev->srb[request_id]->result = (DID_OK << 16);
1340 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1345 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1361 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1366 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1368 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1371 param_value = tw_dev->alignment_physical_address[request_id];
1379 command_que_value = tw_dev->command_packet_physical_address[request_id];
1386 tw_post_command_packet(tw_dev, request_id);
1392 static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1400 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1418 tw_transfer_internal(tw_dev, request_id, request_buffer,
1425 static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
1435 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1445 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1451 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1455 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1458 tw_dev->srb[request_id]->device->id;
1461 param_value = tw_dev->alignment_physical_address[request_id];
1469 command_que_value = tw_dev->command_packet_physical_address[request_id];
1476 tw_post_command_packet(tw_dev, request_id);
1482 static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1492 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1519 tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1525 static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
1536 srb = tw_dev->srb[request_id];
1545 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1577 tw_dev->sector_count = num_sectors;
1578 if (tw_dev->sector_count > tw_dev->max_sector_count)
1579 tw_dev->max_sector_count = tw_dev->sector_count;
1585 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1589 scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
1596 tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
1597 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1598 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1600 command_que_value = tw_dev->command_packet_physical_address[request_id];
1607 tw_post_command_packet(tw_dev, request_id);
1613 static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1623 tw_transfer_internal(tw_dev, request_id, request_buffer,
1626 tw_dev->state[request_id] = TW_S_COMPLETED;
1627 tw_state_request_finish(tw_dev, request_id);
1630 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1631 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1637 static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1645 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1656 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1660 command_que_value = tw_dev->command_packet_physical_address[request_id];
1667 tw_post_command_packet(tw_dev, request_id);
1673 static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1683 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1697 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1701 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1706 param_value = tw_dev->alignment_physical_address[request_id];
1714 command_que_value = tw_dev->command_packet_physical_address[request_id];
1721 tw_post_command_packet(tw_dev, request_id);
1727 static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1734 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1741 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1742 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1744 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1745 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1758 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1761 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1768 tw_state_request_start(tw_dev, &request_id);
1771 tw_dev->srb[request_id] = SCpnt;
1782 retval = tw_scsiop_read_write(tw_dev, request_id);
1786 retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
1790 retval = tw_scsiop_inquiry(tw_dev, request_id);
1794 retval = tw_scsiop_read_capacity(tw_dev, request_id);
1798 retval = tw_scsiop_request_sense(tw_dev, request_id);
1802 retval = tw_scsiop_mode_sense(tw_dev, request_id);
1806 retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
1812 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
1813 tw_dev->state[request_id] = TW_S_COMPLETED;
1814 tw_state_request_finish(tw_dev, request_id);
1820 tw_dev->state[request_id] = TW_S_COMPLETED;
1821 tw_state_request_finish(tw_dev, request_id);
1834 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1841 spin_lock(tw_dev->host->host_lock);
1844 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
1853 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1859 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1860 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1868 TW_CLEAR_HOST_INTERRUPT(tw_dev);
1874 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
1875 tw_state_request_start(tw_dev, &request_id);
1876 error = tw_aen_read_queue(tw_dev, request_id);
1878 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
1879 tw_dev->state[request_id] = TW_S_COMPLETED;
1880 tw_state_request_finish(tw_dev, request_id);
1887 while (tw_dev->pending_request_count > 0) {
1888 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1889 if (tw_dev->state[request_id] != TW_S_PENDING) {
1890 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
1893 if (tw_post_command_packet(tw_dev, request_id)==0) {
1894 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1895 tw_dev->pending_head = TW_Q_START;
1897 tw_dev->pending_head = tw_dev->pending_head + 1;
1899 tw_dev->pending_request_count--;
1906 if (tw_dev->pending_request_count == 0)
1907 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1915 response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1917 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1923 if (tw_dev->srb[request_id] == NULL) {
1924 tw_decode_sense(tw_dev, request_id, 0);
1926 error = tw_decode_sense(tw_dev, request_id, 1);
1931 if (tw_dev->state[request_id] != TW_S_POSTED) {
1932 if (tw_dev->srb[request_id] != NULL) {
1933 printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
1941 if (tw_dev->srb[request_id] == NULL) {
1944 if (request_id != tw_dev->chrdev_request_id) {
1945 retval = tw_aen_complete(tw_dev, request_id);
1947 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
1950 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1951 wake_up(&tw_dev->ioctl_wqueue);
1954 switch (tw_dev->srb[request_id]->cmnd[0]) {
1965 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
1969 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1973 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1977 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
1989 tw_dev->srb[request_id]->result = (DID_OK << 16);
1995 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2000 tw_dev->state[request_id] = TW_S_COMPLETED;
2001 tw_state_request_finish(tw_dev, request_id);
2002 tw_dev->posted_request_count--;
2003 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2005 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2010 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2013 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2014 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2022 spin_unlock(tw_dev->host->host_lock);
2027 static void __tw_shutdown(TW_Device_Extension *tw_dev)
2030 TW_DISABLE_INTERRUPTS(tw_dev);
2033 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2035 printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2038 if (tw_initconnection(tw_dev, 1)) {
2045 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2052 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2054 __tw_shutdown(tw_dev);
2088 TW_Device_Extension *tw_dev;
2111 tw_dev = (TW_Device_Extension *)host->hostdata;
2114 tw_dev->host = host;
2115 tw_dev->tw_pci_dev = pdev;
2117 if (tw_initialize_device_extension(tw_dev)) {
2130 tw_dev->base_addr = pci_resource_start(pdev, 0);
2131 if (!tw_dev->base_addr) {
2137 TW_DISABLE_INTERRUPTS(tw_dev);
2140 if (tw_reset_sequence(tw_dev))
2160 printk(KERN_WARNING "3w-xxxx: scsi%d: Found a 3ware Storage Controller at 0x%x, IRQ: %d.\n", host->host_no, tw_dev->base_addr, pdev->irq);
2163 retval = request_irq(pdev->irq, tw_interrupt, IRQF_SHARED, "3w-xxxx", tw_dev);
2169 tw_device_extension_list[tw_device_extension_count] = tw_dev;
2173 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2189 tw_free_device_extension(tw_dev);
2201 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2203 scsi_remove_host(tw_dev->host);
2212 __tw_shutdown(tw_dev);
2218 tw_free_device_extension(tw_dev);
2220 scsi_host_put(tw_dev->host);