diff options
Diffstat (limited to 'drivers/scsi')
59 files changed, 14553 insertions, 1627 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 6aab9dacdee..1c8f872e2dd 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -1064,6 +1064,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa struct Scsi_Host *host; char *new_name; u_long s; + int retval; template->name = ahd->description; host = scsi_host_alloc(template, sizeof(struct ahd_softc *)); @@ -1096,9 +1097,15 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa host->transportt = ahd_linux_transport_template; - scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */ + retval = scsi_add_host(host, &ahd->dev_softc->dev); + if (retval) { + printk(KERN_WARNING "aic79xx: scsi_add_host failed\n"); + scsi_host_put(host); + return retval; + } + scsi_scan_host(host); - return (0); + return 0; } uint64_t diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index d866213f42b..fd389e9f946 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1061,10 +1061,11 @@ uint32_t aic7xxx_verbose; int ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template) { - char buf[80]; - struct Scsi_Host *host; + char buf[80]; + struct Scsi_Host *host; char *new_name; - u_long s; + u_long s; + int retval; template->name = ahc->description; host = scsi_host_alloc(template, sizeof(struct ahc_softc *)); @@ -1097,9 +1098,16 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa host->transportt = ahc_linux_transport_template; - scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */ + retval = scsi_add_host(host, + (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); + if (retval) { + printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n"); + scsi_host_put(host); + return retval; + } + scsi_scan_host(host); - return (0); + return 0; } /* diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index ccbbae2bf47..0920220f331 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -75,7 +75,7 @@ static int vendor_counts[CH_TYPES-4]; module_param_array(vendor_firsts, int, NULL, 0444); module_param_array(vendor_counts, int, NULL, 0444); -static char *vendor_labels[CH_TYPES-4] = { +static const char * vendor_labels[CH_TYPES-4] = { "v0", "v1", "v2", "v3" }; // module_param_string_array(vendor_labels, NULL, 0444); @@ -140,7 +140,7 @@ static struct file_operations changer_fops = #endif }; -static struct { +static const struct { unsigned char sense; unsigned char asc; unsigned char ascq; diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 09bc81557b6..a972c1e89e3 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1065,7 +1065,7 @@ struct error_info2 { const char * fmt; }; -static struct error_info2 additional2[] = +static const struct error_info2 additional2[] = { {0x40,0x00,0x7f,"Ram failure (%x)"}, {0x40,0x80,0xff,"Diagnostic failure on component (%x)"}, @@ -1077,7 +1077,7 @@ static struct error_info2 additional2[] = }; /* description of the sense key values */ -static const char *snstext[] = { +static const char * const snstext[] = { "No Sense", /* 0: There is no sense information */ "Recovered Error", /* 1: The last command completed successfully but used error correction */ @@ -1279,7 +1279,7 @@ void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq) EXPORT_SYMBOL(scsi_print_req_sense); #ifdef CONFIG_SCSI_CONSTANTS -static const char *one_byte_msgs[] = { +static const char * const one_byte_msgs[] = { /* 0x00 */ "Command Complete", NULL, "Save Pointers", /* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", /* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error", @@ -1289,13 +1289,13 @@ static const char *one_byte_msgs[] = { }; #define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs) / sizeof (const char *)) -static const char *two_byte_msgs[] = { +static const char * const two_byte_msgs[] = { /* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag" /* 0x23 */ "Ignore Wide Residue" }; #define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs) / sizeof (const char *)) -static const char *extended_msgs[] = { +static const char * const extended_msgs[] = { /* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request", /* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request" }; @@ -1397,7 +1397,7 @@ EXPORT_SYMBOL(scsi_print_command); #ifdef CONFIG_SCSI_CONSTANTS -static const char * hostbyte_table[]={ +static const char * const hostbyte_table[]={ "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; @@ -1422,12 +1422,12 @@ void scsi_print_hostbyte(int scsiresult) #ifdef CONFIG_SCSI_CONSTANTS -static const char * driverbyte_table[]={ +static const char * const driverbyte_table[]={ "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; #define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *)) -static const char * driversuggest_table[]={"SUGGEST_OK", +static const char * const driversuggest_table[]={"SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; #define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *)) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index fa2cb3582cf..b6714da4d6e 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -5887,7 +5887,12 @@ static int __devinit ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg) ENTER; spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg); - _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE); + if (ioa_cfg->needs_hard_reset) { + ioa_cfg->needs_hard_reset = 0; + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); + } else + _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, + IPR_SHUTDOWN_NONE); spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); @@ -6264,6 +6269,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, unsigned long ipr_regs_pci; void __iomem *ipr_regs; u32 rc = PCIBIOS_SUCCESSFUL; + volatile u32 mask, uproc; ENTER; @@ -6356,6 +6362,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto cleanup_nomem; } + /* + * If HRRQ updated interrupt is not masked, or reset alert is set, + * the card is in an unknown state and needs a hard reset + */ + mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); + uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); + if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) + ioa_cfg->needs_hard_reset = 1; + ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); rc = request_irq(pdev->irq, ipr_isr, SA_SHIRQ, IPR_NAME, ioa_cfg); diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 6bec673c925..b639332131f 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -36,8 +36,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.1.0" -#define IPR_DRIVER_DATE "(October 31, 2005)" +#define IPR_DRIVER_VERSION "2.1.1" +#define IPR_DRIVER_DATE "(November 15, 2005)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -922,6 +922,7 @@ struct ipr_ioa_cfg { u8 dump_taken:1; u8 allow_cmds:1; u8 allow_ml_add_del:1; + u8 needs_hard_reset:1; enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 3d8009f5534..10bcf42cb65 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -49,7 +49,7 @@ MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, " "Alex Aizman <itn780@yahoo.com>"); MODULE_DESCRIPTION("iSCSI/TCP data-path"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0:4.409"); +MODULE_VERSION("0:4.445"); /* #define DEBUG_TCP */ /* #define DEBUG_SCSI */ #define DEBUG_ASSERT @@ -581,10 +581,16 @@ iscsi_hdr_recv(struct iscsi_conn *conn) crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst); rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + conn->in.ahslen); + if (cdgst != rdgst) { + printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error " + "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst, + cdgst); + return ISCSI_ERR_HDR_DGST; + } } /* save opcode for later */ - conn->in.opcode = hdr->opcode; + conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK; /* verify itt (itt encoding: age+cid+itt) */ if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { @@ -610,13 +616,6 @@ iscsi_hdr_recv(struct iscsi_conn *conn) conn->in.ahslen, conn->in.datalen); if (conn->in.itt < session->cmds_max) { - if (conn->hdrdgst_en && cdgst != rdgst) { - printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error " - "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst, - cdgst); - return ISCSI_ERR_HDR_DGST; - } - ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt]; if (!ctask->sc) { @@ -642,9 +641,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) switch(conn->in.opcode) { case ISCSI_OP_SCSI_CMD_RSP: BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE) - rc = iscsi_cmd_rsp(conn, ctask); - else if (!conn->in.datalen) + if (!conn->in.datalen) rc = iscsi_cmd_rsp(conn, ctask); else /* @@ -666,8 +663,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) break; case ISCSI_OP_R2T: BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE && - ctask->sc->sc_data_direction == DMA_TO_DEVICE) + if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) rc = iscsi_r2t_rsp(conn, ctask); else rc = ISCSI_ERR_PROTO; @@ -906,11 +902,20 @@ partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg, crypto_digest_update(conn->data_rx_tfm, &temp, 1); } +static void +iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len) +{ + struct scatterlist tmp; + + sg_init_one(&tmp, buf, len); + crypto_digest_update(conn->data_rx_tfm, &tmp, 1); +} + static int iscsi_scsi_data_in(struct iscsi_conn *conn) { struct iscsi_cmd_task *ctask = conn->in.ctask; struct scsi_cmnd *sc = ctask->sc; - struct scatterlist tmp, *sg; + struct scatterlist *sg; int i, offset, rc = 0; BUG_ON((void*)ctask != sc->SCp.ptr); @@ -924,10 +929,8 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) sc->request_bufflen, ctask->data_offset); if (rc == -EAGAIN) return rc; - if (conn->datadgst_en) { - sg_init_one(&tmp, sc->request_buffer, i); - crypto_digest_update(conn->data_rx_tfm, &tmp, 1); - } + if (conn->datadgst_en) + iscsi_recv_digest_update(conn, sc->request_buffer, i); rc = 0; goto done; } @@ -1021,6 +1024,9 @@ iscsi_data_recv(struct iscsi_conn *conn) conn->in.hdr = &conn->hdr; conn->senselen = (conn->data[0] << 8) | conn->data[1]; rc = iscsi_cmd_rsp(conn, conn->in.ctask); + if (!rc && conn->datadgst_en) + iscsi_recv_digest_update(conn, conn->data, + conn->in.datalen); } break; case ISCSI_OP_TEXT_RSP: @@ -1045,6 +1051,11 @@ iscsi_data_recv(struct iscsi_conn *conn) rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr, conn->data, conn->in.datalen); + if (!rc && conn->datadgst_en && + conn->in.opcode != ISCSI_OP_LOGIN_RSP) + iscsi_recv_digest_update(conn, conn->data, + conn->in.datalen); + if (mtask && conn->login_mtask != mtask) { spin_lock(&session->lock); __kfifo_put(session->mgmtpool.queue, (void*)&mtask, @@ -1053,6 +1064,8 @@ iscsi_data_recv(struct iscsi_conn *conn) } } break; + case ISCSI_OP_ASYNC_EVENT: + case ISCSI_OP_REJECT: default: BUG_ON(1); } @@ -1114,8 +1127,7 @@ more: */ rc = iscsi_hdr_recv(conn); if (!rc && conn->in.datalen) { - if (conn->datadgst_en && - conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) { + if (conn->datadgst_en) { BUG_ON(!conn->data_rx_tfm); crypto_digest_init(conn->data_rx_tfm); } @@ -1127,26 +1139,24 @@ more: } if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) { + uint32_t recv_digest; debug_tcp("extra data_recv offset %d copy %d\n", conn->in.offset, conn->in.copy); - if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) { - uint32_t recv_digest; - skb_copy_bits(conn->in.skb, conn->in.offset, - &recv_digest, 4); - conn->in.offset += 4; - conn->in.copy -= 4; - if (recv_digest != conn->in.datadgst) { - debug_tcp("iscsi_tcp: data digest error!" - "0x%x != 0x%x\n", recv_digest, - conn->in.datadgst); - iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST); - return 0; - } else { - debug_tcp("iscsi_tcp: data digest match!" - "0x%x == 0x%x\n", recv_digest, - conn->in.datadgst); - conn->in_progress = IN_PROGRESS_WAIT_HEADER; - } + skb_copy_bits(conn->in.skb, conn->in.offset, + &recv_digest, 4); + conn->in.offset += 4; + conn->in.copy -= 4; + if (recv_digest != conn->in.datadgst) { + debug_tcp("iscsi_tcp: data digest error!" + "0x%x != 0x%x\n", recv_digest, + conn->in.datadgst); + iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST); + return 0; + } else { + debug_tcp("iscsi_tcp: data digest match!" + "0x%x == 0x%x\n", recv_digest, + conn->in.datadgst); + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } } @@ -1167,8 +1177,7 @@ more: } conn->in.copy -= conn->in.padding; conn->in.offset += conn->in.padding; - if (conn->datadgst_en && - conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) { + if (conn->datadgst_en) { if (conn->in.padding) { debug_tcp("padding -> %d\n", conn->in.padding); memset(pad, 0, conn->in.padding); @@ -1237,8 +1246,9 @@ iscsi_tcp_state_change(struct sock *sk) conn = (struct iscsi_conn*)sk->sk_user_data; session = conn->session; - if (sk->sk_state == TCP_CLOSE_WAIT || - sk->sk_state == TCP_CLOSE) { + if ((sk->sk_state == TCP_CLOSE_WAIT || + sk->sk_state == TCP_CLOSE) && + !atomic_read(&sk->sk_rmem_alloc)) { debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n"); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); } @@ -2389,6 +2399,15 @@ fault: } static int +iscsi_change_queue_depth(struct scsi_device *sdev, int depth) +{ + if (depth > ISCSI_MAX_CMD_PER_LUN) + depth = ISCSI_MAX_CMD_PER_LUN; + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + return sdev->queue_depth; +} + +static int iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) { int i; @@ -2853,8 +2872,11 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag) * in hdr_extract() and will be re-negotiated at * set_param() time. */ - if (flag == STOP_CONN_RECOVER) + if (flag == STOP_CONN_RECOVER) { conn->hdr_size = sizeof(struct iscsi_hdr); + conn->hdrdgst_en = 0; + conn->datadgst_en = 0; + } } up(&conn->xmitsema); } @@ -3247,13 +3269,14 @@ iscsi_r2tpool_free(struct iscsi_session *session) static struct scsi_host_template iscsi_sht = { .name = "iSCSI Initiator over TCP/IP, v." ISCSI_VERSION_STR, - .queuecommand = iscsi_queuecommand, + .queuecommand = iscsi_queuecommand, + .change_queue_depth = iscsi_change_queue_depth, .can_queue = ISCSI_XMIT_CMDS_MAX - 1, .sg_tablesize = ISCSI_SG_TABLESIZE, - .cmd_per_lun = ISCSI_CMD_PER_LUN, - .eh_abort_handler = iscsi_eh_abort, - .eh_host_reset_handler = iscsi_eh_host_reset, - .use_clustering = DISABLE_CLUSTERING, + .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, + .eh_abort_handler = iscsi_eh_abort, + .eh_host_reset_handler = iscsi_eh_host_reset, + .use_clustering = DISABLE_CLUSTERING, .proc_name = "iscsi_tcp", .this_id = -1, }; diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index d23ae68fae0..855f2dfd18a 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -71,7 +71,8 @@ #define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */ #define ISCSI_MGMT_ITT_OFFSET 0xa00 #define ISCSI_SG_TABLESIZE SG_ALL -#define ISCSI_CMD_PER_LUN 128 +#define ISCSI_DEF_CMD_PER_LUN 32 +#define ISCSI_MAX_CMD_PER_LUN 128 #define ISCSI_TCP_MAX_CMD_LEN 16 #define ITT_MASK (0xfff) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 3062b39fbdb..38ffa8d6e62 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -29,9 +29,10 @@ struct lpfc_sli2_slim; #define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ #define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ -#define LPFC_CMD_PER_LUN 30 /* max outstanding cmds per lun */ +#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ #define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ +#define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ /* Define macros for 64 bit support */ #define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr))) @@ -45,6 +46,11 @@ struct lpfc_sli2_slim; #define MAX_HBAEVT 32 +enum lpfc_polling_flags { + ENABLE_FCP_RING_POLLING = 0x1, + DISABLE_FCP_RING_INT = 0x2 +}; + /* Provide DMA memory definitions the driver uses per port instance. */ struct lpfc_dmabuf { struct list_head list; @@ -167,6 +173,7 @@ struct lpfc_hba { dma_addr_t slim2p_mapping; uint16_t pci_cfg_value; + struct semaphore hba_can_block; uint32_t hba_state; #define LPFC_INIT_START 1 /* Initial state after board reset */ @@ -286,6 +293,8 @@ struct lpfc_hba { uint32_t cfg_fcp_bind_method; uint32_t cfg_discovery_threads; |