diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 11 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 15 | ||||
-rw-r--r-- | drivers/scsi/hosts.c | 13 | ||||
-rw-r--r-- | drivers/scsi/ipr.c | 1 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_elsct.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 35 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 33 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 82 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 18 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 10 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 8 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 18 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 6 | ||||
-rw-r--r-- | drivers/scsi/scsi_devinfo.c | 9 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib_dma.c | 4 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_fc.c | 85 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 9 | ||||
-rw-r--r-- | drivers/scsi/st.c | 23 | ||||
-rw-r--r-- | drivers/scsi/st.h | 1 |
22 files changed, 251 insertions, 141 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 3ee1cbc89479..bfec4fa5addf 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -304,18 +304,15 @@ static int scsi_dh_notifier(struct notifier_block *nb, sdev = to_scsi_device(dev); if (action == BUS_NOTIFY_ADD_DEVICE) { + err = device_create_file(dev, &scsi_dh_state_attr); + /* don't care about err */ devinfo = device_handler_match(NULL, sdev); - if (!devinfo) - goto out; - - err = scsi_dh_handler_attach(sdev, devinfo); - if (!err) - err = device_create_file(dev, &scsi_dh_state_attr); + if (devinfo) + err = scsi_dh_handler_attach(sdev, devinfo); } else if (action == BUS_NOTIFY_DEL_DEVICE) { device_remove_file(dev, &scsi_dh_state_attr); scsi_dh_handler_detach(sdev, NULL); } -out: return err; } diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 704b8e034946..70ab5d0c5a48 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -137,7 +137,7 @@ static struct scsi_host_template fcoe_shost_template = { .change_queue_depth = fc_change_queue_depth, .change_queue_type = fc_change_queue_type, .this_id = -1, - .cmd_per_lun = 32, + .cmd_per_lun = 3, .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS, .use_clustering = ENABLE_CLUSTERING, .sg_tablesize = SG_ALL, @@ -160,6 +160,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, { struct fcoe_ctlr *fip = &fcoe->ctlr; struct netdev_hw_addr *ha; + struct net_device *real_dev; u8 flogi_maddr[ETH_ALEN]; fcoe->netdev = netdev; @@ -173,10 +174,12 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, /* look for SAN MAC address, if multiple SAN MACs exist, only * use the first one for SPMA */ + real_dev = (netdev->priv_flags & IFF_802_1Q_VLAN) ? + vlan_dev_real_dev(netdev) : netdev; rcu_read_lock(); - for_each_dev_addr(netdev, ha) { + for_each_dev_addr(real_dev, ha) { if ((ha->type == NETDEV_HW_ADDR_T_SAN) && - (is_valid_ether_addr(fip->ctl_src_addr))) { + (is_valid_ether_addr(ha->addr))) { memcpy(fip->ctl_src_addr, ha->addr, ETH_ALEN); fip->spma = 1; break; @@ -664,7 +667,7 @@ static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid, { struct net_device *n = fcoe_netdev(lp); - if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup) + if (n->netdev_ops->ndo_fcoe_ddp_setup) return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc); return 0; @@ -681,7 +684,7 @@ static int fcoe_ddp_done(struct fc_lport *lp, u16 xid) { struct net_device *n = fcoe_netdev(lp); - if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done) + if (n->netdev_ops->ndo_fcoe_ddp_done) return n->netdev_ops->ndo_fcoe_ddp_done(n, xid); return 0; } @@ -1631,7 +1634,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) { struct fcoe_interface *fcoe; struct net_device *netdev; - int rc; + int rc = 0; mutex_lock(&fcoe_config_mutex); #ifdef CONFIG_FCOE_MODULE diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index c968cc31cd86..554626e18062 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -180,14 +180,20 @@ void scsi_remove_host(struct Scsi_Host *shost) EXPORT_SYMBOL(scsi_remove_host); /** - * scsi_add_host - add a scsi host + * scsi_add_host_with_dma - add a scsi host with dma device * @shost: scsi host pointer to add * @dev: a struct device of type scsi class + * @dma_dev: dma device for the host + * + * Note: You rarely need to worry about this unless you're in a + * virtualised host environments, so use the simpler scsi_add_host() + * function instead. * * Return value: * 0 on success / != 0 for error **/ -int scsi_add_host(struct Scsi_Host *shost, struct device *dev) +int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, + struct device *dma_dev) { struct scsi_host_template *sht = shost->hostt; int error = -EINVAL; @@ -207,6 +213,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) if (!shost->shost_gendev.parent) shost->shost_gendev.parent = dev ? dev : &platform_bus; + shost->dma_dev = dma_dev; error = device_add(&shost->shost_gendev); if (error) @@ -262,7 +269,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) fail: return error; } -EXPORT_SYMBOL(scsi_add_host); +EXPORT_SYMBOL(scsi_add_host_with_dma); static void scsi_host_dev_release(struct device *dev) { diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 76d294fc7846..c3ff9a64c192 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6516,6 +6516,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) int rc; ENTER; + ioa_cfg->pdev->state_saved = true; rc = pci_restore_state(ioa_cfg->pdev); if (rc != PCIBIOS_SUCCESSFUL) { diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index c48799e9dd8e..d4cb3f9b1a0d 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -371,7 +371,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc) disc, lport->e_d_tov)) return; err: - fc_disc_error(disc, fp); + fc_disc_error(disc, NULL); } /** diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c index 5cfa68732e9d..92984587ff4d 100644 --- a/drivers/scsi/libfc/fc_elsct.c +++ b/drivers/scsi/libfc/fc_elsct.c @@ -53,8 +53,10 @@ static struct fc_seq *fc_elsct_send(struct fc_lport *lport, did = FC_FID_DIR_SERV; } - if (rc) + if (rc) { + fc_frame_free(fp); return NULL; + } fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type, FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 59a4408b27b5..7a144026b49b 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -302,10 +302,13 @@ static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp) if (!fsp) return; + if (fsp->xfer_ddp == FC_XID_UNKNOWN) + return; + lp = fsp->lp; - if (fsp->xfer_ddp && lp->tt.ddp_done) { + if (lp->tt.ddp_done) { fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp); - fsp->xfer_ddp = 0; + fsp->xfer_ddp = FC_XID_UNKNOWN; } } @@ -572,7 +575,8 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, tlen -= sg_bytes; remaining -= sg_bytes; - if (tlen) + if ((skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN) && + (tlen)) continue; /* @@ -1048,7 +1052,6 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp, seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0); if (!seq) { - fc_frame_free(fp); rc = -1; goto unlock; } @@ -1313,7 +1316,6 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp) fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */ return; } - fc_frame_free(fp); retry: if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); @@ -1561,10 +1563,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset) seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL, fsp, jiffies_to_msecs(FC_SCSI_REC_TOV)); - if (!seq) { - fc_frame_free(fp); + if (!seq) goto retry; - } + fsp->recov_seq = seq; fsp->xfer_len = offset; fsp->xfer_contig_end = offset; @@ -1708,6 +1709,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) fsp->cmd = sc_cmd; /* save the cmd */ fsp->lp = lp; /* save the softc ptr */ fsp->rport = rport; /* set the remote port ptr */ + fsp->xfer_ddp = FC_XID_UNKNOWN; sc_cmd->scsi_done = done; /* @@ -1846,7 +1848,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) * scsi status is good but transport level * underrun. */ - sc_cmd->result = DID_OK << 16; + sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ? + DID_OK : DID_ERROR) << 16; } else { /* * scsi got underrun, this is an error @@ -2046,18 +2049,16 @@ EXPORT_SYMBOL(fc_eh_host_reset); int fc_slave_alloc(struct scsi_device *sdev) { struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); - int queue_depth; if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - if (sdev->tagged_supported) { - if (sdev->host->hostt->cmd_per_lun) - queue_depth = sdev->host->hostt->cmd_per_lun; - else - queue_depth = FC_FCP_DFLT_QUEUE_DEPTH; - scsi_activate_tcq(sdev, queue_depth); - } + if (sdev->tagged_supported) + scsi_activate_tcq(sdev, FC_FCP_DFLT_QUEUE_DEPTH); + else + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), + FC_FCP_DFLT_QUEUE_DEPTH); + return 0; } EXPORT_SYMBOL(fc_slave_alloc); diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index bd2f77197447..536492ae6a88 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -329,7 +329,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) * @sp: current sequence in the RLIR exchange * @fp: RLIR request frame * - * Locking Note: The lport lock is exected to be held before calling + * Locking Note: The lport lock is expected to be held before calling * this function. */ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, @@ -348,7 +348,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, * @sp: current sequence in the ECHO exchange * @fp: ECHO request frame * - * Locking Note: The lport lock is exected to be held before calling + * Locking Note: The lport lock is expected to be held before calling * this function. */ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, @@ -361,7 +361,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, void *dp; u32 f_ctl; - FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n", + FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n", fc_lport_state(lport)); len = fr_len(in_fp) - sizeof(struct fc_frame_header); @@ -374,7 +374,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, if (fp) { dp = fc_frame_payload_get(fp, len); memcpy(dp, pp, len); - *((u32 *)dp) = htonl(ELS_LS_ACC << 24); + *((__be32 *)dp) = htonl(ELS_LS_ACC << 24); sp = lport->tt.seq_start_next(sp); f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, @@ -385,12 +385,12 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, } /** - * fc_lport_recv_echo_req() - Handle received Request Node ID data request - * @lport: Fibre Channel local port recieving the RNID - * @sp: current sequence in the RNID exchange - * @fp: RNID request frame + * fc_lport_recv_rnid_req() - Handle received Request Node ID data request + * @sp: The sequence in the RNID exchange + * @fp: The RNID request frame + * @lport: The local port recieving the RNID * - * Locking Note: The lport lock is exected to be held before calling + * Locking Note: The lport lock is expected to be held before calling * this function. */ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, @@ -667,7 +667,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport) * Accept it with the common service parameters indicating our N port. * Set up to do a PLOGI if we have the higher-number WWPN. * - * Locking Note: The lport lock is exected to be held before calling + * Locking Note: The lport lock is expected to be held before calling * this function. */ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, @@ -1115,7 +1115,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport) if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR, fc_lport_scr_resp, lport, lport->e_d_tov)) - fc_lport_error(lport, fp); + fc_lport_error(lport, NULL); } /** @@ -1186,7 +1186,7 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport) if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID, fc_lport_rpn_id_resp, lport, lport->e_d_tov)) - fc_lport_error(lport, fp); + fc_lport_error(lport, NULL); } static struct fc_rport_operations fc_lport_rport_ops = { @@ -1237,10 +1237,13 @@ static void fc_lport_timeout(struct work_struct *work) switch (lport->state) { case LPORT_ST_DISABLED: + WARN_ON(1); + break; case LPORT_ST_READY: - case LPORT_ST_RESET: WARN_ON(1); break; + case LPORT_ST_RESET: + break; case LPORT_ST_FLOGI: fc_lport_enter_flogi(lport); break; @@ -1337,7 +1340,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport) if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO, fc_lport_logo_resp, lport, lport->e_d_tov)) - fc_lport_error(lport, fp); + fc_lport_error(lport, NULL); } /** @@ -1453,7 +1456,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport) if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI, fc_lport_flogi_resp, lport, lport->e_d_tov)) - fc_lport_error(lport, fp); + fc_lport_error(lport, NULL); } /* Configure a fc_lport */ diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 03ea6748e7ee..ff558a631d17 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -86,6 +86,7 @@ static const char *fc_rport_state_names[] = { [RPORT_ST_LOGO] = "LOGO", [RPORT_ST_ADISC] = "ADISC", [RPORT_ST_DELETE] = "Delete", + [RPORT_ST_RESTART] = "Restart", }; /** @@ -99,8 +100,7 @@ static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport, struct fc_rport_priv *rdata; list_for_each_entry(rdata, &lport->disc.rports, peers) - if (rdata->ids.port_id == port_id && - rdata->rp_state != RPORT_ST_DELETE) + if (rdata->ids.port_id == port_id) return rdata; return NULL; } @@ -235,6 +235,7 @@ static void fc_rport_work(struct work_struct *work) struct fc_rport_operations *rport_ops; struct fc_rport_identifiers ids; struct fc_rport *rport; + int restart = 0; mutex_lock(&rdata->rp_mutex); event = rdata->event; @@ -287,8 +288,20 @@ static void fc_rport_work(struct work_struct *work) mutex_unlock(&rdata->rp_mutex); if (port_id != FC_FID_DIR_SERV) { + /* + * We must drop rp_mutex before taking disc_mutex. + * Re-evaluate state to allow for restart. + * A transition to RESTART state must only happen + * while disc_mutex is held and rdata is on the list. + */ mutex_lock(&lport->disc.disc_mutex); - list_del(&rdata->peers); + mutex_lock(&rdata->rp_mutex); + if (rdata->rp_state == RPORT_ST_RESTART) + restart = 1; + else + list_del(&rdata->peers); + rdata->event = RPORT_EV_NONE; + mutex_unlock(&rdata->rp_mutex); mutex_unlock(&lport->disc.disc_mutex); } @@ -312,7 +325,13 @@ static void fc_rport_work(struct work_struct *work) mutex_unlock(&rdata->rp_mutex); fc_remote_port_delete(rport); } - kref_put(&rdata->kref, lport->tt.rport_destroy); + if (restart) { + mutex_lock(&rdata->rp_mutex); + FC_RPORT_DBG(rdata, "work restart\n"); + fc_rport_enter_plogi(rdata); + mutex_unlock(&rdata->rp_mutex); + } else + kref_put(&rdata->kref, lport->tt.rport_destroy); break; default: @@ -342,6 +361,12 @@ int fc_rport_login(struct fc_rport_priv *rdata) FC_RPORT_DBG(rdata, "ADISC port\n"); fc_rport_enter_adisc(rdata); break; + case RPORT_ST_RESTART: + break; + case RPORT_ST_DELETE: + FC_RPORT_DBG(rdata, "Restart deleted port\n"); + fc_rport_state_enter(rdata, RPORT_ST_RESTART); + break; default: FC_RPORT_DBG(rdata, "Login to port\n"); fc_rport_enter_plogi(rdata); @@ -397,20 +422,21 @@ int fc_rport_logoff(struct fc_rport_priv *rdata) if (rdata->rp_state == RPORT_ST_DELETE) { FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n"); - mutex_unlock(&rdata->rp_mutex); goto out; } - fc_rport_enter_logo(rdata); + if (rdata->rp_state == RPORT_ST_RESTART) + FC_RPORT_DBG(rdata, "Port in Restart state, deleting\n"); + else + fc_rport_enter_logo(rdata); /* * Change the state to Delete so that we discard * the response. */ fc_rport_enter_delete(rdata, RPORT_EV_STOP); - mutex_unlock(&rdata->rp_mutex); - out: + mutex_unlock(&rdata->rp_mutex); return 0; } @@ -466,6 +492,7 @@ static void fc_rport_timeout(struct work_struct *work) case RPORT_ST_READY: case RPORT_ST_INIT: case RPORT_ST_DELETE: + case RPORT_ST_RESTART: break; } @@ -499,6 +526,7 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp) fc_rport_enter_logo(rdata); break; case RPORT_ST_DELETE: + case RPORT_ST_RESTART: case RPORT_ST_READY: case RPORT_ST_INIT: break; @@ -632,7 +660,7 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata) if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI, fc_rport_plogi_resp, rdata, lport->e_d_tov)) - fc_rport_error_retry(rdata, fp); + fc_rport_error_retry(rdata, NULL); else kref_get(&rdata->kref); } @@ -793,7 +821,7 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata) if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI, fc_rport_prli_resp, rdata, lport->e_d_tov)) - fc_rport_error_retry(rdata, fp); + fc_rport_error_retry(rdata, NULL); else kref_get(&rdata->kref); } @@ -889,7 +917,7 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata) if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV, fc_rport_rtv_resp, rdata, lport->e_d_tov)) - fc_rport_error_retry(rdata, fp); + fc_rport_error_retry(rdata, NULL); else kref_get(&rdata->kref); } @@ -919,7 +947,7 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata) if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO, fc_rport_logo_resp, rdata, lport->e_d_tov)) - fc_rport_error_retry(rdata, fp); + fc_rport_error_retry(rdata, NULL); else kref_get(&rdata->kref); } @@ -1006,7 +1034,7 @@ static void fc_rport_enter_adisc(struct fc_rport_priv *rdata) } if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC, fc_rport_adisc_resp, rdata, lport->e_d_tov)) - fc_rport_error_retry(rdata, fp); + fc_rport_error_retry(rdata, NULL); else kref_get(&rdata->kref); } @@ -1248,6 +1276,7 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport, } break; case RPORT_ST_PRLI: + case RPORT_ST_RTV: case RPORT_ST_READY: case RPORT_ST_ADISC: FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d " @@ -1255,11 +1284,14 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport, /* XXX TBD - should reset */ break; case RPORT_ST_DELETE: - default: - FC_RPORT_DBG(rdata, "Received PLOGI in unexpected state %d\n", - rdata->rp_state); - fc_frame_free(rx_fp); - goto out; + case RPORT_ST_LOGO: + case RPORT_ST_RESTART: + FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n", + fc_rport_state(rdata)); + mutex_unlock(&rdata->rp_mutex); + rjt_data.reason = ELS_RJT_BUSY; + rjt_data.explan = ELS_EXPL_NONE; + goto reject; } /* @@ -1402,7 +1434,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata, break; case FC_TYPE_FCP: fcp_parm = ntohl(rspp->spp_params); - if (fcp_parm * FCP_SPPF_RETRY) + if (fcp_parm & FCP_SPPF_RETRY) rdata->flags |= FC_RP_FLAGS_RETRY; rdata->supported_classes = FC_COS_CLASS3; if (fcp_parm & FCP_SPPF_INIT_FCN) @@ -1510,14 +1542,14 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport, FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n", fc_rport_state(rdata)); + fc_rport_enter_delete(rdata, RPORT_EV_LOGO); + /* - * If the remote port was created due to discovery, - * log back in. It may have seen a stale RSCN about us. + * If the remote port was created due to discovery, set state + * to log back in. It may have seen a stale RSCN about us. */ - if (rdata->rp_state != RPORT_ST_DELETE && rdata->disc_id) - fc_rport_enter_plogi(rdata); - else - fc_rport_enter_delete(rdata, RPORT_EV_LOGO); + if (rdata->disc_id) + fc_rport_state_enter(rdata, RPORT_ST_RESTART); mutex_unlock(&rdata->rp_mutex); } else FC_RPORT_ID_DBG(lport, sid, diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 562d8cee874b..549bc7d8a361 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2408,7 +2408,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.data = (unsigned long)vport; - error = scsi_add_host(shost, dev); + error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); if (error) goto out_put_shost; @@ -4384,9 +4384,13 @@ lpfc_sli_pci_mem_setup(struct lpfc_hba *phba) pdev = phba->pcidev; /* Set the device DMA mask size */ - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) { return error; + } + } /* Get the bus address of Bar0 and Bar2 and the number of bytes * required by each mapping. @@ -5940,9 +5944,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) pdev = phba->pcidev; /* Set the device DMA mask size */ - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) { return error; + } + } /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the * number of bytes required by each mapping. They are actually diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index a39addc3a596..518712cc7253 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -3032,7 +3032,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, int error = 0, i; void *sense = NULL; dma_addr_t sense_handle; - u32 *sense_ptr; + unsigned long *sense_ptr; memset(kbuff_arr, 0, sizeof(kbuff_arr)); @@ -3109,7 +3109,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, } sense_ptr = - (u32 *) ((unsigned long)cmd->frame + ioc->sense_off); + (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off); *sense_ptr = sense_handle; } @@ -3140,8 +3140,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, * sense_ptr points to the location that has the user * sense buffer address */ - sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw + - ioc->sense_off); + sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + + ioc->sense_off); if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), sense, ioc->sense_len)) { @@ -3451,7 +3451,7 @@ out: return retval; } -static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO, +static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR, megasas_sysfs_show_poll_mode_io, megasas_sysfs_set_poll_mode_io); diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h index ab47c4679640..5af66dbe3239 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h @@ -348,6 +348,14 @@ typedef struct _MPI2_CONFIG_REPLY #define MPI2_MFGPAGE_DEVID_SAS2108_3 (0x0077) #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) +#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) +#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) +#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) +#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083) +#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084) +#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085) +#define MPI2_MFGPAGE_DEVID_SAS2208_7 (0x0086) +#define MPI2_MFGPAGE_DEVID_SAS2208_8 (0x0087) /* Manufacturing Page 0 */ diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 86ab32d7ab15..1743640070ca 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -196,10 +196,28 @@ static struct pci_device_id scsih_pci_table[] = { PCI_ANY_ID, PCI_ANY_ID }, { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, PCI_ANY_ID, PCI_ANY_ID }, + /* Meteor ~ 2116 */ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, PCI_ANY_ID, PCI_ANY_ID }, { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, PCI_ANY_ID, PCI_ANY_ID }, + /* Thunderbolt ~ 2208 */ + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7, + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8, + PCI_ANY_ID, PCI_ANY_ID }, {0} /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, scsih_pci_table); diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fbcb82a2f7f4..21e2bc4d7401 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1654,7 +1654,8 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); } - if (scsi_add_host(vha->host, &fc_vport->dev)) { + if (scsi_add_host_with_dma(vha->host, &fc_vport->dev, + &ha->pdev->dev)) { DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n", vha->host_no, vha->vp_idx)); goto vport_create_failed_2; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b79fca7d461b..06bbe0d8b6d7 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2016,13 +2016,13 @@ skip_dpc: DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", base_vha->host_no, ha)); - base_vha->flags.init_done = 1; - base_vha->flags.online = 1; - ret = scsi_add_host(host, &pdev->dev); if (ret) goto probe_failed; + base_vha->flags.init_done = 1; + base_vha->flags.online = 1; + ha->isp_ops->enable_intrs(ha); scsi_scan_host(host); diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 93c2622cb969..802e91c8892e 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -168,11 +168,10 @@ static struct { {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"HITACHI", "DF400", "*", BLIST_SPARSELUN}, - {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, - {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, - {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, + {"HITACHI", "DF400", "*", BLIST_REPORTLUN2}, + {"HITACHI", "DF500", "*", BLIST_REPORTLUN2}, + {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, + {"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2}, {"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 5987da857103..bc9a88145a71 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -749,9 +749,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) */ req->next_rq->resid_len = scsi_in(cmd)->resid; + scsi_release_buffers(cmd); blk_end_request_all(req, 0); - scsi_release_buffers(cmd); scsi_next_command(cmd); return; } diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c index ac6855cd2657..dcd128583b89 100644 --- a/drivers/scsi/scsi_lib_dma.c +++ b/drivers/scsi/scsi_lib_dma.c @@ -23,7 +23,7 @@ int scsi_dma_map(struct scsi_cmnd *cmd) int nseg = 0; if (scsi_sg_count(cmd)) { - struct device *dev = cmd->device->host->shost_gendev.parent; + struct device *dev = cmd->device->host->dma_dev; nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), cmd->sc_data_direction); @@ -41,7 +41,7 @@ EXPORT_SYMBOL(scsi_dma_map); void scsi_dma_unmap(struct scsi_cmnd *cmd) { if (scsi_sg_count(cmd)) { - struct device *dev = cmd->device->host->shost_gendev.parent; + struct device *dev = cmd->device->host->dma_dev; dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), cmd->sc_data_direction); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index c6f70dae9b2e..bf52decfdef4 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -648,11 +648,22 @@ static __init int fc_transport_init(void) return error; error = transport_class_register(&fc_vport_class); if (error) - return error; + goto unreg_host_class; error = transport_class_register(&fc_rport_class); if (error) - return error; - return transport_class_register(&fc_transport_class); + goto unreg_vport_class; + error = transport_class_register(&fc_transport_class); + if (error) + goto unreg_rport_class; + return 0; + +unreg_rport_class: + transport_class_unregister(&fc_rport_class); +unreg_vport_class: + transport_class_unregister(&fc_vport_class); +unreg_host_class: + transport_class_unregister(&fc_host_class); + return error; } static void __exit fc_transport_exit(void) @@ -2384,6 +2395,7 @@ fc_rport_final_delete(struct work_struct *work) struct Scsi_Host *shost = rport_to_shost(rport); struct fc_internal *i = to_fc_internal(shost->transportt); unsigned long flags; + int do_callback = 0; /* * if a scan is pending, flush the SCSI Host work_q so that @@ -2422,8 +2434,15 @@ fc_rport_final_delete(struct work_struct *work) * Avoid this call if we already called it when we preserved the * rport for the binding. */ + spin_lock_irqsave(shost->host_lock, flags); if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) && - (i->f->dev_loss_tmo_callbk)) + (i->f->dev_loss_tmo_callbk)) { + rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE; + do_callback = 1; + } + spin_unlock_irqrestore(shost->host_lock, flags); + + if (do_callback) i->f->dev_loss_tmo_callbk(rport); fc_bsg_remove(rport->rqst_q); @@ -2970,6 +2989,7 @@ fc_timeout_deleted_rport(struct work_struct *work) struct fc_internal *i = to_fc_internal(shost->transportt); struct fc_host_attrs *fc_host = shost_to_fc_host(shost); unsigned long flags; + int do_callback = 0; spin_lock_irqsave(shost->host_lock, flags); @@ -3035,7 +3055,6 @@ fc_timeout_deleted_rport(struct work_struct *work) rport->roles = FC_PORT_ROLE_UNKNOWN; rport->port_state = FC_PORTSTATE_NOTPRESENT; rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT; - rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE; /* * Pre-emptively kill I/O rather than waiting for the work queue @@ -3045,32 +3064,40 @@ fc_timeout_deleted_rport(struct work_struct *work) spin_unlock_irqrestore(shost->host_lock, flags); fc_terminate_rport_io(rport); - BUG_ON(rport->port_state != FC_PORTSTATE_NOTPRESENT); + spin_lock_irqsave(shost->host_lock, flags); - /* remove the identifiers that aren't used in the consisting binding */ - switch (fc_host->tgtid_bind_type) { - case FC_TGTID_BIND_BY_WWPN: - rport->node_name = -1; - rport->port_id = -1; - break; - case FC_TGTID_BIND_BY_WWNN: - rport->port_name = -1; - rport->port_id = -1; - break; - case FC_TGTID_BIND_BY_ID: - rport->node_name = -1; - rport->port_name = -1; - break; - case FC_TGTID_BIND_NONE: /* to keep compiler happy */ - break; + if (rport->port_state == FC_PORTSTATE_NOTPRESENT) { /* still missing */ + + /* remove the identifiers that aren't used in the consisting binding */ + switch (fc_host->tgtid_bind_type) { + case FC_TGTID_BIND_BY_WWPN: + rport->node_name = -1; + rport->port_id = -1; + break; + case FC_TGTID_BIND_BY_WWNN: + rport->port_name = -1; + rport->port_id = -1; + break; + case FC_TGTID_BIND_BY_ID: + rport->node_name = -1; + rport->port_name = -1; + break; + case FC_TGTID_BIND_NONE: /* to keep compiler happy */ + break; + } + + /* + * As this only occurs if the remote port (scsi target) + * went away and didn't come back - we'll remove + * all attached scsi devices. + */ + rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE; + fc_queue_work(shost, &rport->stgt_delete_work); + + do_callback = 1; } - /* - * As this only occurs if the remote port (scsi target) - * went away and didn't come back - we'll remove - * all attached scsi devices. - */ - fc_queue_work(shost, &rport->stgt_delete_work); + spin_unlock_irqrestore(shost->host_lock, flags); /* * Notify the driver that the rport is now dead. The LLDD will @@ -3078,7 +3105,7 @@ fc_timeout_deleted_rport(struct work_struct *work) * * Note: we set the CALLBK_DONE flag above to correspond */ - if (i->f->dev_loss_tmo_callbk) + if (do_callback && i->f->dev_loss_tmo_callbk) i->f->dev_loss_tmo_callbk(rport); } diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index ad897df36615..de2f8c450049 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -627,8 +627,10 @@ static void __iscsi_block_session(struct work_struct *work) spin_unlock_irqrestore(&session->lock, flags); scsi_target_block(&session->dev); ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n"); - queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work, - session->recovery_tmo * HZ); + if (session->recovery_tmo >= 0) + queue_delayed_work(iscsi_eh_timer_workq, + &session->recovery_work, + session->recovery_tmo * HZ); } void iscsi_block_session(struct iscsi_cls_session *session) @@ -1348,8 +1350,7 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) switch (ev->u.set_param.param) { case ISCSI_PARAM_SESS_RECOVERY_TMO: sscanf(data, "%d", &value); - if (value != 0) - session->recovery_tmo = value; + session->recovery_tmo = value; break; default: err = transport->set_param(conn, ev->u.set_param.param, diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 12d58a7ed6bc..5081f97cbdaa 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -552,13 +552,15 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd SRpnt->waiting = waiting; if (STp->buffer->do_dio) { + mdata->page_order = 0; mdata->nr_entries = STp->buffer->sg_segs; mdata->pages = STp->buffer->mapped_pages; } else { + mdata->page_order = STp->buffer->reserved_page_order; mdata->nr_entries = DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order); - STp->buffer->map_data.pages = STp->buffer->reserved_pages; - STp->buffer->map_data.offset = 0; + mdata->pages = STp->buffer->reserved_pages; + mdata->offset = 0; } memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); @@ -3718,7 +3720,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm priority |= __GFP_ZERO; if (STbuffer->frp_segs) { - order = STbuffer->map_data.page_order; + order = STbuffer->reserved_page_order; b_size = PAGE_SIZE << order; } else { for (b_size = PAGE_SIZE, order = 0; @@ -3751,7 +3753,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm segs++; } STbuffer->b_data = page_address(STbuffer->reserved_pages[0]); - STbuffer->map_data.page_order = order; + STbuffer->reserved_page_order = order; return 1; } @@ -3764,7 +3766,7 @@ static void clear_buffer(struct st_buffer * st_bp) for (i=0; i < st_bp->frp_segs; i++) memset(page_address(st_bp->reserved_pages[i]), 0, - PAGE_SIZE << st_bp->map_data.page_order); + PAGE_SIZE << st_bp->reserved_page_order); st_bp->cleared = 1; } @@ -3772,7 +3774,7 @@ static void clear_buffer(struct st_buffer * st_bp) /* Release the extra buffer */ static void normalize_buffer(struct st_buffer * STbuffer) { - int i, order = STbuffer->map_data.page_order; + int i, order = STbuffer->reserved_page_order; for (i = 0; i < STbuffer->frp_segs; i++) { __free_pages(STbuffer->reserved_pages[i], order); @@ -3780,7 +3782,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) } STbuffer->frp_segs = 0; STbuffer->sg_segs = 0; - STbuffer->map_data.page_order = 0; + STbuffer->reserved_page_order = 0; STbuffer->map_data.offset = 0; } @@ -3790,7 +3792,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count) { int i, cnt, res, offset; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; for (i = 0, offset = st_bp->buffer_bytes; i < st_bp->frp_segs && offset >= length; i++) @@ -3822,7 +3824,7 @@ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, in static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count) { int i, cnt, res, offset; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; for (i = 0, offset = st_bp->read_pointer; i < st_bp->frp_segs && offset >= length; i++) @@ -3855,7 +3857,7 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset) { int src_seg, dst_seg, src_offset = 0, dst_offset; int count, total; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; if (offset == 0) return; @@ -4577,7 +4579,6 @@ static int sgl_map_user_pages(struct st_buffer *STbp, } mdata->offset = uaddr & ~PAGE_MASK; - mdata->page_order = 0; STbp->mapped_pages = pages; return nr_pages; diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 544dc6b1f548..f91a67c6d968 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -46,6 +46,7 @@ struct st_buffer { struct st_request *last_SRpnt; struct st_cmdstatus cmdstat; struct page **reserved_pages; + int reserved_page_order; struct page **mapped_pages; struct rq_map_data map_data; unsigned char *b_data; |