asd_write_reg_word(asd_ha, LmSEQ_FIRST_INV_SCB_SITE(lseq),
(u16)last_scb_site_no+1);
asd_write_reg_word(asd_ha, LmSEQ_INTEN_SAVE(lseq),
- (u16) LmM0INTEN_MASK & 0xFFFF0000 >> 16);
+ (u16) ((LmM0INTEN_MASK & 0xFFFF0000) >> 16));
asd_write_reg_word(asd_ha, LmSEQ_INTEN_SAVE(lseq) + 2,
(u16) LmM0INTEN_MASK & 0xFFFF);
asd_write_reg_byte(asd_ha, LmSEQ_LINK_RST_FRM_LEN(lseq), 0);
/* No delay for the first NOTIFY to be sent to the attached target. */
asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq),
ASD_NOTIFY_DOWN_COUNT);
+ asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(lseq),
+ ASD_NOTIFY_DOWN_COUNT);
/* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */
for (i = 0; i < 2; i++) {
for (i = 0; i < ASD_SCB_SIZE; i += 4)
asd_scbsite_write_dword(asd_ha, site_no, i, 0);
+ /* Initialize SCB Site Opcode field to invalid. */
+ asd_scbsite_write_byte(asd_ha, site_no,
+ offsetof(struct scb_header, opcode),
+ 0xFF);
+
+ /* Initialize SCB Site Flags field to mean a response
+ * frame has been received. This means inadvertent
+ * frames received to be dropped. */
+ asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
+
/* Workaround needed by SEQ to fix a SATA issue is to exclude
* certain SCB sites from the free list. */
if (!SCB_SITE_VALID(site_no))
/* Q_NEXT field of the last SCB is invalidated. */
asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no);
- /* Initialize SCB Site Opcode field to invalid. */
- asd_scbsite_write_byte(asd_ha, site_no,
- offsetof(struct scb_header, opcode),
- 0xFF);
-
- /* Initialize SCB Site Flags field to mean a response
- * frame has been received. This means inadvertent
- * frames received to be dropped. */
- asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
-
first_scb_site_no = site_no;
max_scbs++;
}
set_bit(0, asd_ha->hw_prof.ddb_bitmap);
}
+static void asd_seq_init_ddb_sites(struct asd_ha_struct *asd_ha)
+{
+ unsigned int i;
+ unsigned int ddb_site;
+
+ for (ddb_site = 0 ; ddb_site < ASD_MAX_DDBS; ddb_site++)
+ for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4)
+ asd_ddbsite_write_dword(asd_ha, ddb_site, i, 0);
+}
+
/**
* asd_seq_setup_seqs -- setup and initialize central and link sequencers
* @asd_ha: pointer to host adapter structure
int lseq;
u8 lseq_mask;
+ /* Initialize DDB sites */
+ asd_seq_init_ddb_sites(asd_ha);
+
/* Initialize SCB sites. Done first to compute some values which
* the rest of the init code depends on. */
asd_init_scb_sites(asd_ha);
return asd_seq_unpause_lseq(asd_ha, lseq);
}
+int asd_release_firmware(void)
+{
+ if (sequencer_fw)
+ release_firmware(sequencer_fw);
+ return 0;
+}
+
static int asd_request_firmware(struct asd_ha_struct *asd_ha)
{
int err, i;
* port_map_by_links is also used as the conn_mask byte in the
* initiator/target port DDB.
*/
-void asd_update_port_links(struct asd_sas_phy *sas_phy)
+void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
{
- struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha;
- const u8 phy_mask = (u8) sas_phy->port->phy_mask;
+ const u8 phy_mask = (u8) phy->asd_port->phy_mask;
u8 phy_is_up;
u8 mask;
int i, err;
+ unsigned long flags;
+ spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
for_each_phy(phy_mask, mask, i)
asd_ddbsite_write_byte(asd_ha, 0,
offsetof(struct asd_ddb_seq_shared,
break;
}
}
+ spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
if (err)
asd_printk("couldn't update DDB 0:error:%d\n", err);